[Title] maru_touchscreen was renamed maru_usb_touchscreen
authorgiwoong.kim <giwoong.kim@samsung.com>
Tue, 14 Aug 2012 07:21:23 +0000 (16:21 +0900)
committergiwoong.kim <giwoong.kim@samsung.com>
Tue, 14 Aug 2012 07:25:05 +0000 (16:25 +0900)
[Type] enhancement
[Module] Emulator / touch
[Priority] minor
[Jira#]
[Redmine#]
[Problem]
[Cause]
[Solution]
[TestCase]

tizen/src/Makefile.tizen
tizen/src/hw/maru_touchscreen.c [deleted file]
tizen/src/hw/maru_touchscreen.h [deleted file]
tizen/src/hw/maru_usb_touchscreen.c [new file with mode: 0644]
tizen/src/hw/maru_usb_touchscreen.h [new file with mode: 0644]

index c75e98615f4dcafbf0116a96eeedae34da7df9a3..1dabb655ae245bdfa23267c2932423ec61457505 100755 (executable)
@@ -85,7 +85,7 @@ endif
 obj-i386-y += maru_pm.o
 obj-i386-y += maru_vga.o
 obj-i386-y += maru_brightness.o
-obj-i386-y += maru_touchscreen.o maru_virtio_touchscreen.o
+obj-i386-y += maru_usb_touchscreen.o maru_virtio_touchscreen.o
 
 # FIXME: camera disabled
 ifndef CONFIG_DARWIN
diff --git a/tizen/src/hw/maru_touchscreen.c b/tizen/src/hw/maru_touchscreen.c
deleted file mode 100644 (file)
index e6ebf27..0000000
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Maru Virtual USB Touchscreen emulation.
- * Based on hw/usb-wacom.c:
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  GiWoong Kim <giwoong.kim@samsung.com>
- *  HyunJun Son <hj79.son@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 "maru_touchscreen.h"
-#include "debug_ch.h"
-
-MULTI_DEBUG_CHANNEL(qemu, usb_touchscreen);
-
-
-#define MAX_TOUCH_EVENT_CNT 128
-
-//lock for between communication thread and main thread
-static pthread_mutex_t event_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static QTAILQ_HEAD(, TouchEventEntry) events_queue =
-    QTAILQ_HEAD_INITIALIZER(events_queue);
-
-static unsigned int event_cnt = 0;
-static unsigned int _processed_buf_cnt = 0;
-static TouchEventEntry _event_buf[MAX_TOUCH_EVENT_CNT];
-
-/**
- * @brief : qemu touch(host mouse) event handler
- * @param opaque : state of device
- * @param x : X-axis value
- * @param y : Y-axis value
- * @param z : event id for multiple touch
- */
-static void usb_touchscreen_event(void *opaque, int x, int y, int z, int buttons_state)
-{
-    TouchEventEntry *te;
-    USBTouchscreenState *s = opaque;
-
-    pthread_mutex_lock(&event_mutex);
-    if (event_cnt >= MAX_TOUCH_EVENT_CNT) {
-        pthread_mutex_unlock(&event_mutex);
-        INFO("full touch event queue, lose event\n", event_cnt);
-        return;
-    }
-
-    //using prepared memory
-    te = &(_event_buf[_processed_buf_cnt % MAX_TOUCH_EVENT_CNT]);
-    _processed_buf_cnt++;
-
-    /* mouse event is copied into the queue */
-    te->index = ++event_cnt;
-    te->queue_packet.x = x;
-    te->queue_packet.y = y;
-    te->queue_packet.z = z;
-    te->queue_packet.state = buttons_state;
-
-    QTAILQ_INSERT_TAIL(&events_queue, te, node);
-    s->changed = 1;
-    pthread_mutex_unlock(&event_mutex);
-
-    TRACE("touch event (%d) : x=%d, y=%d, z=%d, state=%d\n", te->index, x, y, z, buttons_state);
-}
-
-/**
- * @brief : fill the usb packet
- * @param s : state of device
- * @param buf : usb packet
- * @param len : size of packet
- */
-static int usb_touchscreen_poll(USBTouchscreenState *s, uint8_t *buf, int len)
-{
-    USBEmulTouchscreenPacket *packet = (USBEmulTouchscreenPacket *)buf;
-
-    if (s->mouse_grabbed == 0) {
-        s->eh_entry = qemu_add_mouse_event_handler(usb_touchscreen_event, s, 1, "QEMU Virtual touchscreen");
-        qemu_activate_mouse_event_handler(s->eh_entry);
-        s->mouse_grabbed = 1;
-    }
-
-    if (len < EMUL_TOUCHSCREEN_PACKET_LEN) {
-        return 0;
-    }
-
-    packet->x = s->dx & 0xffff;
-    packet->y = s->dy & 0xffff;
-    packet->z = s->dz & 0xffff;
-
-    if (s->buttons_state == 0) {
-        packet->state = 0;
-    } else {
-        packet->state = 1;
-    }
-
-    return EMUL_TOUCHSCREEN_PACKET_LEN;
-}
-
-static void usb_touchscreen_handle_reset(USBDevice *dev)
-{
-    USBTouchscreenState *s = (USBTouchscreenState *) dev;
-
-    pthread_mutex_lock(&event_mutex);
-
-    s->dx = 0;
-    s->dy = 0;
-    s->dz = 0;
-    s->buttons_state = 0;
-
-    event_cnt = 0;
-    _processed_buf_cnt = 0;
-
-    pthread_mutex_unlock(&event_mutex);
-}
-
-static int usb_touchscreen_handle_control(USBDevice *dev, USBPacket *p,
-    int request, int value, int index, int length, uint8_t *data)
-{
-    return usb_desc_handle_control(dev, p, request, value, index, length, data);
-}
-
-/**
- * @brief : call by uhci frame timer
- * @param dev : state of device
- * @param p : usb packet
- */
-static int usb_touchscreen_handle_data(USBDevice *dev, USBPacket *p)
-{
-    USBTouchscreenState *s = (USBTouchscreenState *) dev;
-    uint8_t buf[p->iov.size];
-    int ret = 0;
-
-    switch (p->pid) {
-    case USB_TOKEN_IN:
-        if (p->devep == 1) {
-            pthread_mutex_lock(&event_mutex);
-
-            if (s->changed == 0) {
-                pthread_mutex_unlock(&event_mutex);
-                return USB_RET_NAK;
-            }
-
-            if (event_cnt != 0) {
-                if (!QTAILQ_EMPTY(&events_queue)) {
-                    TouchEventEntry *te = QTAILQ_FIRST(&events_queue);
-
-                    s->dx = te->queue_packet.x;
-                    s->dy = te->queue_packet.y;
-                    s->dz = te->queue_packet.z;
-                    s->buttons_state = te->queue_packet.state;
-
-                    QTAILQ_REMOVE(&events_queue, te, node);
-                    event_cnt--;
-                    TRACE("processed touch event (%d) : x=%d, y=%d, z=%d, state=%d\n",
-                        te->index, s->dx, s->dy, s->dz, s->buttons_state);
-
-                    if (QTAILQ_EMPTY(&events_queue)) {
-                        s->changed = 0;
-                        TRACE("processed all touch events (%d)\n", event_cnt);
-                    }
-                }
-            } else {
-                s->changed = 0;
-            }
-
-            pthread_mutex_unlock(&event_mutex);
-
-            memset(buf, 0, sizeof(buf) * (p->iov.size - 1));
-            ret = usb_touchscreen_poll(s, buf, p->iov.size); //write event to packet
-            usb_packet_copy(p, buf, ret);
-            break;
-        }
-        /* Fall through */
-    case USB_TOKEN_OUT:
-    default:
-        ret = USB_RET_STALL;
-        break;
-    }
-    return ret;
-}
-
-static void usb_touchscreen_handle_destroy(USBDevice *dev)
-{
-    USBTouchscreenState *s = (USBTouchscreenState *) dev;
-
-    if (s->mouse_grabbed == 1) {
-        qemu_remove_mouse_event_handler(s->eh_entry);
-        s->mouse_grabbed = 0;
-    }
-}
-
-/**
- * @brief : initialize a touchscreen device
- * @param opaque : state of device
- */
-static int usb_touchscreen_initfn(USBDevice *dev)
-{
-    USBTouchscreenState *s = DO_UPCAST(USBTouchscreenState, dev, dev);
-    usb_desc_init(dev);
-
-    pthread_mutex_lock(&event_mutex);
-    s->changed = 1;
-    pthread_mutex_unlock(&event_mutex);
-
-    return 0;
-}
-
-/**
- * @brief : remove mouse handlers before loading
- * @param opaque : state of device
- */
-static int touchscreen_pre_load(void *opaque)
-{
-    USBTouchscreenState *s = (USBTouchscreenState *)opaque;
-
-    if (s->eh_entry) {
-        qemu_remove_mouse_event_handler(s->eh_entry);
-    }
-
-    return 0;
-}
-
-static int touchscreen_post_load(void *opaque, int version_id)
-{
-    USBTouchscreenState *s = (USBTouchscreenState *)opaque;
-
-    pthread_mutex_lock(&event_mutex);
-    s->changed = 1;
-    pthread_mutex_unlock(&event_mutex);
-
-    if (s->mouse_grabbed == 1) {
-        s->eh_entry = qemu_add_mouse_event_handler(usb_touchscreen_event, s, 1, "QEMU Virtual touchscreen");
-        qemu_activate_mouse_event_handler(s->eh_entry);
-    }
-
-    return 0;
-}
-
-static VMStateDescription vmsd_usbdevice = {
-    .name = "maru-touchscreen-usbdevice",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .minimum_version_id_old = 1,
-    .fields = (VMStateField []) {
-        VMSTATE_UINT8(addr, USBDevice),
-        VMSTATE_INT32(state, USBDevice),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static VMStateDescription vmsd = {
-    .name = "maru-touchscreen",
-    .version_id = 2,
-    .minimum_version_id = 1,
-    .minimum_version_id_old = 1,
-    .pre_load = touchscreen_pre_load,
-    .post_load = touchscreen_post_load,
-    .fields = (VMStateField []) {
-        VMSTATE_STRUCT(dev, USBTouchscreenState, 1, vmsd_usbdevice, USBDevice),
-        VMSTATE_INT32(dx, USBTouchscreenState),
-        VMSTATE_INT32(dy, USBTouchscreenState),
-        VMSTATE_INT32(dz, USBTouchscreenState),
-        VMSTATE_INT32(buttons_state, USBTouchscreenState),
-        VMSTATE_INT8(mouse_grabbed, USBTouchscreenState),
-        VMSTATE_INT8(changed, USBTouchscreenState),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static struct USBDeviceInfo touchscreen_info = {
-    .product_desc   = "QEMU Virtual Touchscreen",
-    .qdev.name      = "usb-maru-touchscreen",
-    .qdev.desc      = "QEMU Virtual Touchscreen",
-    .usbdevice_name = "maru-touchscreen",
-    .usb_desc       = &desc_touchscreen,
-    .qdev.size      = sizeof(USBTouchscreenState),
-    .qdev.vmsd      = &vmsd,
-    .init           = usb_touchscreen_initfn,
-    .handle_packet  = usb_generic_handle_packet,
-    .handle_reset   = usb_touchscreen_handle_reset,
-    .handle_control = usb_touchscreen_handle_control,
-    .handle_data    = usb_touchscreen_handle_data,
-    .handle_destroy = usb_touchscreen_handle_destroy,
-};
-
-/**
- * @brief : register a touchscreen device
- */
-static void usb_touchscreen_register_devices(void)
-{
-    usb_qdev_register(&touchscreen_info);
-}
-
-device_init(usb_touchscreen_register_devices)
diff --git a/tizen/src/hw/maru_touchscreen.h b/tizen/src/hw/maru_touchscreen.h
deleted file mode 100644 (file)
index f1fcade..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Maru Virtual USB Touchscreen emulation.
- * Based on hw/usb-wacom.c:
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  GiWoong Kim <giwoong.kim@samsung.com>
- *  HyunJun Son <hj79.son@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 MARU_TOUCH_H_
-#define MARU_TOUCH_H_
-
-#include <pthread.h>
-#include "hw.h"
-#include "console.h"
-#include "usb.h"
-#include "usb-desc.h"
-
-
-typedef struct USBTouchscreenState {
-    USBDevice dev;
-    QEMUPutMouseEntry *eh_entry;
-
-    int32_t dx, dy, dz, buttons_state;
-    int8_t mouse_grabbed;
-    int8_t changed;
-} USBTouchscreenState;
-
-/* This structure must match the kernel definitions */
-typedef struct USBEmulTouchscreenPacket {
-    uint16_t x, y, z;
-    uint8_t state;
-} USBEmulTouchscreenPacket;
-
-
-#define EMUL_TOUCHSCREEN_PACKET_LEN 7
-#define TOUCHSCREEN_RESOLUTION_X 5040
-#define TOUCHSCREEN_RESOLUTION_Y 3780
-
-enum {
-    STR_MANUFACTURER = 1,
-    STR_PRODUCT,
-    STR_SERIALNUMBER,
-};
-
-static const USBDescStrings desc_strings = {
-    [STR_MANUFACTURER]     = "QEMU " QEMU_VERSION,
-    [STR_PRODUCT]          = "Maru Virtual Touchscreen",
-    [STR_SERIALNUMBER]     = "1",
-};
-
-static const USBDescIface desc_iface_touchscreen = {
-    .bInterfaceNumber              = 0,
-    .bNumEndpoints                 = 1,
-    .bInterfaceClass               = USB_CLASS_HID,
-    .bInterfaceSubClass            = 0x01, /* boot */
-    .bInterfaceProtocol            = 0x02,
-    .ndesc                         = 1,
-    .descs = (USBDescOther[]) {
-        {
-            /* HID descriptor */
-            .data = (uint8_t[]) {
-                0x09,          /*  u8  bLength */
-                0x21,          /*  u8  bDescriptorType */
-                0x01, 0x10,    /*  u16 HID_class */
-                0x00,          /*  u8  country_code */
-                0x01,          /*  u8  num_descriptors */
-                0x22,          /*  u8  type: Report */
-                0x6e, 0,       /*  u16 len */
-            },
-        },
-    },
-    .eps = (USBDescEndpoint[]) {
-        {
-            .bEndpointAddress      = USB_DIR_IN | 0x01,
-            .bmAttributes          = USB_ENDPOINT_XFER_INT,
-            .wMaxPacketSize        = 8,
-            .bInterval             = 0x0a,
-        },
-    },
-};
-
-static const USBDescDevice desc_device_touchscreen = {
-    .bcdUSB                        = 0x0110,
-    .bMaxPacketSize0               = EMUL_TOUCHSCREEN_PACKET_LEN + 1,
-    .bNumConfigurations            = 1,
-    .confs = (USBDescConfig[]) {
-        {
-            .bNumInterfaces        = 1,
-            .bConfigurationValue   = 1,
-            .bmAttributes          = 0x80,
-            .bMaxPower             = 40,
-            .nif = 1,
-            .ifs = &desc_iface_touchscreen,
-        },
-    },
-};
-
-static const USBDesc desc_touchscreen = {
-    .id = {
-        .idVendor          = 0x056a,
-        .idProduct         = 0x0000,
-        .bcdDevice         = 0x0010,
-        .iManufacturer     = STR_MANUFACTURER,
-        .iProduct          = STR_PRODUCT,
-        .iSerialNumber     = STR_SERIALNUMBER,
-    },
-    .full = &desc_device_touchscreen,
-    .str = desc_strings,
-};
-
-typedef struct TouchEventEntry {
-    USBEmulTouchscreenPacket queue_packet;
-    int index;
-
-    /* used internally by qemu for handling mice */
-    QTAILQ_ENTRY(TouchEventEntry) node;
-} TouchEventEntry;
-
-#endif /* MARU_TOUCH_H_ */
diff --git a/tizen/src/hw/maru_usb_touchscreen.c b/tizen/src/hw/maru_usb_touchscreen.c
new file mode 100644 (file)
index 0000000..ea8c570
--- /dev/null
@@ -0,0 +1,315 @@
+/*
+ * Maru Virtual USB Touchscreen emulation.
+ * Based on hw/usb-wacom.c:
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  GiWoong Kim <giwoong.kim@samsung.com>
+ *  HyunJun Son <hj79.son@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 "maru_usb_touchscreen.h"
+#include "debug_ch.h"
+
+MULTI_DEBUG_CHANNEL(qemu, usb_touchscreen);
+
+
+#define MAX_TOUCH_EVENT_CNT 128
+
+//lock for between communication thread and main thread
+static pthread_mutex_t event_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static QTAILQ_HEAD(, TouchEventEntry) events_queue =
+    QTAILQ_HEAD_INITIALIZER(events_queue);
+
+static unsigned int event_cnt = 0;
+static unsigned int _processed_buf_cnt = 0;
+static TouchEventEntry _event_buf[MAX_TOUCH_EVENT_CNT];
+
+/**
+ * @brief : qemu touch(host mouse) event handler
+ * @param opaque : state of device
+ * @param x : X-axis value
+ * @param y : Y-axis value
+ * @param z : event id for multiple touch
+ */
+static void usb_touchscreen_event(void *opaque, int x, int y, int z, int buttons_state)
+{
+    TouchEventEntry *te;
+    USBTouchscreenState *s = opaque;
+
+    pthread_mutex_lock(&event_mutex);
+    if (event_cnt >= MAX_TOUCH_EVENT_CNT) {
+        pthread_mutex_unlock(&event_mutex);
+        INFO("full touch event queue, lose event\n", event_cnt);
+        return;
+    }
+
+    //using prepared memory
+    te = &(_event_buf[_processed_buf_cnt % MAX_TOUCH_EVENT_CNT]);
+    _processed_buf_cnt++;
+
+    /* mouse event is copied into the queue */
+    te->index = ++event_cnt;
+    te->queue_packet.x = x;
+    te->queue_packet.y = y;
+    te->queue_packet.z = z;
+    te->queue_packet.state = buttons_state;
+
+    QTAILQ_INSERT_TAIL(&events_queue, te, node);
+    s->changed = 1;
+    pthread_mutex_unlock(&event_mutex);
+
+    TRACE("touch event (%d) : x=%d, y=%d, z=%d, state=%d\n", te->index, x, y, z, buttons_state);
+}
+
+/**
+ * @brief : fill the usb packet
+ * @param s : state of device
+ * @param buf : usb packet
+ * @param len : size of packet
+ */
+static int usb_touchscreen_poll(USBTouchscreenState *s, uint8_t *buf, int len)
+{
+    USBEmulTouchscreenPacket *packet = (USBEmulTouchscreenPacket *)buf;
+
+    if (s->mouse_grabbed == 0) {
+        s->eh_entry = qemu_add_mouse_event_handler(usb_touchscreen_event, s, 1, "QEMU Virtual touchscreen");
+        qemu_activate_mouse_event_handler(s->eh_entry);
+        s->mouse_grabbed = 1;
+    }
+
+    if (len < EMUL_TOUCHSCREEN_PACKET_LEN) {
+        return 0;
+    }
+
+    packet->x = s->dx & 0xffff;
+    packet->y = s->dy & 0xffff;
+    packet->z = s->dz & 0xffff;
+
+    if (s->buttons_state == 0) {
+        packet->state = 0;
+    } else {
+        packet->state = 1;
+    }
+
+    return EMUL_TOUCHSCREEN_PACKET_LEN;
+}
+
+static void usb_touchscreen_handle_reset(USBDevice *dev)
+{
+    USBTouchscreenState *s = (USBTouchscreenState *) dev;
+
+    pthread_mutex_lock(&event_mutex);
+
+    s->dx = 0;
+    s->dy = 0;
+    s->dz = 0;
+    s->buttons_state = 0;
+
+    event_cnt = 0;
+    _processed_buf_cnt = 0;
+
+    pthread_mutex_unlock(&event_mutex);
+}
+
+static int usb_touchscreen_handle_control(USBDevice *dev, USBPacket *p,
+    int request, int value, int index, int length, uint8_t *data)
+{
+    return usb_desc_handle_control(dev, p, request, value, index, length, data);
+}
+
+/**
+ * @brief : call by uhci frame timer
+ * @param dev : state of device
+ * @param p : usb packet
+ */
+static int usb_touchscreen_handle_data(USBDevice *dev, USBPacket *p)
+{
+    USBTouchscreenState *s = (USBTouchscreenState *) dev;
+    uint8_t buf[p->iov.size];
+    int ret = 0;
+
+    switch (p->pid) {
+    case USB_TOKEN_IN:
+        if (p->devep == 1) {
+            pthread_mutex_lock(&event_mutex);
+
+            if (s->changed == 0) {
+                pthread_mutex_unlock(&event_mutex);
+                return USB_RET_NAK;
+            }
+
+            if (event_cnt != 0) {
+                if (!QTAILQ_EMPTY(&events_queue)) {
+                    TouchEventEntry *te = QTAILQ_FIRST(&events_queue);
+
+                    s->dx = te->queue_packet.x;
+                    s->dy = te->queue_packet.y;
+                    s->dz = te->queue_packet.z;
+                    s->buttons_state = te->queue_packet.state;
+
+                    QTAILQ_REMOVE(&events_queue, te, node);
+                    event_cnt--;
+                    TRACE("processed touch event (%d) : x=%d, y=%d, z=%d, state=%d\n",
+                        te->index, s->dx, s->dy, s->dz, s->buttons_state);
+
+                    if (QTAILQ_EMPTY(&events_queue)) {
+                        s->changed = 0;
+                        TRACE("processed all touch events (%d)\n", event_cnt);
+                    }
+                }
+            } else {
+                s->changed = 0;
+            }
+
+            pthread_mutex_unlock(&event_mutex);
+
+            memset(buf, 0, sizeof(buf) * (p->iov.size - 1));
+            ret = usb_touchscreen_poll(s, buf, p->iov.size); //write event to packet
+            usb_packet_copy(p, buf, ret);
+            break;
+        }
+        /* Fall through */
+    case USB_TOKEN_OUT:
+    default:
+        ret = USB_RET_STALL;
+        break;
+    }
+    return ret;
+}
+
+static void usb_touchscreen_handle_destroy(USBDevice *dev)
+{
+    USBTouchscreenState *s = (USBTouchscreenState *) dev;
+
+    if (s->mouse_grabbed == 1) {
+        qemu_remove_mouse_event_handler(s->eh_entry);
+        s->mouse_grabbed = 0;
+    }
+}
+
+/**
+ * @brief : initialize a touchscreen device
+ * @param opaque : state of device
+ */
+static int usb_touchscreen_initfn(USBDevice *dev)
+{
+    USBTouchscreenState *s = DO_UPCAST(USBTouchscreenState, dev, dev);
+    usb_desc_init(dev);
+
+    pthread_mutex_lock(&event_mutex);
+    s->changed = 1;
+    pthread_mutex_unlock(&event_mutex);
+
+    return 0;
+}
+
+/**
+ * @brief : remove mouse handlers before loading
+ * @param opaque : state of device
+ */
+static int touchscreen_pre_load(void *opaque)
+{
+    USBTouchscreenState *s = (USBTouchscreenState *)opaque;
+
+    if (s->eh_entry) {
+        qemu_remove_mouse_event_handler(s->eh_entry);
+    }
+
+    return 0;
+}
+
+static int touchscreen_post_load(void *opaque, int version_id)
+{
+    USBTouchscreenState *s = (USBTouchscreenState *)opaque;
+
+    pthread_mutex_lock(&event_mutex);
+    s->changed = 1;
+    pthread_mutex_unlock(&event_mutex);
+
+    if (s->mouse_grabbed == 1) {
+        s->eh_entry = qemu_add_mouse_event_handler(usb_touchscreen_event, s, 1, "QEMU Virtual touchscreen");
+        qemu_activate_mouse_event_handler(s->eh_entry);
+    }
+
+    return 0;
+}
+
+static VMStateDescription vmsd_usbdevice = {
+    .name = "maru-touchscreen-usbdevice",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields = (VMStateField []) {
+        VMSTATE_UINT8(addr, USBDevice),
+        VMSTATE_INT32(state, USBDevice),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static VMStateDescription vmsd = {
+    .name = "maru-touchscreen",
+    .version_id = 2,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .pre_load = touchscreen_pre_load,
+    .post_load = touchscreen_post_load,
+    .fields = (VMStateField []) {
+        VMSTATE_STRUCT(dev, USBTouchscreenState, 1, vmsd_usbdevice, USBDevice),
+        VMSTATE_INT32(dx, USBTouchscreenState),
+        VMSTATE_INT32(dy, USBTouchscreenState),
+        VMSTATE_INT32(dz, USBTouchscreenState),
+        VMSTATE_INT32(buttons_state, USBTouchscreenState),
+        VMSTATE_INT8(mouse_grabbed, USBTouchscreenState),
+        VMSTATE_INT8(changed, USBTouchscreenState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static struct USBDeviceInfo touchscreen_info = {
+    .product_desc   = "QEMU Virtual Touchscreen",
+    .qdev.name      = "usb-maru-touchscreen",
+    .qdev.desc      = "QEMU Virtual Touchscreen",
+    .usbdevice_name = "maru-touchscreen",
+    .usb_desc       = &desc_touchscreen,
+    .qdev.size      = sizeof(USBTouchscreenState),
+    .qdev.vmsd      = &vmsd,
+    .init           = usb_touchscreen_initfn,
+    .handle_packet  = usb_generic_handle_packet,
+    .handle_reset   = usb_touchscreen_handle_reset,
+    .handle_control = usb_touchscreen_handle_control,
+    .handle_data    = usb_touchscreen_handle_data,
+    .handle_destroy = usb_touchscreen_handle_destroy,
+};
+
+/**
+ * @brief : register a touchscreen device
+ */
+static void usb_touchscreen_register_devices(void)
+{
+    usb_qdev_register(&touchscreen_info);
+}
+
+device_init(usb_touchscreen_register_devices)
diff --git a/tizen/src/hw/maru_usb_touchscreen.h b/tizen/src/hw/maru_usb_touchscreen.h
new file mode 100644 (file)
index 0000000..f1fcade
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Maru Virtual USB Touchscreen emulation.
+ * Based on hw/usb-wacom.c:
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  GiWoong Kim <giwoong.kim@samsung.com>
+ *  HyunJun Son <hj79.son@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 MARU_TOUCH_H_
+#define MARU_TOUCH_H_
+
+#include <pthread.h>
+#include "hw.h"
+#include "console.h"
+#include "usb.h"
+#include "usb-desc.h"
+
+
+typedef struct USBTouchscreenState {
+    USBDevice dev;
+    QEMUPutMouseEntry *eh_entry;
+
+    int32_t dx, dy, dz, buttons_state;
+    int8_t mouse_grabbed;
+    int8_t changed;
+} USBTouchscreenState;
+
+/* This structure must match the kernel definitions */
+typedef struct USBEmulTouchscreenPacket {
+    uint16_t x, y, z;
+    uint8_t state;
+} USBEmulTouchscreenPacket;
+
+
+#define EMUL_TOUCHSCREEN_PACKET_LEN 7
+#define TOUCHSCREEN_RESOLUTION_X 5040
+#define TOUCHSCREEN_RESOLUTION_Y 3780
+
+enum {
+    STR_MANUFACTURER = 1,
+    STR_PRODUCT,
+    STR_SERIALNUMBER,
+};
+
+static const USBDescStrings desc_strings = {
+    [STR_MANUFACTURER]     = "QEMU " QEMU_VERSION,
+    [STR_PRODUCT]          = "Maru Virtual Touchscreen",
+    [STR_SERIALNUMBER]     = "1",
+};
+
+static const USBDescIface desc_iface_touchscreen = {
+    .bInterfaceNumber              = 0,
+    .bNumEndpoints                 = 1,
+    .bInterfaceClass               = USB_CLASS_HID,
+    .bInterfaceSubClass            = 0x01, /* boot */
+    .bInterfaceProtocol            = 0x02,
+    .ndesc                         = 1,
+    .descs = (USBDescOther[]) {
+        {
+            /* HID descriptor */
+            .data = (uint8_t[]) {
+                0x09,          /*  u8  bLength */
+                0x21,          /*  u8  bDescriptorType */
+                0x01, 0x10,    /*  u16 HID_class */
+                0x00,          /*  u8  country_code */
+                0x01,          /*  u8  num_descriptors */
+                0x22,          /*  u8  type: Report */
+                0x6e, 0,       /*  u16 len */
+            },
+        },
+    },
+    .eps = (USBDescEndpoint[]) {
+        {
+            .bEndpointAddress      = USB_DIR_IN | 0x01,
+            .bmAttributes          = USB_ENDPOINT_XFER_INT,
+            .wMaxPacketSize        = 8,
+            .bInterval             = 0x0a,
+        },
+    },
+};
+
+static const USBDescDevice desc_device_touchscreen = {
+    .bcdUSB                        = 0x0110,
+    .bMaxPacketSize0               = EMUL_TOUCHSCREEN_PACKET_LEN + 1,
+    .bNumConfigurations            = 1,
+    .confs = (USBDescConfig[]) {
+        {
+            .bNumInterfaces        = 1,
+            .bConfigurationValue   = 1,
+            .bmAttributes          = 0x80,
+            .bMaxPower             = 40,
+            .nif = 1,
+            .ifs = &desc_iface_touchscreen,
+        },
+    },
+};
+
+static const USBDesc desc_touchscreen = {
+    .id = {
+        .idVendor          = 0x056a,
+        .idProduct         = 0x0000,
+        .bcdDevice         = 0x0010,
+        .iManufacturer     = STR_MANUFACTURER,
+        .iProduct          = STR_PRODUCT,
+        .iSerialNumber     = STR_SERIALNUMBER,
+    },
+    .full = &desc_device_touchscreen,
+    .str = desc_strings,
+};
+
+typedef struct TouchEventEntry {
+    USBEmulTouchscreenPacket queue_packet;
+    int index;
+
+    /* used internally by qemu for handling mice */
+    QTAILQ_ENTRY(TouchEventEntry) node;
+} TouchEventEntry;
+
+#endif /* MARU_TOUCH_H_ */