Direct Rendering: New feature added 90/33990/3
authorjinhyung.jo <jinhyung.jo@samsung.com>
Wed, 14 Jan 2015 10:05:16 +0000 (19:05 +0900)
committerjinhyung.jo <jinhyung.jo@samsung.com>
Tue, 20 Jan 2015 09:03:39 +0000 (18:03 +0900)
Modified the vigs & the yagl device for the direct rendering
Added Qt5 UI for the direct rendering
This is a compressed many commits produced by several authors below into one.

Change-Id: I455f607c363851c57d0a250f1220ede6027e1ea0
Signed-off-by: GiWoong Kim <giwoong.kim@samsung.com>
Signed-off-by: Stanislav Vorobiov <s.vorobiov@samsung.com>
Signed-off-by: Vasiliy Ulyanov <v.ulyanov@samsung.com>
Signed-off-by: SungMin Ha <sungmin82.ha@samsung.com>
Signed-off-by: hyunjin816.lee <hyunjin816.lee@samsung.com>
Signed-off-by: Munkyu Im <munkyu.im@samsung.com>
Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
Signed-off-by: Jinhyung Jo <jinhyung.jo@samsung.com>
153 files changed:
configure
hw/vigs/Makefile.objs
hw/vigs/display.c
hw/vigs/vigs_backend.h
hw/vigs/vigs_device.c
hw/vigs/vigs_gl_backend.c
hw/vigs/vigs_gl_backend.h
hw/vigs/vigs_gl_backend_cgl.c
hw/vigs/vigs_gl_backend_glx.c
hw/vigs/vigs_gl_backend_wgl.c
hw/vigs/vigs_inc/GL/gl.h
hw/vigs/vigs_offscreen_server.c [new file with mode: 0644]
hw/vigs/vigs_offscreen_server.h [new file with mode: 0644]
hw/vigs/vigs_onscreen_server.c [new file with mode: 0644]
hw/vigs/vigs_onscreen_server.h [new file with mode: 0644]
hw/vigs/vigs_qt5.cpp [new file with mode: 0644]
hw/vigs/vigs_qt5.h [new file with mode: 0644]
hw/vigs/vigs_qt5_stub.c [new file with mode: 0644]
hw/vigs/vigs_server.c
hw/vigs/vigs_server.h
hw/vigs/vigs_sw_backend.c
hw/yagl/Makefile.objs
hw/yagl/yagl_drivers/egl_cgl/yagl_egl_cgl.c
hw/yagl/yagl_drivers/egl_glx/yagl_egl_glx.c
hw/yagl/yagl_drivers/egl_wgl/yagl_egl_wgl.c
include/sysemu/sysemu.h
include/ui/console.h
tizen/emulator_configure.sh
tizen/src/Makefile
tizen/src/Makefile.objs
tizen/src/display/Makefile.objs
tizen/src/display/maru_display.c
tizen/src/display/maru_display.h
tizen/src/display/maru_finger.c
tizen/src/display/maru_finger.h
tizen/src/display/maru_shm.c
tizen/src/display/qt5.c [new file with mode: 0644]
tizen/src/display/qt5_supplement.cpp [new file with mode: 0644]
tizen/src/display/qt5_supplement.h [new file with mode: 0644]
tizen/src/emul_state.c
tizen/src/emul_state.h
tizen/src/emulator.c
tizen/src/emulator_legacy.c
tizen/src/ns_event.h
tizen/src/ns_event.m
tizen/src/skin/maruskin_keymap.h
tizen/src/skin/maruskin_operation.c
tizen/src/skin/maruskin_operation.h
tizen/src/skin/maruskin_server.c
tizen/src/skin/maruskin_server.h
tizen/src/ui/Makefile.objs [new file with mode: 0644]
tizen/src/ui/controllerform.cpp [new file with mode: 0644]
tizen/src/ui/controllerform.h [new file with mode: 0644]
tizen/src/ui/displaybase.cpp [new file with mode: 0644]
tizen/src/ui/displaybase.h [new file with mode: 0644]
tizen/src/ui/displayglwidget.cpp [new file with mode: 0644]
tizen/src/ui/displayglwidget.h [new file with mode: 0644]
tizen/src/ui/displayswwidget.cpp [new file with mode: 0644]
tizen/src/ui/displayswwidget.h [new file with mode: 0644]
tizen/src/ui/dockingcontroller.cpp [new file with mode: 0644]
tizen/src/ui/dockingcontroller.h [new file with mode: 0644]
tizen/src/ui/dockingconview.cpp [new file with mode: 0644]
tizen/src/ui/dockingconview.h [new file with mode: 0644]
tizen/src/ui/floatingcontroller.cpp [new file with mode: 0644]
tizen/src/ui/floatingcontroller.h [new file with mode: 0644]
tizen/src/ui/floatingconview.cpp [new file with mode: 0644]
tizen/src/ui/floatingconview.h [new file with mode: 0644]
tizen/src/ui/hardwarekey.cpp [new file with mode: 0644]
tizen/src/ui/hardwarekey.h [new file with mode: 0644]
tizen/src/ui/keyboardhelper.cpp [new file with mode: 0644]
tizen/src/ui/keyboardhelper.h [new file with mode: 0644]
tizen/src/ui/mainform.cpp [new file with mode: 0644]
tizen/src/ui/mainform.h [new file with mode: 0644]
tizen/src/ui/mainwindow.cpp [new file with mode: 0644]
tizen/src/ui/mainwindow.h [new file with mode: 0644]
tizen/src/ui/menu/Makefile.objs [new file with mode: 0644]
tizen/src/ui/menu/aboutdialog.cpp [new file with mode: 0644]
tizen/src/ui/menu/aboutdialog.h [new file with mode: 0644]
tizen/src/ui/menu/contextmenu.cpp [new file with mode: 0644]
tizen/src/ui/menu/contextmenu.h [new file with mode: 0644]
tizen/src/ui/menu/detailedinfodialog.cpp [new file with mode: 0644]
tizen/src/ui/menu/detailedinfodialog.h [new file with mode: 0644]
tizen/src/ui/menu/screenshot.cpp [new file with mode: 0644]
tizen/src/ui/menu/screenshot.h [new file with mode: 0644]
tizen/src/ui/menu/screenshotview.cpp [new file with mode: 0644]
tizen/src/ui/menu/screenshotview.h [new file with mode: 0644]
tizen/src/ui/resource/about.png [new file with mode: 0644]
tizen/src/ui/resource/icons/about.png [new file with mode: 0644]
tizen/src/ui/resource/icons/advanced.png [new file with mode: 0644]
tizen/src/ui/resource/icons/close.png [new file with mode: 0644]
tizen/src/ui/resource/icons/control_panel.png [new file with mode: 0644]
tizen/src/ui/resource/icons/copy_screenshot_dialog.png [new file with mode: 0644]
tizen/src/ui/resource/icons/detailed_info.png [new file with mode: 0644]
tizen/src/ui/resource/icons/emulator_icon.ico [new file with mode: 0644]
tizen/src/ui/resource/icons/force_close.png [new file with mode: 0644]
tizen/src/ui/resource/icons/host_keyboard.png [new file with mode: 0644]
tizen/src/ui/resource/icons/refresh_screenshot_dialog.png [new file with mode: 0644]
tizen/src/ui/resource/icons/rotate.png [new file with mode: 0644]
tizen/src/ui/resource/icons/save_screenshot_dialog.png [new file with mode: 0644]
tizen/src/ui/resource/icons/scale.png [new file with mode: 0644]
tizen/src/ui/resource/icons/screen_shot.png [new file with mode: 0644]
tizen/src/ui/resource/icons/shell.png [new file with mode: 0644]
tizen/src/ui/resource/mobile-720x1280-3btn/default.dbi [new file with mode: 0644]
tizen/src/ui/resource/mobile-720x1280-3btn/default_0.png [new file with mode: 0644]
tizen/src/ui/resource/mobile-720x1280-3btn/default_0_p.png [new file with mode: 0644]
tizen/src/ui/resource/mobile-720x1280-3btn/default_180.png [new file with mode: 0644]
tizen/src/ui/resource/mobile-720x1280-3btn/default_180_p.png [new file with mode: 0644]
tizen/src/ui/resource/mobile-720x1280-3btn/default_L90.png [new file with mode: 0644]
tizen/src/ui/resource/mobile-720x1280-3btn/default_L90_p.png [new file with mode: 0644]
tizen/src/ui/resource/mobile-720x1280-3btn/default_R90.png [new file with mode: 0644]
tizen/src/ui/resource/mobile-720x1280-3btn/default_R90_p.png [new file with mode: 0644]
tizen/src/ui/resource/mobile-720x1280-3btn/info.ini [new file with mode: 0644]
tizen/src/ui/resource/mobile-720x1280-3btn/layout.qml [new file with mode: 0644]
tizen/src/ui/resource/resource.qrc [new file with mode: 0644]
tizen/src/ui/resource/wearable-320x320-1btn/default.dbi [new file with mode: 0644]
tizen/src/ui/resource/wearable-320x320-1btn/default_0.png [new file with mode: 0755]
tizen/src/ui/resource/wearable-320x320-1btn/default_0_p.png [new file with mode: 0644]
tizen/src/ui/resource/wearable-320x320-1btn/default_180.png [new file with mode: 0644]
tizen/src/ui/resource/wearable-320x320-1btn/default_180_p.png [new file with mode: 0644]
tizen/src/ui/resource/wearable-320x320-1btn/default_L90.png [new file with mode: 0644]
tizen/src/ui/resource/wearable-320x320-1btn/default_L90_p.png [new file with mode: 0644]
tizen/src/ui/resource/wearable-320x320-1btn/default_R90.png [new file with mode: 0644]
tizen/src/ui/resource/wearable-320x320-1btn/default_R90_p.png [new file with mode: 0644]
tizen/src/ui/resource/wearable-320x320-1btn/info.ini [new file with mode: 0644]
tizen/src/ui/resource/wearable-320x320-1btn/layout.qml [new file with mode: 0644]
tizen/src/ui/skinbezelitem.cpp [new file with mode: 0644]
tizen/src/ui/skinbezelitem.h [new file with mode: 0644]
tizen/src/ui/skinkeyitem.cpp [new file with mode: 0644]
tizen/src/ui/skinkeyitem.h [new file with mode: 0644]
tizen/src/ui/skinview.cpp [new file with mode: 0644]
tizen/src/ui/skinview.h [new file with mode: 0644]
tizen/src/ui/uiinformation.cpp [new file with mode: 0644]
tizen/src/ui/uiinformation.h [new file with mode: 0644]
tizen/src/ui/uistate.cpp [new file with mode: 0644]
tizen/src/ui/uistate.h [new file with mode: 0644]
tizen/src/ui/uiutil.cpp [new file with mode: 0644]
tizen/src/ui/uiutil.h [new file with mode: 0644]
tizen/src/ui/xml/Makefile.objs [new file with mode: 0644]
tizen/src/ui/xml/emulatoruitype.cpp [new file with mode: 0644]
tizen/src/ui/xml/emulatoruitype.h [new file with mode: 0644]
tizen/src/ui/xml/formlisttype.cpp [new file with mode: 0644]
tizen/src/ui/xml/formlisttype.h [new file with mode: 0644]
tizen/src/ui/xml/formtype.cpp [new file with mode: 0644]
tizen/src/ui/xml/formtype.h [new file with mode: 0644]
tizen/src/ui/xml/hardwarekeytype.cpp [new file with mode: 0644]
tizen/src/ui/xml/hardwarekeytype.h [new file with mode: 0644]
tizen/src/ui/xml/keylisttype.cpp [new file with mode: 0644]
tizen/src/ui/xml/keylisttype.h [new file with mode: 0644]
tizen/src/ui/xml/regiontype.cpp [new file with mode: 0644]
tizen/src/ui/xml/regiontype.h [new file with mode: 0644]
tizen/src/util/Makefile.objs
tizen/src/util/check_gl_cgl.c
vl.c

index 0a54bb8..8ad78b8 100755 (executable)
--- a/configure
+++ b/configure
@@ -337,6 +337,8 @@ libav="no"
 libpng="no"
 dxva2="no"
 vaapi="no"
+qt="no"
+qtabi="5.0"
 #
 glusterfs=""
 glusterfs_discard="no"
@@ -1144,6 +1146,10 @@ for opt do
   ;;
   --enable-vaapi) vaapi="yes"
   ;;
+  --disable-qt) qt="no"
+  ;;
+  --enable-qt) qt="yes"
+  ;;
 #
   --disable-glusterfs) glusterfs="no"
   ;;
@@ -1337,6 +1343,8 @@ Advanced options (experts only):
   --disable-gtk            disable gtk UI
   --enable-gtk             enable gtk UI
   --with-gtkabi            select preferred GTK ABI 2.0 or 3.0
+  --disable-qt             disable Qt5 UI
+  --enable-qt              enable Qt5 UI
   --disable-virtfs         disable VirtFS
   --enable-virtfs          enable VirtFS
   --disable-vnc            disable VNC
@@ -2178,6 +2186,42 @@ if test "$vte" != "no"; then
 fi
 
 ##########################################
+# Qt probe
+
+qtversion=""
+if test "$qt" != "no"; then
+    if test "$qtabi" = "5.0" ; then
+        qtpackage="Qt5Widgets Qt5Qml Qt5OpenGL Qt5Gui"
+        qtversion="5.0.0"
+
+        if $pkg_config --exists "$qtpackage >= $qtversion"; then
+            qt_cflags=`$pkg_config --cflags $qtpackage`
+            qt_libs=`$pkg_config --libs $qtpackage`
+            libs_softmmu="$qt_libs $libs_softmmu"
+
+            qt_cflags_private=`pkg-config --modversion Qt5Gui`
+            if test "$darwin" = "yes" ; then
+                qt_cflags_private=`pkg-config --cflags Qt5Gui | sed "s,QtGui.framework/Headers,&/$qt_cflags_private/QtGui,g"`
+            else
+                qt_cflags_private=`pkg-config --cflags Qt5Gui | sed "s,QtGui,&/$qt_cflags_private/QtGui,g"`
+            fi
+
+            qt_cflags="$qt_cflags $qt_cflags_private"
+            if test "$mingw32" = "no" ; then
+                qt_cflags="$qt_cflags -fPIC"
+            fi
+            qt="yes"
+        elif test "$qt" = "yes"; then
+            feature_not_found "qt" "Install qt devel"
+        else
+            qt="no"
+        fi
+    else
+        qt="no"
+    fi
+fi
+
+##########################################
 # SDL probe
 
 # Look for sdl configuration program (pkg-config or sdl-config).  Try
@@ -4499,6 +4543,7 @@ fi
 echo "pixman            $pixman"
 echo "SDL support       $sdl"
 echo "GTK support       $gtk"
+echo "Qt support        $qt"
 echo "VTE support       $vte"
 echo "curses support    $curses"
 echo "curl support      $curl"
@@ -4863,6 +4908,10 @@ if test "$vte" = "yes" ; then
   echo "CONFIG_VTE=y" >> $config_host_mak
   echo "VTE_CFLAGS=$vte_cflags" >> $config_host_mak
 fi
+if test "$qt" = "yes" ; then
+  echo "CONFIG_QT=y" >> $config_host_mak
+  echo "QT_CFLAGS=$qt_cflags" >> $config_host_mak
+fi
 if test "$xen" = "yes" ; then
   echo "CONFIG_XEN_BACKEND=y" >> $config_host_mak
   echo "CONFIG_XEN_CTRL_INTERFACE_VERSION=$xen_ctrl_version" >> $config_host_mak
index 967bf46..3ebd185 100644 (file)
@@ -1,11 +1,11 @@
 # VIGS
-QEMU_CFLAGS += -I$(SRC_PATH)/hw/vigs/vigs_inc
-
 obj-y += vigs_log.o
 obj-y += vigs_device.o
 libs_softmmu += $(GLX_LIBS)
 obj-y += vigs_comm.o
 obj-y += vigs_server.o
+obj-y += vigs_onscreen_server.o
+obj-y += vigs_offscreen_server.o
 obj-y += vigs_backend.o
 obj-y += vigs_surface.o
 obj-y += vigs_utils.o
@@ -15,9 +15,16 @@ obj-y += vigs_fenceman.o
 obj-y += vigs_gl_pool.o
 obj-y += vigs_gl_backend.o
 obj-y += vigs_sw_backend.o
+obj-$(CONFIG_QT) += vigs_qt5.o
+ifndef CONFIG_QT
+obj-y += vigs_qt5_stub.o
+endif
 obj-y += work_queue.o
 obj-y += winsys.o
 obj-y += display.o
+
+$(obj)/vigs_qt5.o: QEMU_CFLAGS += $(QT_CFLAGS)
+
 # GL GLX backend
 ifdef CONFIG_LINUX
 obj-y += vigs_gl_backend_glx.o
@@ -25,8 +32,10 @@ endif
 # GL WGL backend
 ifdef CONFIG_WIN32
 obj-y += vigs_gl_backend_wgl.o
+$(obj)/%.o: QEMU_CFLAGS += -I$(SRC_PATH)/hw/vigs/vigs_inc
 endif
 # GL CGL backend
 ifdef CONFIG_DARWIN
 obj-y += vigs_gl_backend_cgl.o
+$(obj)/%.o: QEMU_CFLAGS += -I$(SRC_PATH)/hw/vigs/vigs_inc
 endif
index 961e7aa..65dae3e 100644 (file)
@@ -1,4 +1,5 @@
 #include "display.h"
+#include "vigs_qt5.h"
 #include "qom/object_interfaces.h"
 #if defined(CONFIG_LINUX)
 #include <X11/Xlib.h>
@@ -24,7 +25,11 @@ static void displayobject_complete(UserCreatable *obj, Error **errp)
     XSetErrorHandler(x_error_handler);
     XInitThreads();
 
-    dobj->dpy = XOpenDisplay(0);
+    dobj->dpy = (Display*)vigs_qt5_display();
+
+    if (!dobj->dpy) {
+        dobj->dpy = XOpenDisplay(0);
+    }
 
     if (!dobj->dpy) {
         error_setg(errp, "Cannot open X display");
index cffcd2b..bbbd90a 100644 (file)
@@ -36,16 +36,6 @@ struct winsys_info;
 struct vigs_surface;
 struct vigs_plane;
 
-typedef uint8_t *(*vigs_composite_start_cb)(void */*user_data*/,
-                                            uint32_t /*width*/,
-                                            uint32_t /*height*/,
-                                            uint32_t /*stride*/,
-                                            vigsp_surface_format /*format*/);
-
-typedef void (*vigs_composite_end_cb)(void */*user_data*/,
-                                      bool /*was_started*/,
-                                      bool /*dirty*/);
-
 struct vigs_backend
 {
     struct winsys_info *ws_info;
@@ -59,14 +49,19 @@ struct vigs_backend
                                            vigsp_surface_format /*format*/,
                                            vigsp_surface_id /*id*/);
 
-    void (*composite)(struct vigs_surface */*surface*/,
+    bool (*composite)(struct vigs_surface */*surface*/,
                       const struct vigs_plane */*planes*/,
-                      vigs_composite_start_cb /*start_cb*/,
-                      vigs_composite_end_cb /*end_cb*/,
-                      void */*user_data*/);
+                      bool /*planes_dirty*/,
+                      uint8_t */*display_data*/);
+
+    bool (*capture)(struct vigs_surface */*surface*/,
+                    void */*pixels*/);
 
     void (*batch_end)(struct vigs_backend */*backend*/);
 
+    bool (*display)(struct vigs_backend */*backend*/,
+                    uint8_t */*display_data*/);
+
     void (*destroy)(struct vigs_backend */*backend*/);
 };
 
index 562704b..e2b02c4 100644 (file)
  */
 
 #include "vigs_log.h"
-#include "vigs_server.h"
+#include "vigs_onscreen_server.h"
+#include "vigs_offscreen_server.h"
 #include "vigs_backend.h"
 #include "vigs_regs.h"
 #include "vigs_fenceman.h"
+#include "vigs_qt5.h"
 #include "display.h"
 #include "work_queue.h"
 #include "winsys.h"
@@ -145,6 +147,29 @@ static void vigs_hw_update(void *opaque)
     }
 }
 
+static void vigs_hw_display(void *opaque, console_ch_t *text)
+{
+    VIGSState *s = opaque;
+    DisplaySurface *ds = qemu_console_surface(s->con);
+    bool displayed;
+
+    if (!surface_data(ds)) {
+        return;
+    }
+
+    if (vigs_server_display(s->server, &displayed)) {
+        /*
+         * 'vigs_server_display' could have updated the surface,
+         * so fetch it again.
+         */
+        ds = qemu_console_surface(s->con);
+
+        dpy_gfx_update(s->con, 0, 0, surface_width(ds), surface_height(ds));
+    }
+
+    *text = displayed;
+}
+
 static void vigs_hw_invalidate(void *opaque)
 {
     VIGSState *s = opaque;
@@ -266,10 +291,33 @@ static void vigs_io_write(void *opaque, hwaddr offset,
     }
 }
 
+static void vigs_register_capture_request_listener(void *listener,
+                                                   void (*handler)(void *))
+{
+    return vigs_qt5_register_capture_request_listener(listener, handler);
+}
+
+static void vigs_unregister_capture_request_listener(void *listener)
+{
+    return vigs_qt5_unregister_capture_request_listener(listener);
+}
+
+static void vigs_process_captured(bool captured, void *pixels,
+                                  uint32_t width, uint32_t height)
+{
+    return vigs_qt5_process_captured(captured, pixels, width, height);
+}
+
 static struct GraphicHwOps vigs_hw_ops =
 {
     .invalidate = vigs_hw_invalidate,
-    .gfx_update = vigs_hw_update
+    .gfx_update = vigs_hw_update,
+    /*
+     * Hack. use 'graphic_hw_text_update' to do displaying, but
+     * we have no choice, that's the only way to direct-to-window
+     * rendering from Qt5.
+     */
+    .text_update = vigs_hw_display,
 };
 
 static const MemoryRegionOps vigs_io_ops =
@@ -288,6 +336,13 @@ static struct vigs_display_ops vigs_dpy_ops =
     .fence_ack = vigs_fence_ack,
 };
 
+static struct vigs_capture_ops capture_ops =
+{
+    .register_listener = vigs_register_capture_request_listener,
+    .unregister_listener = vigs_unregister_capture_request_listener,
+    .process_captured = vigs_process_captured,
+};
+
 static int vigs_device_init(PCIDevice *dev)
 {
     VIGSState *s = DO_UPCAST(VIGSState, dev, dev);
@@ -421,12 +476,23 @@ static int vigs_device_init(PCIDevice *dev)
         goto fail;
     }
 
-    s->server = vigs_server_create(memory_region_get_ram_ptr(&s->vram_bar),
-                                   memory_region_get_ram_ptr(&s->ram_bar),
-                                   &vigs_dpy_ops,
-                                   s,
-                                   backend,
-                                   wqobj->wq);
+    if (vigs_qt5_onscreen_enabled()) {
+        s->server = vigs_onscreen_server_create(memory_region_get_ram_ptr(&s->vram_bar),
+                                                memory_region_get_ram_ptr(&s->ram_bar),
+                                                &vigs_dpy_ops,
+                                                &capture_ops,
+                                                s,
+                                                backend,
+                                                wqobj->wq);
+    } else {
+        s->server = vigs_offscreen_server_create(memory_region_get_ram_ptr(&s->vram_bar),
+                                                 memory_region_get_ram_ptr(&s->ram_bar),
+                                                 &vigs_dpy_ops,
+                                                 &capture_ops,
+                                                 s,
+                                                 backend,
+                                                 wqobj->wq);
+    }
 
     if (!s->server) {
         goto fail;
@@ -484,7 +550,7 @@ static void vigs_device_exit(PCIDevice *dev)
 {
     VIGSState *s = DO_UPCAST(VIGSState, dev, dev);
 
-    vigs_server_destroy(s->server);
+    s->server->destroy(s->server);
 
     qemu_bh_delete(s->fence_ack_bh);
 
index b27f99a..e0cb37e 100644 (file)
 #include "vigs_log.h"
 #include "vigs_utils.h"
 #include "vigs_ref.h"
+#include "vigs_qt5.h"
 #include "winsys_gl.h"
-#include "work_queue.h"
+#include "hw/pci/maru_brightness.h"
+#include <math.h>
 
-struct vigs_gl_surface;
-
-struct vigs_gl_backend_read_pixels_work_item
-{
-    struct work_queue_item base;
-
-    struct vigs_gl_backend *backend;
+extern uint32_t qt5_window_width;
+extern uint32_t qt5_window_height;
+extern int qt5_window_angle;
 
-    vigs_composite_start_cb start_cb;
-    vigs_composite_end_cb end_cb;
-    void *user_data;
-    uint32_t width;
-    uint32_t height;
-    uint32_t stride;
-    vigsp_surface_format format;
-};
+struct vigs_gl_surface;
 
 struct vigs_winsys_gl_surface
 {
@@ -203,6 +194,136 @@ static const char *g_fs_color_source_gl3 =
     "    FragColor = color;\n"
     "}\n";
 
+static const char *g_fs_dpy_source_gl2 =
+    "#version 120\n\n"
+    "uniform sampler2D tex;\n"
+    "uniform float brightness;\n"
+    "varying vec2 v_texCoord;\n"
+    "void main()\n"
+    "{\n"
+    "    gl_FragColor = texture2D(tex, v_texCoord) * brightness;\n"
+    "}\n";
+
+static const char *g_fs_dpy_source_gl3 =
+    "#version 140\n\n"
+    "uniform sampler2D tex;\n"
+    "uniform float brightness;\n"
+    "in vec2 v_texCoord;\n"
+    "out vec4 FragColor;\n"
+    "void main()\n"
+    "{\n"
+    "    FragColor = texture(tex, v_texCoord) * brightness;\n"
+    "}\n";
+
+static const char *g_fs_scale_source_gl2 =
+"#version 120\n\
+\n\
+uniform sampler2D tex;\n\
+uniform float brightness;\n\
+uniform vec2 texSize;\n\
+varying vec2 v_texCoord;\n\
+vec4 cubic(float x)\n\
+{\n\
+    float x2 = x * x;\n\
+    float x3 = x2 * x;\n\
+    vec4 w;\n\
+    w.x = -x3 + 3*x2 - 3*x + 1;\n\
+    w.y = 3*x3 - 6*x2 + 4;\n\
+    w.z = -3*x3 + 3*x2 + 3*x + 1;\n\
+    w.w = x3;\n\
+    return w / 6.f;\n\
+}\n\
+void main()\n\
+{\n\
+    vec2 texscale = vec2(1.0 / texSize.x, 1.0 / texSize.y);\n\
+    vec2 texcoord = vec2(v_texCoord.x * texSize.x, v_texCoord.y * texSize.y);\n\
+    float fx = fract(texcoord.x);\n\
+    float fy = fract(texcoord.y);\n\
+    texcoord.x -= fx;\n\
+    texcoord.y -= fy;\n\
+\n\
+    vec4 xcubic = cubic(fx);\n\
+    vec4 ycubic = cubic(fy);\n\
+\n\
+    vec4 c = vec4(texcoord.x - 0.5, texcoord.x + 1.5, texcoord.y -\n\
+0.5, texcoord.y + 1.5);\n\
+    vec4 s = vec4(xcubic.x + xcubic.y, xcubic.z + xcubic.w, ycubic.x +\n\
+ycubic.y, ycubic.z + ycubic.w);\n\
+    vec4 offset = c + vec4(xcubic.y, xcubic.w, ycubic.y, ycubic.w) /\n\
+s;\n\
+\n\
+    vec4 sample0 = texture2D(tex, vec2(offset.x, offset.z) *\n\
+texscale);\n\
+    vec4 sample1 = texture2D(tex, vec2(offset.y, offset.z) *\n\
+texscale);\n\
+    vec4 sample2 = texture2D(tex, vec2(offset.x, offset.w) *\n\
+texscale);\n\
+    vec4 sample3 = texture2D(tex, vec2(offset.y, offset.w) *\n\
+texscale);\n\
+\n\
+    float sx = s.x / (s.x + s.y);\n\
+    float sy = s.z / (s.z + s.w);\n\
+\n\
+    gl_FragColor = mix(\n\
+        mix(sample3, sample2, sx),\n\
+        mix(sample1, sample0, sx), sy) * brightness;\n\
+}";
+
+static const char *g_fs_scale_source_gl3 =
+"#version 140\n\
+\n\
+uniform sampler2D tex;\n\
+uniform float brightness;\n\
+uniform vec2 texSize;\n\
+in vec2 v_texCoord;\n\
+out vec4 FragColor;\n\
+vec4 cubic(float x)\n\
+{\n\
+    float x2 = x * x;\n\
+    float x3 = x2 * x;\n\
+    vec4 w;\n\
+    w.x = -x3 + 3*x2 - 3*x + 1;\n\
+    w.y = 3*x3 - 6*x2 + 4;\n\
+    w.z = -3*x3 + 3*x2 + 3*x + 1;\n\
+    w.w = x3;\n\
+    return w / 6.f;\n\
+}\n\
+void main()\n\
+{\n\
+    vec2 texscale = vec2(1.0 / texSize.x, 1.0 / texSize.y);\n\
+    vec2 texcoord = vec2(v_texCoord.x * texSize.x, v_texCoord.y * texSize.y);\n\
+    float fx = fract(texcoord.x);\n\
+    float fy = fract(texcoord.y);\n\
+    texcoord.x -= fx;\n\
+    texcoord.y -= fy;\n\
+\n\
+    vec4 xcubic = cubic(fx);\n\
+    vec4 ycubic = cubic(fy);\n\
+\n\
+    vec4 c = vec4(texcoord.x - 0.5, texcoord.x + 1.5, texcoord.y -\n\
+0.5, texcoord.y + 1.5);\n\
+    vec4 s = vec4(xcubic.x + xcubic.y, xcubic.z + xcubic.w, ycubic.x +\n\
+ycubic.y, ycubic.z + ycubic.w);\n\
+    vec4 offset = c + vec4(xcubic.y, xcubic.w, ycubic.y, ycubic.w) /\n\
+s;\n\
+\n\
+    vec4 sample0 = texture(tex, vec2(offset.x, offset.z) *\n\
+texscale);\n\
+    vec4 sample1 = texture(tex, vec2(offset.y, offset.z) *\n\
+texscale);\n\
+    vec4 sample2 = texture(tex, vec2(offset.x, offset.w) *\n\
+texscale);\n\
+    vec4 sample3 = texture(tex, vec2(offset.y, offset.w) *\n\
+texscale);\n\
+\n\
+    float sx = s.x / (s.x + s.y);\n\
+    float sy = s.z / (s.z + s.w);\n\
+\n\
+    FragColor = mix(\n\
+        mix(sample3, sample2, sx),\n\
+        mix(sample1, sample0, sx), sy) * brightness;\n\
+}";
+
 static const char *g_vs_nv21_source_gl2 =
     "#version 120\n\n"
     "attribute vec4 vertCoord;\n"
@@ -614,6 +735,102 @@ static void vigs_gl_draw_color_prog(struct vigs_gl_backend *backend,
     backend->DisableVertexAttribArray(backend->color_prog_vertCoord_loc);
 }
 
+static void vigs_gl_draw_dpy_tex_prog(struct vigs_gl_backend *backend,
+                                      uint32_t count)
+{
+    uint32_t size = count * 16;
+    void *ptr;
+
+    if (size > backend->dpy_vbo_size) {
+        backend->dpy_vbo_size = size;
+        backend->BufferData(GL_ARRAY_BUFFER,
+                            size,
+                            0,
+                            GL_STREAM_DRAW);
+    }
+
+    if (backend->MapBufferRange) {
+        ptr = backend->MapBufferRange(GL_ARRAY_BUFFER, 0, size,
+                                      GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
+
+        if (ptr) {
+            memcpy(ptr, vigs_vector_data(&backend->dpy_v1), size / 2);
+            memcpy(ptr + (size / 2), vigs_vector_data(&backend->dpy_v2), size / 2);
+
+            backend->UnmapBuffer(GL_ARRAY_BUFFER);
+        } else {
+            VIGS_LOG_ERROR("glMapBufferRange failed");
+        }
+    } else {
+        backend->Finish();
+        backend->BufferSubData(GL_ARRAY_BUFFER, 0,
+                               (size / 2), vigs_vector_data(&backend->dpy_v1));
+        backend->BufferSubData(GL_ARRAY_BUFFER, (size / 2),
+                               (size / 2), vigs_vector_data(&backend->dpy_v2));
+    }
+
+    backend->EnableVertexAttribArray(backend->dpy_tex_prog_vertCoord_loc);
+    backend->EnableVertexAttribArray(backend->dpy_tex_prog_texCoord_loc);
+
+    backend->VertexAttribPointer(backend->dpy_tex_prog_vertCoord_loc,
+                                 2, GL_FLOAT, GL_FALSE, 0, NULL);
+    backend->VertexAttribPointer(backend->dpy_tex_prog_texCoord_loc,
+                                 2, GL_FLOAT, GL_FALSE, 0, NULL + (size / 2));
+
+    backend->DrawArrays(GL_TRIANGLES, 0, count);
+
+    backend->DisableVertexAttribArray(backend->dpy_tex_prog_texCoord_loc);
+    backend->DisableVertexAttribArray(backend->dpy_tex_prog_vertCoord_loc);
+}
+
+static void vigs_gl_draw_dpy_scale_prog(struct vigs_gl_backend *backend,
+                                        uint32_t count)
+{
+    uint32_t size = count * 16;
+    void *ptr;
+
+    if (size > backend->dpy_vbo_size) {
+        backend->dpy_vbo_size = size;
+        backend->BufferData(GL_ARRAY_BUFFER,
+                            size,
+                            0,
+                            GL_STREAM_DRAW);
+    }
+
+    if (backend->MapBufferRange) {
+        ptr = backend->MapBufferRange(GL_ARRAY_BUFFER, 0, size,
+                                      GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
+
+        if (ptr) {
+            memcpy(ptr, vigs_vector_data(&backend->dpy_v1), size / 2);
+            memcpy(ptr + (size / 2), vigs_vector_data(&backend->dpy_v2), size / 2);
+
+            backend->UnmapBuffer(GL_ARRAY_BUFFER);
+        } else {
+            VIGS_LOG_ERROR("glMapBufferRange failed");
+        }
+    } else {
+        backend->Finish();
+        backend->BufferSubData(GL_ARRAY_BUFFER, 0,
+                               (size / 2), vigs_vector_data(&backend->dpy_v1));
+        backend->BufferSubData(GL_ARRAY_BUFFER, (size / 2),
+                               (size / 2), vigs_vector_data(&backend->dpy_v2));
+    }
+
+    backend->EnableVertexAttribArray(backend->dpy_scale_prog_vertCoord_loc);
+    backend->EnableVertexAttribArray(backend->dpy_scale_prog_texCoord_loc);
+
+    backend->VertexAttribPointer(backend->dpy_scale_prog_vertCoord_loc,
+                                 2, GL_FLOAT, GL_FALSE, 0, NULL);
+    backend->VertexAttribPointer(backend->dpy_scale_prog_texCoord_loc,
+                                 2, GL_FLOAT, GL_FALSE, 0, NULL + (size / 2));
+
+    backend->DrawArrays(GL_TRIANGLES, 0, count);
+
+    backend->DisableVertexAttribArray(backend->dpy_scale_prog_texCoord_loc);
+    backend->DisableVertexAttribArray(backend->dpy_scale_prog_vertCoord_loc);
+}
+
 static void vigs_gl_draw_nv21_prog(struct vigs_gl_backend *backend,
                                    uint32_t count)
 {
@@ -670,6 +887,28 @@ static void vigs_gl_create_ortho(GLfloat left, GLfloat right,
     ortho[15] = 1.0f;
 }
 
+static void vigs_gl_rotate_ortho(const GLfloat ortho[16],
+                                 GLfloat angle,
+                                 GLfloat res[16])
+{
+    GLfloat rot[4][4] = {
+        { cos(angle), sin(angle), 0, 0 },
+        { -sin(angle), cos(angle), 0, 0 },
+        { 0, 0, 1, 0 },
+        { 0, 0, 0, 1 }
+    };
+    int i, j, k;
+
+    for (i = 0; i < 4; ++i) {
+        for (j = 0; j < 4; ++j) {
+            res[i * 4 + j] = 0.0f;
+            for (k = 0; k < 4; ++k) {
+                res[i * 4 + j] += ortho[i * 4 + k] * rot[k][j];
+            }
+        }
+    }
+}
+
 static void vigs_gl_translate_color(vigsp_color color,
                                     vigsp_surface_format format,
                                     GLfloat res[4])
@@ -694,20 +933,20 @@ static void vigs_gl_translate_color(vigsp_color color,
 
 static bool vigs_winsys_gl_surface_create_texture(struct vigs_winsys_gl_surface *ws_sfc)
 {
-    GLuint cur_tex = 0;
+    GLuint cur_tex = 0, tmp_tex = 0;
 
     if (ws_sfc->tex) {
         return true;
     }
 
-    ws_sfc->backend->GenTextures(1, &ws_sfc->tex);
+    ws_sfc->backend->GenTextures(1, &tmp_tex);
 
-    if (!ws_sfc->tex) {
+    if (!tmp_tex) {
         return false;
     }
 
     ws_sfc->backend->GetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)&cur_tex);
-    ws_sfc->backend->BindTexture(GL_TEXTURE_2D, ws_sfc->tex);
+    ws_sfc->backend->BindTexture(GL_TEXTURE_2D, tmp_tex);
 
     /*
      * Workaround for problem in "Mesa DRI Intel(R) Ivybridge Desktop x86/MMX/SSE2, version 9.0.3":
@@ -723,6 +962,8 @@ static bool vigs_winsys_gl_surface_create_texture(struct vigs_winsys_gl_surface
                                 NULL);
     ws_sfc->backend->BindTexture(GL_TEXTURE_2D, cur_tex);
 
+    ws_sfc->tex = tmp_tex;
+
     return true;
 }
 
@@ -777,6 +1018,55 @@ static bool vigs_gl_surface_setup_framebuffer(struct vigs_gl_surface *gl_sfc,
     return true;
 }
 
+static bool vigs_gl_update_dpy_texture(struct vigs_gl_backend *gl_backend,
+                                       uint32_t width, uint32_t height,
+                                       GLfloat ortho[16])
+{
+    GLuint cur_tex = 0;
+
+    gl_backend->GetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)&cur_tex);
+
+    if (gl_backend->dpy_tex) {
+        if ((gl_backend->dpy_tex_width == width) &&
+            (gl_backend->dpy_tex_height == height)) {
+            return true;
+        }
+        gl_backend->BindTexture(GL_TEXTURE_2D, gl_backend->dpy_tex);
+    } else {
+        GLuint tmp_tex = 0;
+
+        gl_backend->GenTextures(1, &tmp_tex);
+
+        if (!tmp_tex) {
+            return false;
+        }
+
+        gl_backend->dpy_tex = tmp_tex;
+
+        gl_backend->BindTexture(GL_TEXTURE_2D, tmp_tex);
+
+        gl_backend->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+        gl_backend->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        gl_backend->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        gl_backend->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    }
+
+    gl_backend->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,
+                           width, height, 0,
+                           GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
+                           NULL);
+
+    gl_backend->BindTexture(GL_TEXTURE_2D, cur_tex);
+
+    memcpy(gl_backend->dpy_tex_ortho,
+           ortho,
+           sizeof(gl_backend->dpy_tex_ortho));
+    gl_backend->dpy_tex_width = width;
+    gl_backend->dpy_tex_height = height;
+
+    return true;
+}
+
 /*
  * @}
  */
@@ -1504,43 +1794,23 @@ static struct vigs_surface *vigs_gl_backend_create_surface(struct vigs_backend *
     return &gl_sfc->base;
 }
 
-static void vigs_gl_backend_read_pixels_work(struct work_queue_item *wq_item)
+static inline void
+vigs_gl_backend_sort_planes(const struct vigs_plane *planes,
+                            const struct vigs_plane **sorted_planes)
 {
-    struct vigs_gl_backend_read_pixels_work_item *item = (struct vigs_gl_backend_read_pixels_work_item*)wq_item;
-    struct vigs_gl_backend *backend = item->backend;
-    uint8_t *dst = NULL;
-
-    VIGS_LOG_TRACE("enter");
-
-    if (backend->read_pixels_make_current(backend, true)) {
-        uint8_t *src;
-
-        backend->BindBuffer(GL_PIXEL_PACK_BUFFER_ARB, backend->pbo);
-
-        src = backend->MapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
-
-        if (src) {
-            dst = item->start_cb(item->user_data,
-                                 item->width, item->height,
-                                 item->stride, item->format);
-
-            memcpy(dst, src, item->stride * item->height);
-
-            if (!backend->UnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB)) {
-                VIGS_LOG_CRITICAL("glUnmapBuffer failed");
-            }
-        } else {
-            VIGS_LOG_CRITICAL("glMapBuffer failed");
-        }
+    /*
+     * Sort planes, only 2 of them now, don't bother...
+     */
 
-        backend->BindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
+    assert(VIGS_MAX_PLANES == 2);
 
-        backend->read_pixels_make_current(backend, false);
+    if (planes[0].z_pos <= planes[1].z_pos) {
+        sorted_planes[0] = &planes[0];
+        sorted_planes[1] = &planes[1];
+    } else {
+        sorted_planes[0] = &planes[1];
+        sorted_planes[1] = &planes[0];
     }
-
-    item->end_cb(item->user_data, (dst != NULL), true);
-
-    g_free(item);
 }
 
 /*
@@ -1567,6 +1837,17 @@ static bool vigs_gl_backend_composite_planes(struct vigs_gl_backend *gl_backend,
             continue;
         }
 
+        VIGS_LOG_DEBUG("plane[%u]: %ux%u format = %d, z_pos = %d, hflip = %d,"
+                       " vflip = %d, rotation = %d ",
+                       i,
+                       plane->width,
+                       plane->height,
+                       plane->format,
+                       plane->z_pos,
+                       plane->hflip,
+                       plane->vflip,
+                       plane->rotation);
+
         src_w = plane->width;
         src_h = plane->height;
 
@@ -1787,11 +2068,10 @@ static bool vigs_gl_backend_composite_planes(struct vigs_gl_backend *gl_backend,
     return bottom;
 }
 
-static void vigs_gl_backend_composite(struct vigs_surface *surface,
+static bool vigs_gl_backend_composite(struct vigs_surface *surface,
                                       const struct vigs_plane *planes,
-                                      vigs_composite_start_cb start_cb,
-                                      vigs_composite_end_cb end_cb,
-                                      void *user_data)
+                                      bool planes_dirty,
+                                      uint8_t *display_data)
 {
     struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)surface->backend;
     struct vigs_gl_surface *gl_root_sfc = (struct vigs_gl_surface*)surface;
@@ -1801,13 +2081,18 @@ static void vigs_gl_backend_composite(struct vigs_surface *surface,
     GLfloat *vert_coords;
     GLfloat *tex_coords;
     const struct vigs_plane *sorted_planes[VIGS_MAX_PLANES];
-    uint32_t size = surface->stride * surface->ws_sfc->height;
-    struct vigs_gl_backend_read_pixels_work_item *item;
     bool bottom = true;
 
     VIGS_LOG_TRACE("enter");
 
-    if (!surface->ptr && !ws_root_sfc->tex) {
+    if (surface->ptr) {
+        if (!vigs_qt5_onscreen_enabled() && !planes_dirty) {
+            memcpy(display_data,
+                   surface->ptr,
+                   surface->stride * surface->ws_sfc->height);
+            return true;
+        }
+    } else if (!ws_root_sfc->tex) {
         VIGS_LOG_WARN("compositing garbage (root surface) ???");
     }
 
@@ -1815,7 +2100,10 @@ static void vigs_gl_backend_composite(struct vigs_surface *surface,
         goto out;
     }
 
-    if (!vigs_gl_surface_create_tmp_texture(gl_root_sfc)) {
+    if (!vigs_gl_update_dpy_texture(gl_backend,
+                                    surface->ws_sfc->width,
+                                    surface->ws_sfc->height,
+                                    gl_root_sfc->ortho)) {
         goto out;
     }
 
@@ -1852,19 +2140,7 @@ static void vigs_gl_backend_composite(struct vigs_surface *surface,
         goto out;
     }
 
-    /*
-     * Sort planes, only 2 of them now, don't bother...
-     */
-
-    assert(VIGS_MAX_PLANES == 2);
-
-    if (planes[0].z_pos <= planes[1].z_pos) {
-        sorted_planes[0] = &planes[0];
-        sorted_planes[1] = &planes[1];
-    } else {
-        sorted_planes[0] = &planes[1];
-        sorted_planes[1] = &planes[0];
-    }
+    vigs_gl_backend_sort_planes(planes, sorted_planes);
 
     vigs_vector_resize(&gl_backend->v1, 0);
     vigs_vector_resize(&gl_backend->v2, 0);
@@ -1896,7 +2172,7 @@ static void vigs_gl_backend_composite(struct vigs_surface *surface,
     }
 
     gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                                     GL_TEXTURE_2D, gl_root_sfc->tmp_tex, 0);
+                                     GL_TEXTURE_2D, gl_backend->dpy_tex, 0);
 
     bottom = vigs_gl_backend_composite_planes(gl_backend,
                                               sorted_planes,
@@ -1917,14 +2193,25 @@ static void vigs_gl_backend_composite(struct vigs_surface *surface,
     vert_coords[10] = 0;
     vert_coords[11] = 0;
 
-    tex_coords[6] = tex_coords[0] = 0;
-    tex_coords[7] =tex_coords[1] = 0;
-    tex_coords[2] = 1;
-    tex_coords[3] = 0;
-    tex_coords[8] = tex_coords[4] = 1;
-    tex_coords[9] = tex_coords[5] = 1;
-    tex_coords[10] = 0;
-    tex_coords[11] = 1;
+    if (!surface->ptr) {
+        tex_coords[6] = tex_coords[0] = 0;
+        tex_coords[7] = tex_coords[1] = 0;
+        tex_coords[2] = 1;
+        tex_coords[3] = 0;
+        tex_coords[8] = tex_coords[4] = 1;
+        tex_coords[9] = tex_coords[5] = 1;
+        tex_coords[10] = 0;
+        tex_coords[11] = 1;
+    } else {
+        tex_coords[6] = tex_coords[0] = 0;
+        tex_coords[7] = tex_coords[1] = 1;
+        tex_coords[2] = 1;
+        tex_coords[3] = 1;
+        tex_coords[8] = tex_coords[4] = 1;
+        tex_coords[9] = tex_coords[5] = 0;
+        tex_coords[10] = 0;
+        tex_coords[11] = 0;
+    }
 
     if (!bottom) {
         /*
@@ -1959,55 +2246,48 @@ static void vigs_gl_backend_composite(struct vigs_surface *surface,
                                      bottom,
                                      gl_root_sfc->ortho);
 
-    /*
-     * Now schedule asynchronous glReadPixels.
-     */
+out:
+    gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0);
 
-    gl_backend->BindBuffer(GL_PIXEL_PACK_BUFFER_ARB, gl_backend->pbo);
+    return false;
+}
 
-    if (size > gl_backend->pbo_size) {
-        gl_backend->pbo_size = size;
-        gl_backend->BufferData(GL_PIXEL_PACK_BUFFER_ARB,
-                               size,
-                               0,
-                               GL_STREAM_READ);
-    }
+static bool vigs_gl_backend_capture(struct vigs_surface *surface,
+                                    void *pixels)
+{
+    struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)surface->backend;
 
-    gl_backend->PixelStorei(GL_PACK_ALIGNMENT, 1);
-    gl_backend->ReadPixels(0, 0,
-                           surface->ws_sfc->width, surface->ws_sfc->height,
-                           ws_root_sfc->tex_format, ws_root_sfc->tex_type,
-                           NULL);
+    if (gl_backend->read_pixels_make_current(gl_backend, true)) {
 
-    gl_backend->BindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
+        if (!gl_backend->dpy_fb) {
+            gl_backend->GenFramebuffers(1, &gl_backend->dpy_fb);
 
-    /*
-     * That's a tricky one, if we don't do this then it's not
-     * guaranteed that PBO will actually be updated by the time
-     * 'vigs_gl_backend_read_pixels_work' runs and since
-     * 'vigs_gl_backend_read_pixels_work' uses another OpenGL context
-     * we might get old results.
-     */
-    gl_backend->Finish();
+            if (!gl_backend->dpy_fb) {
+                VIGS_LOG_ERROR("cannot create capture FB");
 
-    item = g_malloc(sizeof(*item));
+                gl_backend->read_pixels_make_current(gl_backend, false);
 
-    work_queue_item_init(&item->base, &vigs_gl_backend_read_pixels_work);
+                return false;
+            }
 
-    item->backend = gl_backend;
+        }
 
-    item->start_cb = start_cb;
-    item->end_cb = end_cb;
-    item->user_data = user_data;
-    item->width = surface->ws_sfc->width;
-    item->height = surface->ws_sfc->height;
-    item->stride = surface->stride;
-    item->format = surface->format;
+        gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_backend->dpy_fb);
+        gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                         GL_TEXTURE_2D, gl_backend->dpy_tex, 0);
 
-    work_queue_add_item(gl_backend->read_pixels_queue, &item->base);
+        gl_backend->ReadPixels(0, 0, gl_backend->dpy_tex_width,
+                               gl_backend->dpy_tex_height,
+                               GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
+                               pixels);
+        gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0);
 
-out:
-    gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0);
+        gl_backend->read_pixels_make_current(gl_backend, false);
+
+        return true;
+    }
+
+    return false;
 }
 
 static void vigs_gl_backend_batch_end(struct vigs_backend *backend)
@@ -2018,6 +2298,142 @@ static void vigs_gl_backend_batch_end(struct vigs_backend *backend)
     gl_backend->make_current(gl_backend, false);
 }
 
+static bool vigs_gl_backend_display(struct vigs_backend *backend,
+                                    uint8_t *display_data)
+{
+    struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)backend;
+
+    VIGS_LOG_TRACE("enter");
+
+    if (vigs_qt5_onscreen_enabled()) {
+        GLfloat *vert_coords;
+        GLfloat *tex_coords;
+        bool scale;
+        GLfloat rotated_ortho[16];
+        GLfloat *ortho;
+        float brightness = (float)(255 - brightness_tbl[brightness_level]) / 255.0f;
+
+        if (display_off) {
+            brightness = 0.0f;
+        }
+
+        if (!gl_backend->is_gl_2 && !gl_backend->dpy_vao) {
+            gl_backend->GenVertexArrays(1, &gl_backend->dpy_vao);
+
+            if (!gl_backend->dpy_vao) {
+                VIGS_LOG_CRITICAL("cannot create VAO");
+                exit(1);
+            }
+
+            gl_backend->BindVertexArray(gl_backend->dpy_vao);
+        }
+
+        gl_backend->BindBuffer(GL_ARRAY_BUFFER, gl_backend->dpy_vbo);
+        gl_backend->Disable(GL_DEPTH_TEST);
+        gl_backend->Disable(GL_BLEND);
+
+        if (qt5_window_angle == 0) {
+            ortho = gl_backend->dpy_tex_ortho;
+        } else {
+            vigs_gl_rotate_ortho(gl_backend->dpy_tex_ortho,
+                                 (float)(360.0f - qt5_window_angle) * M_PI / 180.0f,
+                                 rotated_ortho);
+            ortho = rotated_ortho;
+        }
+
+        scale = (qt5_window_width != gl_backend->dpy_tex_width) ||
+                (qt5_window_height != gl_backend->dpy_tex_height);
+
+        gl_backend->Viewport(0, 0,
+                             qt5_window_width,
+                             qt5_window_height);
+
+        if (scale) {
+            float texSize[2];
+
+            gl_backend->UseProgram(gl_backend->dpy_scale_prog_id);
+            gl_backend->UniformMatrix4fv(gl_backend->dpy_scale_prog_proj_loc, 1, GL_FALSE,
+                                         ortho);
+
+            texSize[0] = gl_backend->dpy_tex_width;
+            texSize[1] = gl_backend->dpy_tex_height;
+
+            gl_backend->Uniform2fv(gl_backend->dpy_scale_prog_texSize_loc, 1, texSize);
+            gl_backend->Uniform1f(gl_backend->dpy_scale_prog_brightness_loc, brightness);
+        } else {
+            gl_backend->UseProgram(gl_backend->dpy_tex_prog_id);
+            gl_backend->UniformMatrix4fv(gl_backend->dpy_tex_prog_proj_loc, 1, GL_FALSE,
+                                         ortho);
+            gl_backend->Uniform1f(gl_backend->dpy_tex_prog_brightness_loc, brightness);
+        }
+
+        gl_backend->BindTexture(GL_TEXTURE_2D, gl_backend->dpy_tex);
+
+        vigs_vector_resize(&gl_backend->dpy_v1, 0);
+        vigs_vector_resize(&gl_backend->dpy_v2, 0);
+
+        vert_coords = vigs_vector_append(&gl_backend->dpy_v1,
+                                         (12 * sizeof(GLfloat)));
+        tex_coords = vigs_vector_append(&gl_backend->dpy_v2,
+                                        (12 * sizeof(GLfloat)));
+
+        vert_coords[6] = vert_coords[0] = 0;
+        vert_coords[7] = vert_coords[1] = gl_backend->dpy_tex_height;
+        vert_coords[2] = gl_backend->dpy_tex_width;
+        vert_coords[3] = gl_backend->dpy_tex_height;
+        vert_coords[8] = vert_coords[4] = gl_backend->dpy_tex_width;
+        vert_coords[9] = vert_coords[5] = 0;
+        vert_coords[10] = 0;
+        vert_coords[11] = 0;
+
+        tex_coords[6] = tex_coords[0] = 0;
+        tex_coords[7] = tex_coords[1] = 0;
+        tex_coords[2] = 1;
+        tex_coords[3] = 0;
+        tex_coords[8] = tex_coords[4] = 1;
+        tex_coords[9] = tex_coords[5] = 1;
+        tex_coords[10] = 0;
+        tex_coords[11] = 1;
+
+        if (scale) {
+            vigs_gl_draw_dpy_scale_prog(gl_backend, 6);
+        } else {
+            vigs_gl_draw_dpy_tex_prog(gl_backend, 6);
+        }
+
+        gl_backend->Finish();
+
+        return true;
+    } else {
+        if (gl_backend->read_pixels_make_current(gl_backend, true)) {
+            if (!gl_backend->dpy_fb) {
+                gl_backend->GenFramebuffers(1, &gl_backend->dpy_fb);
+
+                if (!gl_backend->dpy_fb) {
+                    VIGS_LOG_CRITICAL("cannot create FB");
+                    exit(1);
+                }
+
+                gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_backend->dpy_fb);
+            }
+
+            gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                             GL_TEXTURE_2D, gl_backend->dpy_tex, 0);
+
+            gl_backend->ReadPixels(0, 0, gl_backend->dpy_tex_width,
+                                   gl_backend->dpy_tex_height,
+                                   GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
+                                   display_data);
+
+            gl_backend->read_pixels_make_current(gl_backend, false);
+
+            return true;
+        } else {
+            return false;
+        }
+    }
+}
+
 bool vigs_gl_backend_init(struct vigs_gl_backend *gl_backend)
 {
     if (!gl_backend->make_current(gl_backend, true)) {
@@ -2177,9 +2593,10 @@ bool vigs_gl_backend_init(struct vigs_gl_backend *gl_backend)
     gl_backend->yuv420_prog_vtex_loc = gl_backend->GetUniformLocation(gl_backend->yuv420_prog_id, "vtex");
 
     gl_backend->GenBuffers(1, &gl_backend->vbo);
+    gl_backend->GenBuffers(1, &gl_backend->dpy_vbo);
 
-    if (!gl_backend->vbo) {
-        VIGS_LOG_CRITICAL("cannot create VBO");
+    if (!gl_backend->vbo || !gl_backend->dpy_vbo) {
+        VIGS_LOG_CRITICAL("cannot create VBOs");
         goto fail;
     }
 
@@ -2197,27 +2614,81 @@ bool vigs_gl_backend_init(struct vigs_gl_backend *gl_backend)
     gl_backend->UseProgram(gl_backend->tex_prog_id);
     gl_backend->cur_prog_id = gl_backend->tex_prog_id;
 
-    gl_backend->GenBuffers(1, &gl_backend->pbo);
+    gl_backend->dpy_tex_prog_vs_id = vigs_gl_create_shader(gl_backend,
+        (gl_backend->is_gl_2 ? g_vs_tex_source_gl2 : g_vs_tex_source_gl3),
+        GL_VERTEX_SHADER);
 
-    if (!gl_backend->pbo) {
-        VIGS_LOG_CRITICAL("cannot create read_pixels PBO");
+    if (!gl_backend->dpy_tex_prog_vs_id) {
         goto fail;
     }
 
+    gl_backend->dpy_tex_prog_fs_id = vigs_gl_create_shader(gl_backend,
+        (gl_backend->is_gl_2 ? g_fs_dpy_source_gl2 : g_fs_dpy_source_gl3),
+        GL_FRAGMENT_SHADER);
+
+    if (!gl_backend->dpy_tex_prog_fs_id) {
+        goto fail;
+    }
+
+    gl_backend->dpy_tex_prog_id = vigs_gl_create_program(gl_backend,
+                                                         gl_backend->dpy_tex_prog_vs_id,
+                                                         gl_backend->dpy_tex_prog_fs_id);
+
+    if (!gl_backend->dpy_tex_prog_id) {
+        goto fail;
+    }
+
+    gl_backend->dpy_tex_prog_proj_loc = gl_backend->GetUniformLocation(gl_backend->dpy_tex_prog_id, "proj");
+    gl_backend->dpy_tex_prog_vertCoord_loc = gl_backend->GetAttribLocation(gl_backend->dpy_tex_prog_id, "vertCoord");
+    gl_backend->dpy_tex_prog_texCoord_loc = gl_backend->GetAttribLocation(gl_backend->dpy_tex_prog_id, "texCoord");
+    gl_backend->dpy_tex_prog_brightness_loc = gl_backend->GetUniformLocation(gl_backend->dpy_tex_prog_id, "brightness");
+
+    gl_backend->dpy_scale_prog_vs_id = vigs_gl_create_shader(gl_backend,
+        (gl_backend->is_gl_2 ? g_vs_tex_source_gl2 : g_vs_tex_source_gl3),
+        GL_VERTEX_SHADER);
+
+    if (!gl_backend->dpy_scale_prog_vs_id) {
+        goto fail;
+    }
+
+    gl_backend->dpy_scale_prog_fs_id = vigs_gl_create_shader(gl_backend,
+        (gl_backend->is_gl_2 ? g_fs_scale_source_gl2 : g_fs_scale_source_gl3),
+        GL_FRAGMENT_SHADER);
+
+    if (!gl_backend->dpy_scale_prog_fs_id) {
+        goto fail;
+    }
+
+    gl_backend->dpy_scale_prog_id = vigs_gl_create_program(gl_backend,
+                                                           gl_backend->dpy_scale_prog_vs_id,
+                                                           gl_backend->dpy_scale_prog_fs_id);
+
+    if (!gl_backend->dpy_scale_prog_id) {
+        goto fail;
+    }
+
+    gl_backend->dpy_scale_prog_proj_loc = gl_backend->GetUniformLocation(gl_backend->dpy_scale_prog_id, "proj");
+    gl_backend->dpy_scale_prog_vertCoord_loc = gl_backend->GetAttribLocation(gl_backend->dpy_scale_prog_id, "vertCoord");
+    gl_backend->dpy_scale_prog_texCoord_loc = gl_backend->GetAttribLocation(gl_backend->dpy_scale_prog_id, "texCoord");
+    gl_backend->dpy_scale_prog_texSize_loc = gl_backend->GetUniformLocation(gl_backend->dpy_scale_prog_id, "texSize");
+    gl_backend->dpy_scale_prog_brightness_loc = gl_backend->GetUniformLocation(gl_backend->dpy_scale_prog_id, "brightness");
+
     gl_backend->Disable(GL_DEPTH_TEST);
     gl_backend->Disable(GL_BLEND);
 
     gl_backend->base.batch_start = &vigs_gl_backend_batch_start;
     gl_backend->base.create_surface = &vigs_gl_backend_create_surface;
     gl_backend->base.composite = &vigs_gl_backend_composite;
+    gl_backend->base.capture = &vigs_gl_backend_capture;
     gl_backend->base.batch_end = &vigs_gl_backend_batch_end;
+    gl_backend->base.display = &vigs_gl_backend_display;
 
     gl_backend->make_current(gl_backend, false);
 
     vigs_vector_init(&gl_backend->v1, 0);
     vigs_vector_init(&gl_backend->v2, 0);
-
-    gl_backend->read_pixels_queue = work_queue_create("vigs_work_queue");
+    vigs_vector_init(&gl_backend->dpy_v1, 0);
+    vigs_vector_init(&gl_backend->dpy_v2, 0);
 
     return true;
 
@@ -2229,10 +2700,25 @@ fail:
 
 void vigs_gl_backend_cleanup(struct vigs_gl_backend *gl_backend)
 {
-    work_queue_destroy(gl_backend->read_pixels_queue);
-
     if (gl_backend->make_current(gl_backend, true)) {
-        gl_backend->DeleteBuffers(1, &gl_backend->pbo);
+        if (gl_backend->dpy_tex) {
+            gl_backend->DeleteTextures(1, &gl_backend->dpy_tex);
+        }
+        gl_backend->DeleteBuffers(1, &gl_backend->dpy_vbo);
+        gl_backend->DetachShader(gl_backend->dpy_scale_prog_id,
+                                 gl_backend->dpy_scale_prog_vs_id);
+        gl_backend->DetachShader(gl_backend->dpy_scale_prog_id,
+                                 gl_backend->dpy_scale_prog_fs_id);
+        gl_backend->DeleteShader(gl_backend->dpy_scale_prog_vs_id);
+        gl_backend->DeleteShader(gl_backend->dpy_scale_prog_fs_id);
+        gl_backend->DeleteProgram(gl_backend->dpy_scale_prog_id);
+        gl_backend->DetachShader(gl_backend->dpy_tex_prog_id,
+                                 gl_backend->dpy_tex_prog_vs_id);
+        gl_backend->DetachShader(gl_backend->dpy_tex_prog_id,
+                                 gl_backend->dpy_tex_prog_fs_id);
+        gl_backend->DeleteShader(gl_backend->dpy_tex_prog_vs_id);
+        gl_backend->DeleteShader(gl_backend->dpy_tex_prog_fs_id);
+        gl_backend->DeleteProgram(gl_backend->dpy_tex_prog_id);
         gl_backend->DeleteBuffers(1, &gl_backend->vbo);
         gl_backend->DetachShader(gl_backend->yuv420_prog_id,
                                  gl_backend->yuv420_prog_vs_id);
@@ -2273,6 +2759,8 @@ void vigs_gl_backend_cleanup(struct vigs_gl_backend *gl_backend)
         gl_backend->make_current(gl_backend, false);
     }
 
+    vigs_vector_cleanup(&gl_backend->dpy_v2);
+    vigs_vector_cleanup(&gl_backend->dpy_v1);
     vigs_vector_cleanup(&gl_backend->v2);
     vigs_vector_cleanup(&gl_backend->v1);
 }
index bfa4110..584ec04 100644 (file)
@@ -37,7 +37,6 @@
 #include <GL/glext.h>
 #include "winsys_gl.h"
 
-struct work_queue;
 struct vigs_gl_pool;
 
 struct vigs_gl_backend
@@ -121,6 +120,8 @@ struct vigs_gl_backend
     void (GLAPIENTRY* VertexAttribPointer)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer);
     void (GLAPIENTRY* Uniform4fv)(GLint location, GLsizei count, const GLfloat* value);
     void (GLAPIENTRY* UniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+    void (GLAPIENTRY* Uniform2fv)(GLint location, GLsizei count, const GLfloat* value);
+    void (GLAPIENTRY* Uniform1f)(GLint location, GLfloat v0);
     void (GLAPIENTRY* Uniform1i)(GLint location, GLint v0);
     void (GLAPIENTRY* Uniform2f)(GLint location, GLfloat v0, GLfloat v1);
     void (GLAPIENTRY* ActiveTexture)(GLenum texture);
@@ -163,7 +164,8 @@ struct vigs_gl_backend
      */
 
     /*
-     * Other.
+     * Rendering thread related.
+     * @{
      */
 
     GLuint vao;
@@ -213,10 +215,46 @@ struct vigs_gl_backend
 
     GLuint cur_prog_id;
 
-    struct work_queue *read_pixels_queue;
+    /*
+     * @}
+     * Display thread related.
+     * @{
+     */
 
-    GLuint pbo;
-    uint32_t pbo_size;
+    struct vigs_vector dpy_v1;
+    struct vigs_vector dpy_v2;
+
+    GLuint dpy_vao;
+
+    GLuint dpy_tex_prog_vs_id;
+    GLuint dpy_tex_prog_fs_id;
+    GLuint dpy_tex_prog_id;
+    GLint dpy_tex_prog_proj_loc;
+    GLint dpy_tex_prog_vertCoord_loc;
+    GLint dpy_tex_prog_texCoord_loc;
+    GLint dpy_tex_prog_brightness_loc;
+
+    GLuint dpy_scale_prog_vs_id;
+    GLuint dpy_scale_prog_fs_id;
+    GLuint dpy_scale_prog_id;
+    GLint dpy_scale_prog_proj_loc;
+    GLint dpy_scale_prog_vertCoord_loc;
+    GLint dpy_scale_prog_texCoord_loc;
+    GLint dpy_scale_prog_texSize_loc;
+    GLint dpy_scale_prog_brightness_loc;
+
+    GLuint dpy_vbo;
+    uint32_t dpy_vbo_size;
+
+    GLuint dpy_tex;
+    GLuint dpy_fb;
+    GLfloat dpy_tex_ortho[16];
+    uint32_t dpy_tex_width;
+    uint32_t dpy_tex_height;
+
+    /*
+     * @}
+     */
 };
 
 bool vigs_gl_backend_init(struct vigs_gl_backend *gl_backend);
index e21a7a1..db07be6 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "vigs_gl_backend.h"
 #include "vigs_log.h"
+#include "vigs_qt5.h"
 #include <OpenGL/OpenGL.h>
 #include <dlfcn.h>
 
@@ -61,7 +62,6 @@ static const CGLPixelFormatAttribute pixel_format_legacy_attrs[] =
     kCGLPFAAlphaSize, 8,
     kCGLPFADepthSize, 24,
     kCGLPFAStencilSize, 8,
-    kCGLPFANoRecovery,
     kCGLPFAPBuffer,
     0
 };
@@ -74,7 +74,6 @@ static const CGLPixelFormatAttribute pixel_format_3_2_core_attrs[] =
     kCGLPFAAlphaSize, 8,
     kCGLPFADepthSize, 24,
     kCGLPFAStencilSize, 8,
-    kCGLPFANoRecovery,
     kCGLPFAOpenGLProfile, kCGLOGLPVersion_3_2_Core,
     0
 };
@@ -257,6 +256,7 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     CGLError error;
     CGLPixelFormatObj pixel_format;
     int n;
+    CGLContextObj qt5_ctx = NULL;
 
     gl_backend_cgl = g_malloc0(sizeof(*gl_backend_cgl));
 
@@ -321,6 +321,8 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     VIGS_GL_GET_PROC(VertexAttribPointer, glVertexAttribPointer);
     VIGS_GL_GET_PROC(Uniform4fv, glUniform4fv);
     VIGS_GL_GET_PROC(UniformMatrix4fv, glUniformMatrix4fv);
+    VIGS_GL_GET_PROC(Uniform2fv, glUniform2fv);
+    VIGS_GL_GET_PROC(Uniform1f, glUniform1f);
     VIGS_GL_GET_PROC(Uniform1i, glUniform1i);
     VIGS_GL_GET_PROC(Uniform2f, glUniform2f);
     VIGS_GL_GET_PROC(ActiveTexture, glActiveTexture);
@@ -375,9 +377,16 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
         goto fail2;
     }
 
+    if (vigs_qt5_onscreen_enabled()) {
+        qt5_ctx = (CGLContextObj)vigs_qt5_gl_context_create(gl_backend_cgl->base.is_gl_2);
+        if (!qt5_ctx) {
+            goto fail2;
+        }
+    }
+
     if (!vigs_gl_backend_cgl_create_context(gl_backend_cgl,
                                             pixel_format,
-                                            NULL,
+                                            qt5_ctx,
                                             &gl_backend_cgl->context)) {
         goto fail3;
     }
index 8faa13b..7b1fe13 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "vigs_gl_backend.h"
 #include "vigs_log.h"
+#include "vigs_qt5.h"
 #include <GL/glx.h>
 #include <dlfcn.h>
 
@@ -85,6 +86,7 @@ struct vigs_gl_backend_glx
     PFNGLXMAKECONTEXTCURRENTPROC glXMakeContextCurrent;
     PFNGLXGETCURRENTCONTEXTPROC glXGetCurrentContext;
     PFNGLXCREATENEWCONTEXTPROC glXCreateNewContext;
+    PFNGLXQUERYCONTEXTPROC glXQueryContext;
 
     /* GLX_ARB_create_context */
     PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB;
@@ -96,6 +98,16 @@ struct vigs_gl_backend_glx
     GLXContext read_pixels_ctx;
 };
 
+static const char *gl_3_2_check_funcs[] =
+{
+    "glGenTransformFeedbacks",
+    "glBindTransformFeedback",
+    "glPauseTransformFeedback",
+    "glResumeTransformFeedback",
+    "glDeleteTransformFeedbacks",
+    "glVertexAttribDivisor"
+};
+
 static bool vigs_gl_backend_glx_check_gl_version(struct vigs_gl_backend_glx *gl_backend_glx,
                                                  bool *is_gl_2)
 {
@@ -126,6 +138,7 @@ static bool vigs_gl_backend_glx_check_gl_version(struct vigs_gl_backend_glx *gl_
     int n = 0;
     GLXFBConfig *configs = NULL;
     GLXContext ctx = NULL;
+    unsigned int i;
 
     tmp = getenv("GL_VERSION");
 
@@ -178,6 +191,19 @@ static bool vigs_gl_backend_glx_check_gl_version(struct vigs_gl_backend_glx *gl_
         VIGS_LOG_INFO("glXCreateContextAttribsARB failed, using OpenGL 2.1");
     }
 
+    if (*is_gl_2 == false) {
+        for (i = 0;
+             i < sizeof(gl_3_2_check_funcs)/sizeof(gl_3_2_check_funcs[0]);
+             ++i) {
+            if (!gl_backend_glx->glXGetProcAddress((const GLubyte *)
+                                                   gl_3_2_check_funcs[i])) {
+                VIGS_LOG_INFO("Failed to find function \"%s\", "
+                              "using OpenGL 2.1", gl_3_2_check_funcs[i]);
+                *is_gl_2 = true;
+            }
+        }
+    }
+
 out:
     if (ctx) {
         gl_backend_glx->glXMakeContextCurrent(gl_backend_glx->dpy, 0, 0, NULL);
@@ -192,28 +218,50 @@ out:
 
 static GLXFBConfig vigs_gl_backend_glx_get_config(struct vigs_gl_backend_glx *gl_backend_glx)
 {
-    int config_attribs[] =
-    {
-        GLX_DOUBLEBUFFER, True,
-        GLX_RED_SIZE, 8,
-        GLX_GREEN_SIZE, 8,
-        GLX_BLUE_SIZE, 8,
-        GLX_ALPHA_SIZE, 8,
-        GLX_BUFFER_SIZE, 32,
-        GLX_DEPTH_SIZE, 24,
-        GLX_STENCIL_SIZE, 8,
-        GLX_RENDER_TYPE, GLX_RGBA_BIT,
-        GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
-        None
-    };
     int n = 0;
     GLXFBConfig *glx_configs;
     GLXFBConfig best_config = NULL;
 
-    glx_configs = gl_backend_glx->glXChooseFBConfig(gl_backend_glx->dpy,
-                                                    DefaultScreen(gl_backend_glx->dpy),
-                                                    config_attribs,
-                                                    &n);
+    if (vigs_qt5_onscreen_enabled()) {
+        int config_attribs[] =
+        {
+            GLX_FBCONFIG_ID, 0,
+            None
+        };
+
+        if (gl_backend_glx->glXQueryContext(gl_backend_glx->dpy,
+                                            gl_backend_glx->ctx,
+                                            GLX_FBCONFIG_ID,
+                                            &config_attribs[1]) != Success) {
+            VIGS_LOG_CRITICAL("Unable to get context's GLX config");
+            return NULL;
+        }
+
+        glx_configs = gl_backend_glx->glXChooseFBConfig(gl_backend_glx->dpy,
+                                                        DefaultScreen(gl_backend_glx->dpy),
+                                                        config_attribs,
+                                                        &n);
+    } else {
+        int config_attribs[] =
+        {
+            GLX_DOUBLEBUFFER, True,
+            GLX_RED_SIZE, 8,
+            GLX_GREEN_SIZE, 8,
+            GLX_BLUE_SIZE, 8,
+            GLX_ALPHA_SIZE, 8,
+            GLX_BUFFER_SIZE, 32,
+            GLX_DEPTH_SIZE, 24,
+            GLX_STENCIL_SIZE, 8,
+            GLX_RENDER_TYPE, GLX_RGBA_BIT,
+            GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
+            None
+        };
+
+        glx_configs = gl_backend_glx->glXChooseFBConfig(gl_backend_glx->dpy,
+                                                        DefaultScreen(gl_backend_glx->dpy),
+                                                        config_attribs,
+                                                        &n);
+    }
 
     if (n > 0) {
         int tmp;
@@ -357,14 +405,18 @@ static void vigs_gl_backend_glx_destroy(struct vigs_backend *backend)
 
     vigs_gl_backend_cleanup(&gl_backend_glx->base);
 
-    gl_backend_glx->glXDestroyContext(gl_backend_glx->dpy,
-                                      gl_backend_glx->read_pixels_ctx);
-
-    gl_backend_glx->glXDestroyContext(gl_backend_glx->dpy,
-                                      gl_backend_glx->ctx);
-
-    gl_backend_glx->glXDestroyPbuffer(gl_backend_glx->dpy,
-                                      gl_backend_glx->read_pixels_sfc);
+    if (gl_backend_glx->read_pixels_sfc) {
+        gl_backend_glx->glXDestroyPbuffer(gl_backend_glx->dpy,
+                                          gl_backend_glx->read_pixels_sfc);
+    }
+    if (!vigs_qt5_onscreen_enabled() && gl_backend_glx->ctx) {
+        gl_backend_glx->glXDestroyContext(gl_backend_glx->dpy,
+                                          gl_backend_glx->ctx);
+    }
+    if (gl_backend_glx->read_pixels_ctx) {
+        gl_backend_glx->glXDestroyContext(gl_backend_glx->dpy,
+                                          gl_backend_glx->read_pixels_ctx);
+    }
 
     gl_backend_glx->glXDestroyPbuffer(gl_backend_glx->dpy,
                                       gl_backend_glx->sfc);
@@ -418,6 +470,7 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     VIGS_GLX_GET_PROC(PFNGLXGETCURRENTCONTEXTPROC, glXGetCurrentContext);
     VIGS_GLX_GET_PROC(PFNGLXCREATENEWCONTEXTPROC, glXCreateNewContext);
     VIGS_GLX_GET_PROC(PFNGLXCREATECONTEXTATTRIBSARBPROC, glXCreateContextAttribsARB);
+    VIGS_GLX_GET_PROC(PFNGLXQUERYCONTEXTPROC, glXQueryContext);
 
     VIGS_GL_GET_PROC(GenTextures, glGenTextures);
     VIGS_GL_GET_PROC(DeleteTextures, glDeleteTextures);
@@ -470,6 +523,8 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     VIGS_GL_GET_PROC(VertexAttribPointer, glVertexAttribPointer);
     VIGS_GL_GET_PROC(Uniform4fv, glUniform4fv);
     VIGS_GL_GET_PROC(UniformMatrix4fv, glUniformMatrix4fv);
+    VIGS_GL_GET_PROC(Uniform2fv, glUniform2fv);
+    VIGS_GL_GET_PROC(Uniform1f, glUniform1f);
     VIGS_GL_GET_PROC(Uniform1i, glUniform1i);
     VIGS_GL_GET_PROC(Uniform2f, glUniform2f);
     VIGS_GL_GET_PROC(ActiveTexture, glActiveTexture);
@@ -508,36 +563,64 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
         VIGS_GL_GET_PROC(DeleteVertexArrays, glDeleteVertexArrays);
     }
 
-    config = vigs_gl_backend_glx_get_config(gl_backend_glx);
+    if (vigs_qt5_onscreen_enabled()) {
+        gl_backend_glx->ctx =
+            (GLXContext)vigs_qt5_gl_context_create(gl_backend_glx->base.is_gl_2);
 
-    if (!config) {
-        goto fail2;
-    }
+        if (!gl_backend_glx->ctx) {
+            goto fail2;
+        }
 
-    if (!vigs_gl_backend_glx_create_surface(gl_backend_glx,
-                                            config,
-                                            &gl_backend_glx->sfc)) {
-        goto fail2;
-    }
+        config = vigs_gl_backend_glx_get_config(gl_backend_glx);
 
-    if (!vigs_gl_backend_glx_create_surface(gl_backend_glx,
-                                            config,
-                                            &gl_backend_glx->read_pixels_sfc)) {
-        goto fail3;
-    }
+        if (!config) {
+            goto fail2;
+        }
 
-    if (!vigs_gl_backend_glx_create_context(gl_backend_glx,
-                                            config,
-                                            NULL,
-                                            &gl_backend_glx->ctx)) {
-        goto fail4;
+        if (!vigs_gl_backend_glx_create_surface(gl_backend_glx,
+                                                config,
+                                                &gl_backend_glx->read_pixels_sfc)) {
+            goto fail2;
+        }
+
+        if (!vigs_gl_backend_glx_create_context(gl_backend_glx,
+                                                config,
+                                                gl_backend_glx->ctx,
+                                                &gl_backend_glx->read_pixels_ctx)) {
+            goto fail2;
+        }
+    } else {
+        config = vigs_gl_backend_glx_get_config(gl_backend_glx);
+
+        if (!config) {
+            goto fail2;
+        }
+
+        if (!vigs_gl_backend_glx_create_surface(gl_backend_glx,
+                                                config,
+                                                &gl_backend_glx->read_pixels_sfc)) {
+            goto fail2;
+        }
+
+        if (!vigs_gl_backend_glx_create_context(gl_backend_glx,
+                                                config,
+                                                NULL,
+                                                &gl_backend_glx->ctx)) {
+            goto fail2;
+        }
+
+        if (!vigs_gl_backend_glx_create_context(gl_backend_glx,
+                                                config,
+                                                gl_backend_glx->ctx,
+                                                &gl_backend_glx->read_pixels_ctx)) {
+            goto fail2;
+        }
     }
 
-    if (!vigs_gl_backend_glx_create_context(gl_backend_glx,
+    if (!vigs_gl_backend_glx_create_surface(gl_backend_glx,
                                             config,
-                                            gl_backend_glx->ctx,
-                                            &gl_backend_glx->read_pixels_ctx)) {
-        goto fail5;
+                                            &gl_backend_glx->sfc)) {
+        goto fail2;
     }
 
     gl_backend_glx->base.base.destroy = &vigs_gl_backend_glx_destroy;
@@ -547,26 +630,29 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     gl_backend_glx->base.ws_info.context = gl_backend_glx->ctx;
 
     if (!vigs_gl_backend_init(&gl_backend_glx->base)) {
-        goto fail6;
+        goto fail3;
     }
 
     VIGS_LOG_DEBUG("created");
 
     return &gl_backend_glx->base.base;
 
-fail6:
-    gl_backend_glx->glXDestroyContext(gl_backend_glx->dpy,
-                                      gl_backend_glx->read_pixels_ctx);
-fail5:
-    gl_backend_glx->glXDestroyContext(gl_backend_glx->dpy,
-                                      gl_backend_glx->ctx);
-fail4:
-    gl_backend_glx->glXDestroyPbuffer(gl_backend_glx->dpy,
-                                      gl_backend_glx->read_pixels_sfc);
 fail3:
     gl_backend_glx->glXDestroyPbuffer(gl_backend_glx->dpy,
                                       gl_backend_glx->sfc);
 fail2:
+    if (gl_backend_glx->read_pixels_sfc) {
+        gl_backend_glx->glXDestroyPbuffer(gl_backend_glx->dpy,
+                                          gl_backend_glx->read_pixels_sfc);
+    }
+    if (!vigs_qt5_onscreen_enabled() && gl_backend_glx->ctx) {
+        gl_backend_glx->glXDestroyContext(gl_backend_glx->dpy,
+                                          gl_backend_glx->ctx);
+    }
+    if (gl_backend_glx->read_pixels_ctx) {
+        gl_backend_glx->glXDestroyContext(gl_backend_glx->dpy,
+                                          gl_backend_glx->read_pixels_ctx);
+    }
     dlclose(gl_backend_glx->handle);
 fail1:
     vigs_backend_cleanup(&gl_backend_glx->base.base);
index 219eb4d..1d8add5 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "vigs_gl_backend.h"
 #include "vigs_log.h"
+#include "vigs_qt5.h"
 #include <windows.h>
 #include <wingdi.h>
 #include <GL/gl.h>
@@ -122,6 +123,16 @@ struct vigs_gl_backend_wgl
     HGLRC read_pixels_ctx;
 };
 
+static const char *gl_3_2_check_funcs[] =
+{
+    "glGenTransformFeedbacks",
+    "glBindTransformFeedback",
+    "glPauseTransformFeedback",
+    "glResumeTransformFeedback",
+    "glDeleteTransformFeedbacks",
+    "glVertexAttribDivisor"
+};
+
 static bool vigs_gl_backend_wgl_check_gl_version(struct vigs_gl_backend_wgl *gl_backend_wgl,
                                                  bool *is_gl_2)
 {
@@ -155,6 +166,7 @@ static bool vigs_gl_backend_wgl_check_gl_version(struct vigs_gl_backend_wgl *gl_
     UINT n = 0;
     PIXELFORMATDESCRIPTOR pix_fmt;
     HGLRC ctx;
+    unsigned int i;
 
     tmp = getenv("GL_VERSION");
 
@@ -235,6 +247,19 @@ static bool vigs_gl_backend_wgl_check_gl_version(struct vigs_gl_backend_wgl *gl_
         VIGS_LOG_INFO("wglCreateContextAttribsARB failed, using OpenGL 2.1");
     }
 
+    if (*is_gl_2 == false) {
+        for (i = 0;
+             i < sizeof(gl_3_2_check_funcs)/sizeof(gl_3_2_check_funcs[0]);
+             ++i) {
+            if (!gl_backend_wgl->wglGetProcAddress((LPCSTR)
+                                                   gl_3_2_check_funcs[i])) {
+                VIGS_LOG_INFO("Failed to find function \"%s\", "
+                              "using OpenGL 2.1", gl_3_2_check_funcs[i]);
+                *is_gl_2 = true;
+            }
+        }
+    }
+
     gl_backend_wgl->wglDeleteContext(ctx);
 
 out3:
@@ -455,6 +480,7 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     };
     const char *ext_str = NULL;
     struct vigs_gl_backend_wgl *gl_backend_wgl = NULL;
+    HGLRC qt5_ctx = NULL;
 
     vigs_win_class.cbSize = sizeof(WNDCLASSEXA);
     vigs_win_class.style = 0;
@@ -611,6 +637,8 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     VIGS_GL_GET_PROC(VertexAttribPointer, glVertexAttribPointer);
     VIGS_GL_GET_PROC(Uniform4fv, glUniform4fv);
     VIGS_GL_GET_PROC(UniformMatrix4fv, glUniformMatrix4fv);
+    VIGS_GL_GET_PROC(Uniform2fv, glUniform2fv);
+    VIGS_GL_GET_PROC(Uniform1f, glUniform1f);
     VIGS_GL_GET_PROC(Uniform1i, glUniform1i);
     VIGS_GL_GET_PROC(Uniform2f, glUniform2f);
     VIGS_GL_GET_PROC(ActiveTexture, glActiveTexture);
@@ -655,6 +683,14 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     DestroyWindow(tmp_win);
     tmp_win = NULL;
 
+    if (vigs_qt5_onscreen_enabled()) {
+        qt5_ctx =
+            (HGLRC)vigs_qt5_gl_context_create(gl_backend_wgl->base.is_gl_2);
+        if (!qt5_ctx) {
+            goto fail;
+        }
+    }
+
     gl_backend_wgl->win = CreateWindow(VIGS_WGL_WIN_CLASS, "VIGSWin",
                                        WS_DISABLED | WS_POPUP,
                                        0, 0, 1, 1, NULL, NULL, 0, 0);
@@ -690,7 +726,7 @@ struct vigs_backend *vigs_gl_backend_create(void *display)
     }
 
     if (!vigs_gl_backend_wgl_create_context(gl_backend_wgl,
-                                            NULL,
+                                            qt5_ctx,
                                             &gl_backend_wgl->ctx)) {
         goto fail;
     }
index e65e1bc..43eefe3 100644 (file)
@@ -2087,7 +2087,7 @@ typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLsh
 #endif  /* GL_GLEXT_LEGACY */
 
 
-
+#ifdef GL_ARB_shader_objects
 #if GL_ARB_shader_objects
 
 #ifndef GL_MESA_shader_debug
@@ -2106,7 +2106,7 @@ GLAPI GLsizei GLAPIENTRY glGetDebugLogLengthMESA (GLhandleARB obj, GLenum logTyp
 #endif /* GL_MESA_shader_debug */
 
 #endif /* GL_ARB_shader_objects */
-
+#endif
 
 /*
  * ???. GL_MESA_packed_depth_stencil
diff --git a/hw/vigs/vigs_offscreen_server.c b/hw/vigs/vigs_offscreen_server.c
new file mode 100644 (file)
index 0000000..3f961a7
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * vigs
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Stanislav Vorobiov <s.vorobiov@samsung.com>
+ * Jinhyung Jo <jinhyung.jo@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 "vigs_offscreen_server.h"
+#include "vigs_backend.h"
+#include "work_queue.h"
+
+struct vigs_display_work_item
+{
+    struct work_queue_item base;
+
+    struct vigs_server *server;
+};
+
+static void vigs_offscreen_server_display_work(struct work_queue_item *wq_item)
+{
+    struct vigs_display_work_item *item = (struct vigs_display_work_item*)wq_item;
+    struct vigs_server *server = item->server;
+    int index = (&server->capture_buffers[0] == server->captured) ? 1 : 0;
+
+    vigs_server_finish_update_display(
+        server, server->backend->display(server->backend,
+                                         server->capture_buffers[index].data));
+
+    g_free(item);
+}
+
+static bool vigs_offscreen_server_begin_update(struct vigs_server *server,
+                                               bool is_capturing,
+                                               bool force)
+{
+    return vigs_server_process_captured(server, force);
+}
+
+static void vigs_offscreen_server_finish_update(struct vigs_server *server,
+                                                bool composited,
+                                                bool dirty)
+{
+    if (dirty) {
+        vigs_server_finish_update_display(server, true);
+    } else if (composited) {
+        struct vigs_offscreen_server *offscreen_server =
+            (struct vigs_offscreen_server*)server;
+
+        struct vigs_display_work_item *item;
+
+        item = g_malloc(sizeof(*item));
+
+        work_queue_item_init(&item->base, &vigs_offscreen_server_display_work);
+
+        item->server = server;
+
+        work_queue_add_item(offscreen_server->display_queue, &item->base);
+    } else {
+        vigs_server_finish_update_display(server, false);
+    }
+}
+
+static bool vigs_offscreen_server_display(struct vigs_server *server,
+                                          bool *displayed)
+{
+    *displayed = false;
+    return false;
+}
+
+static bool vigs_offscreen_server_capture(struct vigs_server *server,
+                                          struct vigs_surface *sfc,
+                                          void *pixels)
+{
+    if (server->captured && server->captured->data) {
+        memcpy(pixels,
+               server->captured->data,
+               sfc->stride * sfc->ws_sfc->height);
+
+        return true;
+    }
+
+    return false;
+}
+
+static void vigs_offscreen_server_destroy(struct vigs_server *server)
+{
+    struct vigs_offscreen_server *offscreen_server =
+        (struct vigs_offscreen_server*)server;
+
+    work_queue_destroy(offscreen_server->display_queue);
+
+    vigs_server_cleanup(server);
+
+    g_free(server);
+}
+
+struct vigs_server *vigs_offscreen_server_create(uint8_t *vram_ptr,
+                                                 uint8_t *ram_ptr,
+                                                 struct vigs_display_ops *display_ops,
+                                                 struct vigs_capture_ops *capture_ops,
+                                                 void *display_user_data,
+                                                 struct vigs_backend *backend,
+                                                 struct work_queue *render_queue)
+{
+    struct vigs_offscreen_server *server = NULL;
+
+    server = g_malloc0(sizeof(*server));
+
+    if (!vigs_server_init(&server->base, vram_ptr, ram_ptr,
+                          display_ops, capture_ops, display_user_data,
+                          backend, render_queue)) {
+        g_free(server);
+        return NULL;
+    }
+
+    server->display_queue = work_queue_create("display_queue");
+
+    server->base.begin_update = &vigs_offscreen_server_begin_update;
+    server->base.finish_update = &vigs_offscreen_server_finish_update;
+    server->base.display = &vigs_offscreen_server_display;
+    server->base.capture = &vigs_offscreen_server_capture;
+    server->base.destroy = &vigs_offscreen_server_destroy;
+
+    return &server->base;
+}
diff --git a/hw/vigs/vigs_offscreen_server.h b/hw/vigs/vigs_offscreen_server.h
new file mode 100644 (file)
index 0000000..f0e715f
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * vigs
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Stanislav Vorobiov <s.vorobiov@samsung.com>
+ * Jinhyung Jo <jinhyung.jo@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 _QEMU_VIGS_OFFSCREEN_SERVER_H
+#define _QEMU_VIGS_OFFSCREEN_SERVER_H
+
+#include "vigs_server.h"
+
+struct vigs_offscreen_server
+{
+    struct vigs_server base;
+
+    struct work_queue *display_queue;
+};
+
+struct vigs_server *vigs_offscreen_server_create(uint8_t *vram_ptr,
+                                                 uint8_t *ram_ptr,
+                                                 struct vigs_display_ops *display_ops,
+                                                 struct vigs_capture_ops *capture_ops,
+                                                 void *display_user_data,
+                                                 struct vigs_backend *backend,
+                                                 struct work_queue *render_queue);
+
+#endif
diff --git a/hw/vigs/vigs_onscreen_server.c b/hw/vigs/vigs_onscreen_server.c
new file mode 100644 (file)
index 0000000..7fcc352
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * vigs
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Stanislav Vorobiov <s.vorobiov@samsung.com>
+ * Jinhyung Jo <jinhyung.jo@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 "vigs_onscreen_server.h"
+#include "vigs_backend.h"
+#include "vigs_log.h"
+#include "work_queue.h"
+
+static bool vigs_onscreen_server_begin_update(struct vigs_server *server,
+                                              bool is_capturing,
+                                              bool force)
+{
+    struct vigs_onscreen_server *onscreen_server =
+        (struct vigs_onscreen_server*)server;
+
+    qemu_mutex_lock(&onscreen_server->mutex);
+
+    if (force) {
+        ++onscreen_server->invalidate_cnt;
+    }
+
+    if (is_capturing) {
+        /*
+         * If capturing is in progress then just skip this update.
+         */
+        goto out;
+    }
+
+    onscreen_server->updated = false;
+    onscreen_server->composited = false;
+    onscreen_server->dirty = false;
+
+out:
+    qemu_mutex_unlock(&onscreen_server->mutex);
+
+    return false;
+}
+
+static void vigs_onscreen_server_finish_update(struct vigs_server *server,
+                                               bool composited,
+                                               bool dirty)
+{
+    struct vigs_onscreen_server *onscreen_server =
+        (struct vigs_onscreen_server*)server;
+
+    qemu_mutex_lock(&onscreen_server->mutex);
+
+    onscreen_server->updated = true;
+    onscreen_server->composited = composited;
+    onscreen_server->dirty = dirty;
+
+    qemu_mutex_unlock(&onscreen_server->mutex);
+
+    qemu_cond_signal(&onscreen_server->cond);
+}
+
+static bool vigs_onscreen_server_display(struct vigs_server *server,
+                                         bool *displayed)
+{
+    struct vigs_onscreen_server *onscreen_server =
+        (struct vigs_onscreen_server*)server;
+    bool force = false;
+
+    qemu_mutex_lock(&onscreen_server->mutex);
+
+    /*
+     * Wait until rendering is finished.
+     */
+    while (!onscreen_server->updated) {
+        qemu_cond_wait(&onscreen_server->cond, &onscreen_server->mutex);
+    }
+
+    if (onscreen_server->invalidate_cnt > 0) {
+        --onscreen_server->invalidate_cnt;
+        force = true;
+    }
+
+    onscreen_server->updated = false;
+
+    qemu_mutex_unlock(&onscreen_server->mutex);
+
+    *displayed = true;
+
+    if (onscreen_server->dirty) {
+        /*
+         * Software composition took place, finish ASAP and
+         * process captured data.
+         */
+        vigs_server_finish_update_display(server, true);
+        return vigs_server_process_captured(server, force);
+    } else if (onscreen_server->composited) {
+        /*
+         * Hw composition took place, display the content.
+         */
+        server->backend->display(server->backend, NULL);
+    } else if (force) {
+        /*
+         * Nothing happened, but if it's a forced display, then
+         * we should try to display hw stuff first, if there isn't any
+         * then display sw stuff.
+         */
+        if (!server->backend->display(server->backend, NULL)) {
+            vigs_server_finish_update_display(server, false);
+            return vigs_server_process_captured(server, force);
+        }
+    } else {
+        *displayed = false;
+    }
+
+    vigs_server_finish_update_display(server, false);
+
+    return false;
+}
+
+static bool vigs_onscreen_server_capture(struct vigs_server *server,
+                                         struct vigs_surface *sfc,
+                                         void *pixels)
+{
+    return server->backend->capture(sfc, pixels);
+}
+
+static void vigs_onscreen_server_destroy(struct vigs_server *server)
+{
+    struct vigs_onscreen_server *onscreen_server =
+        (struct vigs_onscreen_server*)server;
+
+    qemu_cond_destroy(&onscreen_server->cond);
+    qemu_mutex_destroy(&onscreen_server->mutex);
+
+    vigs_server_cleanup(server);
+
+    g_free(server);
+}
+
+struct vigs_server *vigs_onscreen_server_create(uint8_t *vram_ptr,
+                                                uint8_t *ram_ptr,
+                                                struct vigs_display_ops *display_ops,
+                                                struct vigs_capture_ops *capture_ops,
+                                                void *display_user_data,
+                                                struct vigs_backend *backend,
+                                                struct work_queue *render_queue)
+{
+    struct vigs_onscreen_server *server = NULL;
+
+    server = g_malloc0(sizeof(*server));
+
+    if (!vigs_server_init(&server->base, vram_ptr, ram_ptr,
+                          display_ops, capture_ops, display_user_data,
+                          backend, render_queue)) {
+        g_free(server);
+        return NULL;
+    }
+
+    qemu_mutex_init(&server->mutex);
+    qemu_cond_init(&server->cond);
+
+    server->base.begin_update = &vigs_onscreen_server_begin_update;
+    server->base.finish_update = &vigs_onscreen_server_finish_update;
+    server->base.display = &vigs_onscreen_server_display;
+    server->base.capture = &vigs_onscreen_server_capture;
+    server->base.destroy = &vigs_onscreen_server_destroy;
+
+    return &server->base;
+}
diff --git a/hw/vigs/vigs_onscreen_server.h b/hw/vigs/vigs_onscreen_server.h
new file mode 100644 (file)
index 0000000..b0ea1e9
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * vigs
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Stanislav Vorobiov <s.vorobiov@samsung.com>
+ * Jinhyung Jo <jinhyung.jo@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 _QEMU_VIGS_ONSCREEN_SERVER_H
+#define _QEMU_VIGS_ONSCREEN_SERVER_H
+
+#include "vigs_server.h"
+
+struct vigs_onscreen_server
+{
+    struct vigs_server base;
+
+    QemuMutex mutex;
+    QemuCond cond;
+    bool updated;
+    bool composited;
+    bool dirty;
+
+    int invalidate_cnt;
+};
+
+struct vigs_server *vigs_onscreen_server_create(uint8_t *vram_ptr,
+                                                uint8_t *ram_ptr,
+                                                struct vigs_display_ops *display_ops,
+                                                struct vigs_capture_ops *capture_ops,
+                                                void *display_user_data,
+                                                struct vigs_backend *backend,
+                                                struct work_queue *render_queue);
+
+#endif
diff --git a/hw/vigs/vigs_qt5.cpp b/hw/vigs/vigs_qt5.cpp
new file mode 100644 (file)
index 0000000..1166c8d
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * vigs
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Stanislav Vorobiov <s.vorobiov@samsung.com>
+ * Jinhyung Jo <jinhyung.jo@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 "vigs_qt5.h"
+#include "config-host.h"
+#include <QGuiApplication>
+#include <QOpenGLContext>
+#include <qpa/qplatformnativeinterface.h>
+#include <stdio.h>
+
+extern QApplication *qt5App;
+extern QOpenGLContext *qt5GLContext;
+extern QSurfaceFormat qt5GLFormat;
+
+extern void qt5_register_capture_request_listener(void *listener,
+                                                  void (*handler)(void *));
+extern void qt5_unregister_capture_request_listener(void *listener);
+extern void qt5_process_captured(bool captured, void *pixels,
+                                 int width, int height);
+
+bool vigs_qt5_onscreen_enabled(void)
+{
+#ifndef CONFIG_DARWIN
+    /* Qt5 bug, QGLWidget has some problem on MacOS.
+     * (scrambled screen when resizing, invalid region masking) */
+    if (qt5App != NULL) {
+        return true;
+    }
+#endif
+
+    return  false;
+}
+
+void *vigs_qt5_display(void)
+{
+    if (!qt5App) {
+        return NULL;
+    }
+
+    QPlatformNativeInterface *native =
+        QGuiApplication::platformNativeInterface();
+
+    return native->nativeResourceForScreen(QByteArray("display"),
+                                           QGuiApplication::primaryScreen());
+}
+
+void *vigs_qt5_gl_context_create(bool is_gl2)
+{
+    if (!qt5App) {
+        fprintf(stderr, "QT5 not enabled!\n");
+        return NULL;
+    }
+
+    if (qt5GLContext) {
+        fprintf(stderr, "QT5 GL context already created!\n");
+        return NULL;
+    }
+
+    qt5GLContext = new QOpenGLContext();
+
+    QSurfaceFormat format;
+
+    format.setRedBufferSize(8);
+    format.setGreenBufferSize(8);
+    format.setBlueBufferSize(8);
+    format.setAlphaBufferSize(8);
+    format.setDepthBufferSize(24);
+    format.setStencilBufferSize(8);
+
+    if (!is_gl2) {
+        format.setMajorVersion(3);
+#ifdef CONFIG_DARWIN
+        format.setMinorVersion(2);
+        format.setProfile(QSurfaceFormat::CoreProfile);
+#else
+        format.setMinorVersion(1);
+#endif
+    }
+
+    qt5GLContext->setScreen(QGuiApplication::primaryScreen());
+    qt5GLContext->setFormat(format);
+
+    if (!qt5GLContext->create()) {
+        fprintf(stderr, "Cannot create QT5 GL context!\n");
+
+        delete qt5GLContext;
+        qt5GLContext = NULL;
+
+        return NULL;
+    }
+
+    if (!is_gl2) {
+        if ((qt5GLContext->format().majorVersion() < 3) ||
+            ((qt5GLContext->format().majorVersion() == 3) &&
+             (qt5GLContext->format().minorVersion() < 1))) {
+            fprintf(stderr, "Cannot create QT5 3.1 GL context!\n");
+
+            delete qt5GLContext;
+            qt5GLContext = NULL;
+
+            return NULL;
+        }
+    }
+
+    QPlatformNativeInterface *native =
+        QGuiApplication::platformNativeInterface();
+
+    void *ret = NULL;
+
+#if defined(CONFIG_LINUX)
+    ret = native->nativeResourceForContext(QByteArray("glxcontext"), qt5GLContext);
+#elif defined(CONFIG_WIN32)
+    ret = native->nativeResourceForContext(QByteArray("renderingContext"), qt5GLContext);
+#elif defined(CONFIG_DARWIN)
+    ret = native->nativeResourceForContext(QByteArray("cglContextObj"), qt5GLContext);
+#endif
+
+    if (!ret) {
+        fprintf(stderr, "Cannot get native QT5 GL context!\n");
+
+        delete qt5GLContext;
+        qt5GLContext = NULL;
+    }
+
+    qt5GLFormat = format;
+
+    return ret;
+}
+
+void vigs_qt5_register_capture_request_listener(void *listener,
+                                                void (*handler)(void *))
+{
+    qt5_register_capture_request_listener(listener, handler);
+}
+
+void vigs_qt5_unregister_capture_request_listener(void *listener)
+{
+    qt5_unregister_capture_request_listener(listener);
+}
+
+void vigs_qt5_process_captured(bool captured, void *pixels,
+                               int width, int height)
+{
+    qt5_process_captured(captured, pixels, width, height);
+}
diff --git a/hw/vigs/vigs_qt5.h b/hw/vigs/vigs_qt5.h
new file mode 100644 (file)
index 0000000..b88c84e
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * vigs
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Stanislav Vorobiov <s.vorobiov@samsung.com>
+ * Jinhyung Jo <jinhyung.jo@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 _QEMU_VIGS_QT5_H
+#define _QEMU_VIGS_QT5_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool vigs_qt5_onscreen_enabled(void);
+
+void *vigs_qt5_display(void);
+
+void *vigs_qt5_gl_context_create(bool is_gl2);
+
+void vigs_qt5_register_capture_request_listener(void *listener,
+                                                void (*handler)(void *));
+void vigs_qt5_unregister_capture_request_listener(void *listener);
+void vigs_qt5_process_captured(bool captured, void *pixels,
+                               int width, int height);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/hw/vigs/vigs_qt5_stub.c b/hw/vigs/vigs_qt5_stub.c
new file mode 100644 (file)
index 0000000..94bf46d
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * vigs stub
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Kitae Kim <kt920.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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
+ *
+ */
+
+/*
+ * This is just a temporary implemention to fix compilation errors
+ * in case of "disable-qt" configuration. We should consider it later.
+ */
+
+#include "emulator_common.h"
+#include "vigs_qt5.h"
+
+uint32_t qt5_window_width = 0;
+uint32_t qt5_window_height = 0;
+int qt5_window_angle = 0;
+
+bool vigs_qt5_onscreen_enabled(void)
+{
+    return false;
+}
+
+void *vigs_qt5_display(void)
+{
+    return NULL;
+}
+
+void *vigs_qt5_gl_context_create(bool is_gl2)
+{
+    return NULL;
+}
+
+void vigs_qt5_register_capture_request_listener(void *listener,
+                                                void (*handler)(void *))
+{
+    return;
+}
+
+void vigs_qt5_unregister_capture_request_listener(void *listener)
+{
+    return;
+}
+
+void vigs_qt5_process_captured(bool captured, void *pixels,
+                               int width, int height)
+{
+    return;
+}
index 4212453..3c3b184 100644 (file)
@@ -438,6 +438,36 @@ static void vigs_server_work(struct work_queue_item *wq_item)
     g_free(item);
 }
 
+static void vigs_server_capture_work(struct work_queue_item *wq_item)
+{
+    struct vigs_server_work_item *item = (struct vigs_server_work_item*)wq_item;
+    struct vigs_server *server = item->server;
+    struct vigs_surface *root_sfc = server->root_sfc;
+    bool captured = false;
+    void *pixels;
+
+    if (!root_sfc) {
+        return;
+    }
+
+    qemu_mutex_lock(&server->capture_mutex);
+
+    pixels = vigs_server_get_capture_buffer(server, root_sfc);
+
+    if (pixels) {
+        captured = server->capture(server, root_sfc, pixels);
+    }
+
+    server->capture_ops->process_captured(captured,
+                                          pixels,
+                                          root_sfc->ws_sfc->width,
+                                          root_sfc->ws_sfc->height);
+
+    qemu_mutex_unlock(&server->capture_mutex);
+
+    g_free(item);
+}
+
 static void vigs_server_set_root_surface_work(struct work_queue_item *wq_item)
 {
     struct vigs_server_set_root_surface_work_item *item =
@@ -486,111 +516,52 @@ out:
     g_free(item);
 }
 
-static uint8_t *vigs_server_update_display_start_cb(void *user_data,
-                                                    uint32_t width,
-                                                    uint32_t height,
-                                                    uint32_t stride,
-                                                    vigsp_surface_format format)
-{
-    struct vigs_server *server = user_data;
-
-    qemu_mutex_lock(&server->capture_mutex);
-
-    if ((server->captured.stride != stride) ||
-        (server->captured.height != height)) {
-        g_free(server->captured.data);
-        server->captured.data = g_malloc(stride * height);
-    }
-
-    server->captured.width = width;
-    server->captured.height = height;
-    server->captured.stride = stride;
-    server->captured.format = format;
-
-    return server->captured.data;
-}
-
-static void vigs_server_update_display_end_cb(void *user_data,
-                                              bool was_started,
-                                              bool dirty)
-{
-    struct vigs_server *server = user_data;
-    uint32_t capture_fence_seq;
-
-    if (!was_started) {
-        qemu_mutex_lock(&server->capture_mutex);
-    }
-
-    if (dirty) {
-        server->captured.dirty = true;
-    }
-
-    server->is_capturing = false;
-    capture_fence_seq = server->capture_fence_seq;
-    server->capture_fence_seq = 0;
-
-    qemu_mutex_unlock(&server->capture_mutex);
-
-    if (capture_fence_seq) {
-        server->display_ops->fence_ack(server->display_user_data,
-                                       capture_fence_seq);
-    }
-}
-
 static void vigs_server_update_display_work(struct work_queue_item *wq_item)
 {
     struct vigs_server_work_item *item = (struct vigs_server_work_item*)wq_item;
     struct vigs_server *server = item->server;
     struct vigs_surface *root_sfc = server->root_sfc;
-    int i;
-    bool planes_on = false;
     bool planes_dirty = false;
+    bool dirty = false;
+    bool composited = false;
+    int i, index;
 
     if (!root_sfc) {
         /*
          * If no root surface then this is a no-op.
          * TODO: Can planes be enabled without a root surface ?
          */
-        vigs_server_update_display_end_cb(server, false, false);
         goto out;
     }
 
     for (i = 0; i < VIGS_MAX_PLANES; ++i) {
-        if (!planes_dirty) {
-            planes_dirty = vigs_plane_dirty(&server->planes[i]);
-        }
-
-        if (!planes_on) {
-            planes_on = vigs_plane_enabled(&server->planes[i]);
-        }
+        planes_dirty |= vigs_plane_dirty(&server->planes[i]);
     }
 
-    if (root_sfc->ptr && !root_sfc->is_dirty && !planes_on) {
-        /*
-         * Root surface is scanout, it's not dirty and planes not on,
-         * finish immediately.
-         */
-        uint8_t *buff = vigs_server_update_display_start_cb(server,
-                                                            root_sfc->ws_sfc->width,
-                                                            root_sfc->ws_sfc->height,
-                                                            root_sfc->stride,
-                                                            root_sfc->format);
-
-        memcpy(buff,
-               root_sfc->ptr,
-               root_sfc->stride * root_sfc->ws_sfc->height);
-
-        vigs_server_update_display_end_cb(server, true, true);
-    } else if (root_sfc->ptr || root_sfc->is_dirty || planes_dirty) {
+    if (root_sfc->ptr || root_sfc->is_dirty || planes_dirty) {
         /*
          * Composite root surface and planes.
          */
+        composited = true;
+
+        index = (&server->capture_buffers[0] == server->captured) ? 1 : 0;
+
+        if ((server->capture_buffers[index].stride != root_sfc->stride) ||
+            (server->capture_buffers[index].height != root_sfc->ws_sfc->height)) {
+            g_free(server->capture_buffers[index].data);
+            server->capture_buffers[index].data = g_malloc(root_sfc->stride * root_sfc->ws_sfc->height);
+        }
+
+        server->capture_buffers[index].width = root_sfc->ws_sfc->width;
+        server->capture_buffers[index].height = root_sfc->ws_sfc->height;
+        server->capture_buffers[index].stride = root_sfc->stride;
+        server->capture_buffers[index].format = root_sfc->format;
+
         server->backend->batch_start(server->backend);
-        server->backend->composite(root_sfc,
-                                   &server->planes[0],
-                                   &vigs_server_update_display_start_cb,
-                                   &vigs_server_update_display_end_cb,
-                                   server);
+        dirty = server->backend->composite(root_sfc,
+                                           &server->planes[0],
+                                           planes_dirty,
+                                           server->capture_buffers[index].data);
         server->backend->batch_end(server->backend);
 
         root_sfc->is_dirty = false;
@@ -598,14 +569,11 @@ static void vigs_server_update_display_work(struct work_queue_item *wq_item)
         for (i = 0; i < VIGS_MAX_PLANES; ++i) {
             vigs_plane_reset_dirty(&server->planes[i]);
         }
-    } else {
-        /*
-         * No changes, no-op.
-         */
-        vigs_server_update_display_end_cb(server, false, false);
     }
 
 out:
+    server->finish_update(server, composited, dirty);
+
     g_free(item);
 }
 
@@ -725,23 +693,36 @@ static struct vigs_comm_ops vigs_server_dispatch_ops =
     .batch = &vigs_server_dispatch_batch
 };
 
-struct vigs_server *vigs_server_create(uint8_t *vram_ptr,
-                                       uint8_t *ram_ptr,
-                                       struct vigs_display_ops *display_ops,
-                                       void *display_user_data,
-                                       struct vigs_backend *backend,
-                                       struct work_queue *render_queue)
+static void vigs_server_capture(void *data)
 {
-    struct vigs_server *server = NULL;
+    struct vigs_server *server = (struct vigs_server*)data;
+    struct vigs_server_work_item *item;
+
+    item = g_malloc(sizeof(*item));
 
-    server = g_malloc0(sizeof(*server));
+    work_queue_item_init(&item->base, &vigs_server_capture_work);
 
+    item->server = server;
+
+    work_queue_add_item(server->capture_queue, &item->base);
+}
+
+bool vigs_server_init(struct vigs_server *server,
+                      uint8_t *vram_ptr,
+                      uint8_t *ram_ptr,
+                      struct vigs_display_ops *display_ops,
+                      struct vigs_capture_ops *capture_ops,
+                      void *display_user_data,
+                      struct vigs_backend *backend,
+                      struct work_queue *render_queue)
+{
     server->wsi.ws_info = backend->ws_info;
     server->wsi.acquire_surface = &vigs_server_acquire_surface;
     server->wsi.fence_ack = &vigs_server_fence_ack;
 
     server->vram_ptr = vram_ptr;
     server->display_ops = display_ops;
+    server->capture_ops = capture_ops;
     server->display_user_data = display_user_data;
     server->backend = backend;
     server->render_queue = render_queue;
@@ -749,7 +730,7 @@ struct vigs_server *vigs_server_create(uint8_t *vram_ptr,
     server->comm = vigs_comm_create(ram_ptr);
 
     if (!server->comm) {
-        goto fail;
+        return false;
     }
 
     server->surfaces = g_hash_table_new_full(g_direct_hash,
@@ -759,24 +740,28 @@ struct vigs_server *vigs_server_create(uint8_t *vram_ptr,
 
     qemu_mutex_init(&server->capture_mutex);
 
-    return server;
+    server->captured = &server->capture_buffers[0];
 
-fail:
-    g_free(server);
+    server->capture_queue = work_queue_create("capture_queue");
+    server->capture_ops->register_listener(server,
+                                           vigs_server_capture);
 
-    return NULL;
+    return true;
 }
 
-void vigs_server_destroy(struct vigs_server *server)
+void vigs_server_cleanup(struct vigs_server *server)
 {
     vigs_server_reset(server);
 
+    server->capture_ops->unregister_listener(server);
+
     g_hash_table_destroy(server->surfaces);
     vigs_comm_destroy(server->comm);
     server->backend->destroy(server->backend);
     qemu_mutex_destroy(&server->capture_mutex);
-    g_free(server->captured.data);
-    g_free(server);
+    g_free(server->capture_buffers[0].data);
+    g_free(server->capture_buffers[1].data);
+    g_free(server->capture_buffers[2].data);
 }
 
 void vigs_server_reset(struct vigs_server *server)
@@ -813,87 +798,113 @@ void vigs_server_dispatch(struct vigs_server *server,
 
 bool vigs_server_update_display(struct vigs_server *server, int invalidate_cnt)
 {
+    bool is_capturing = server->is_capturing;
+
+    bool updated = server->begin_update(server, is_capturing, (invalidate_cnt > 0));
+
+    if (!is_capturing) {
+        struct vigs_server_work_item *item;
+
+        item = g_malloc(sizeof(*item));
+
+        work_queue_item_init(&item->base, &vigs_server_update_display_work);
+
+        item->server = server;
+
+        server->is_capturing = true;
+
+        work_queue_add_item(server->render_queue, &item->base);
+    }
+
+    return updated;
+}
+
+bool vigs_server_display(struct vigs_server *server, bool *displayed)
+{
+    return server->display(server, displayed);
+}
+
+void *vigs_server_get_capture_buffer(struct vigs_server *server,
+                                     struct vigs_surface *sfc)
+{
+    const int index = 2;
+
+    if ((server->capture_buffers[index].stride != sfc->stride) ||
+        (server->capture_buffers[index].height != sfc->ws_sfc->height)) {
+        g_free(server->capture_buffers[index].data);
+        server->capture_buffers[index].data = g_malloc(sfc->stride * sfc->ws_sfc->height);
+    }
+
+    server->capture_buffers[index].width = sfc->ws_sfc->width;
+    server->capture_buffers[index].height = sfc->ws_sfc->height;
+    server->capture_buffers[index].stride = sfc->stride;
+    server->capture_buffers[index].format = sfc->format;
+
+    return server->capture_buffers[index].data;
+}
+
+bool vigs_server_process_captured(struct vigs_server *server, bool force)
+{
     bool updated = false;
-    uint32_t sfc_bpp;
     uint32_t display_stride, display_bpp;
     uint8_t *display_data;
 
     qemu_mutex_lock(&server->capture_mutex);
 
-    if (!server->captured.data ||
-        (!server->captured.dirty && invalidate_cnt <= 0)) {
+    if (!server->captured->data ||
+        (!server->captured->dirty && !force)) {
         goto out;
     }
 
-    server->captured.dirty = false;
-    updated = true;
-
-    sfc_bpp = vigs_format_bpp(server->captured.format);
+    server->captured->dirty = false;
 
     server->display_ops->resize(server->display_user_data,
-                                server->captured.width,
-                                server->captured.height);
+                                server->captured->width,
+                                server->captured->height);
 
     display_stride = server->display_ops->get_stride(server->display_user_data);
     display_bpp = server->display_ops->get_bpp(server->display_user_data);
     display_data = server->display_ops->get_data(server->display_user_data);
 
-    if (sfc_bpp != display_bpp) {
-        VIGS_LOG_CRITICAL("bpp mismatch");
+    if ((vigs_format_bpp(server->captured->format) != display_bpp) ||
+        (server->captured->stride != display_stride)) {
+        VIGS_LOG_CRITICAL("bpp/format mismatch");
         assert(false);
-        exit(1);
-    }
-
-    if (display_stride == server->captured.stride) {
-        switch (server->captured.format) {
-        case vigsp_surface_bgrx8888:
-        case vigsp_surface_bgra8888:
-            memcpy(display_data,
-                   server->captured.data,
-                   server->captured.height * display_stride);
-            break;
-        default:
-            assert(false);
-            VIGS_LOG_CRITICAL("unknown format: %d", server->captured.format);
-            exit(1);
-        }
-    } else {
-        uint32_t i;
-        uint8_t *src = server->captured.data;
-        uint8_t *dst = display_data;
-
-        for (i = 0; i < server->captured.height; ++i) {
-            switch (server->captured.format) {
-            case vigsp_surface_bgrx8888:
-            case vigsp_surface_bgra8888:
-                memcpy(dst, src, server->captured.width * sfc_bpp);
-                break;
-            default:
-                assert(false);
-                VIGS_LOG_CRITICAL("unknown format: %d", server->captured.format);
-                exit(1);
-            }
-            src += server->captured.stride;
-            dst += display_stride;
-        }
+        goto out;
     }
 
+    memcpy(display_data,
+           server->captured->data,
+           server->captured->stride * server->captured->height);
+
+    updated = true;
+
 out:
     qemu_mutex_unlock(&server->capture_mutex);
 
-    if (!server->is_capturing) {
-        struct vigs_server_work_item *item;
+    return updated;
+}
 
-        item = g_malloc(sizeof(*item));
+void vigs_server_finish_update_display(struct vigs_server *server, bool dirty)
+{
+    uint32_t capture_fence_seq = 0;
 
-        work_queue_item_init(&item->base, &vigs_server_update_display_work);
+    qemu_mutex_lock(&server->capture_mutex);
 
-        item->server = server;
+    if (dirty) {
+        int index = (&server->capture_buffers[0] == server->captured) ? 1 : 0;
+        server->capture_buffers[index].dirty = true;
+        server->captured = &server->capture_buffers[index];
+    }
 
-        server->is_capturing = true;
+    server->is_capturing = false;
+    capture_fence_seq = server->capture_fence_seq;
+    server->capture_fence_seq = 0;
 
-        work_queue_add_item(server->render_queue, &item->base);
-    }
+    qemu_mutex_unlock(&server->capture_mutex);
 
-    return updated;
+    if (capture_fence_seq) {
+        server->display_ops->fence_ack(server->display_user_data,
+                                       capture_fence_seq);
+    }
 }
index 7bb902b..15f64e5 100644 (file)
@@ -67,6 +67,17 @@ struct vigs_display_ops
                       uint32_t /*fence_seq*/);
 };
 
+struct vigs_capture_ops
+{
+    void (*register_listener)(void */*listener*/,
+                              void (*handler)(void */*listener*/));
+    void (*unregister_listener)(void */*listener*/);
+    void (*process_captured)(bool /*captured*/,
+                             void */*pixels*/,
+                             uint32_t /*width*/,
+                             uint32_t /*height*/);
+};
+
 struct vigs_server
 {
     struct winsys_interface wsi;
@@ -74,12 +85,16 @@ struct vigs_server
     uint8_t *vram_ptr;
 
     struct vigs_display_ops *display_ops;
+    struct vigs_capture_ops *capture_ops;
+
     void *display_user_data;
 
     struct vigs_backend *backend;
 
     struct work_queue *render_queue;
 
+    struct work_queue *capture_queue;
+
     struct vigs_comm *comm;
 
     /*
@@ -110,21 +125,39 @@ struct vigs_server
         uint32_t stride;
         vigsp_surface_format format;
         bool dirty;
-    } captured;
+    } capture_buffers[3], *captured;
 
     /*
      * @}
      */
+
+    bool (*begin_update)(struct vigs_server */*server*/,
+                         bool /*is_capturing*/,
+                         bool /*force*/);
+
+    void (*finish_update)(struct vigs_server */*server*/,
+                          bool /*composited*/,
+                          bool /*dirty*/);
+
+    bool (*display)(struct vigs_server */*server*/, bool */*displayed*/);
+
+    bool (*capture)(struct vigs_server */*server*/,
+                    struct vigs_surface */*sfc*/,
+                    void */*pixels*/);
+
+    void (*destroy)(struct vigs_server */*server*/);
 };
 
-struct vigs_server *vigs_server_create(uint8_t *vram_ptr,
-                                       uint8_t *ram_ptr,
-                                       struct vigs_display_ops *display_ops,
-                                       void *display_user_data,
-                                       struct vigs_backend *backend,
-                                       struct work_queue *render_queue);
+bool vigs_server_init(struct vigs_server *server,
+                      uint8_t *vram_ptr,
+                      uint8_t *ram_ptr,
+                      struct vigs_display_ops *display_ops,
+                      struct vigs_capture_ops *capture_ops,
+                      void *display_user_data,
+                      struct vigs_backend *backend,
+                      struct work_queue *render_queue);
 
-void vigs_server_destroy(struct vigs_server *server);
+void vigs_server_cleanup(struct vigs_server *server);
 
 void vigs_server_reset(struct vigs_server *server);
 
@@ -133,4 +166,22 @@ void vigs_server_dispatch(struct vigs_server *server,
 
 bool vigs_server_update_display(struct vigs_server *server, int invalidate_cnt);
 
+bool vigs_server_display(struct vigs_server *server, bool *displayed);
+
+void *vigs_server_get_capture_buffer(struct vigs_server *server,
+                                     struct vigs_surface *sfc);
+
+/*
+ * For internal use only.
+ * @{
+ */
+
+bool vigs_server_process_captured(struct vigs_server *server, bool force);
+
+void vigs_server_finish_update_display(struct vigs_server *server, bool dirty);
+
+/*
+ * @}
+ */
+
 #endif
index ee3869d..2261ebc 100644 (file)
@@ -377,39 +377,48 @@ static struct vigs_surface *vigs_sw_backend_create_surface(struct vigs_backend *
     return &sw_sfc->base;
 }
 
-static void vigs_sw_backend_composite(struct vigs_surface *surface,
+static bool vigs_sw_backend_composite(struct vigs_surface *surface,
                                       const struct vigs_plane *planes,
-                                      vigs_composite_start_cb start_cb,
-                                      vigs_composite_end_cb end_cb,
-                                      void *user_data)
+                                      bool planes_dirty,
+                                      uint8_t *display_data)
 {
     struct vigs_sw_surface *sw_sfc = (struct vigs_sw_surface*)surface;
-    uint8_t *buff;
 
     /*
      * TODO: Render planes.
      */
 
-    buff = start_cb(user_data, surface->ws_sfc->width, surface->ws_sfc->height,
-                    surface->stride, surface->format);
-
     if (surface->ptr) {
-        memcpy(buff,
+        memcpy(display_data,
                surface->ptr,
                surface->stride * surface->ws_sfc->height);
-    } else if (surface->is_dirty) {
-        memcpy(buff,
+    } else {
+        memcpy(display_data,
                sw_sfc->data,
                surface->stride * surface->ws_sfc->height);
     }
 
-    end_cb(user_data, true, true);
+    return true;
+}
+
+static bool vigs_sw_backend_capture(struct vigs_surface *surface,
+                                    void *pixels)
+{
+    vigs_sw_backend_composite(surface, NULL, false, pixels);
+
+    return true;
 }
 
 static void vigs_sw_backend_batch_end(struct vigs_backend *backend)
 {
 }
 
+static bool vigs_sw_backend_display(struct vigs_backend *backend,
+                                    uint8_t *display_data)
+{
+    return false;
+}
+
 static void vigs_sw_backend_destroy(struct vigs_backend *backend)
 {
     struct vigs_sw_backend *sw_backend = (struct vigs_sw_backend*)backend;
@@ -429,7 +438,9 @@ struct vigs_backend *vigs_sw_backend_create(void)
     backend->base.batch_start = &vigs_sw_backend_batch_start;
     backend->base.create_surface = &vigs_sw_backend_create_surface;
     backend->base.composite = &vigs_sw_backend_composite;
+    backend->base.capture = &vigs_sw_backend_capture;
     backend->base.batch_end = &vigs_sw_backend_batch_end;
+    backend->base.display = &vigs_sw_backend_display;
     backend->base.destroy = &vigs_sw_backend_destroy;
 
     return &backend->base;
index 2453ae9..fcd358f 100644 (file)
@@ -1,5 +1,3 @@
-QEMU_CFLAGS += -I$(SRC_PATH)/hw/yagl -I$(SRC_PATH)/hw/yagl/yagl_inc
-
 obj-y += yagl_device.o
 obj-y += yagl_log.o
 obj-y += yagl_process.o
@@ -29,3 +27,5 @@ obj-y += yagl_egl_surface_attribs.o
 obj-y += yagl_apis/
 obj-y += yagl_backends/
 obj-y += yagl_drivers/
+
+$(obj)/%.o: QEMU_CFLAGS += -I$(SRC_PATH)/hw/yagl -I$(SRC_PATH)/hw/yagl/yagl_inc
index 31bf8d6..8e24255 100644 (file)
@@ -55,7 +55,6 @@ static const CGLPixelFormatAttribute pixel_format_legacy_attrs[] =
     kCGLPFAAlphaSize, 8,
     kCGLPFADepthSize, 24,
     kCGLPFAStencilSize, 8,
-    kCGLPFANoRecovery,
     kCGLPFAPBuffer,
     0
 };
@@ -68,7 +67,6 @@ static const CGLPixelFormatAttribute pixel_format_3_2_core_attrs[] =
     kCGLPFAAlphaSize, 8,
     kCGLPFADepthSize, 24,
     kCGLPFAStencilSize, 8,
-    kCGLPFANoRecovery,
     kCGLPFAOpenGLProfile, kCGLOGLPVersion_3_2_Core,
     0
 };
index e73af91..08afac4 100644 (file)
@@ -123,6 +123,16 @@ struct yagl_egl_glx
     PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB;
 };
 
+static const char *gl_3_2_check_funcs[] =
+{
+    "glGenTransformFeedbacks",
+    "glBindTransformFeedback",
+    "glPauseTransformFeedback",
+    "glResumeTransformFeedback",
+    "glDeleteTransformFeedbacks",
+    "glVertexAttribDivisor"
+};
+
 static bool yagl_egl_glx_get_gl_version(struct yagl_egl_glx *egl_glx,
                                         yagl_gl_version *version)
 {
@@ -172,6 +182,7 @@ static bool yagl_egl_glx_get_gl_version(struct yagl_egl_glx *egl_glx,
     const GLubyte *(GLAPIENTRY *GetStringi)(GLenum, GLuint) = NULL;
     void (GLAPIENTRY *GetIntegerv)(GLenum, GLint*) = NULL;
     GLint i, num_extensions = 0;
+    unsigned int j;
 
     YAGL_EGL_GLX_ENTER(yagl_egl_glx_get_gl_version, NULL);
 
@@ -239,6 +250,19 @@ static bool yagl_egl_glx_get_gl_version(struct yagl_egl_glx *egl_glx,
         goto out;
     }
 
+    for (j = 0;
+         j < sizeof(gl_3_2_check_funcs)/sizeof(gl_3_2_check_funcs[0]);
+         ++j) {
+        if (!yagl_dyn_lib_get_ogl_procaddr(egl_glx->base.dyn_lib,
+                                           gl_3_2_check_funcs[j])) {
+            YAGL_LOG_INFO("Failed to find function \"%s\", using OpenGL 2.1",
+                          gl_3_2_check_funcs[j]);
+            *version = yagl_gl_2;
+            res = true;
+            goto out;
+        }
+    }
+
     GetStringi = yagl_dyn_lib_get_ogl_procaddr(egl_glx->base.dyn_lib,
                                                "glGetStringi");
 
index c900234..dd62b5e 100644 (file)
@@ -126,6 +126,16 @@ static inline HWND yagl_egl_wgl_dummy_win_create(void)
         WS_DISABLED | WS_POPUP, 0, 0, 1, 1, NULL, NULL, 0, 0);
 }
 
+static const char *gl_3_2_check_funcs[] =
+{
+    "glGenTransformFeedbacks",
+    "glBindTransformFeedback",
+    "glPauseTransformFeedback",
+    "glResumeTransformFeedback",
+    "glDeleteTransformFeedbacks",
+    "glVertexAttribDivisor"
+};
+
 static bool yagl_egl_wgl_get_gl_version(YaglEglWglDriver *egl_wgl,
                                         yagl_gl_version *version)
 {
@@ -178,6 +188,7 @@ static bool yagl_egl_wgl_get_gl_version(YaglEglWglDriver *egl_wgl,
     const GLubyte *(GLAPIENTRY *GetStringi)(GLenum, GLuint) = NULL;
     void (GLAPIENTRY *GetIntegerv)(GLenum, GLint*) = NULL;
     GLint i, num_extensions = 0;
+    unsigned int j;
 
     YAGL_EGL_WGL_ENTER(yagl_egl_wgl_get_gl_version, NULL);
 
@@ -275,6 +286,19 @@ static bool yagl_egl_wgl_get_gl_version(YaglEglWglDriver *egl_wgl,
         goto out6;
     }
 
+    for (j = 0;
+         j < sizeof(gl_3_2_check_funcs)/sizeof(gl_3_2_check_funcs[0]);
+         ++j) {
+        if (!yagl_dyn_lib_get_ogl_procaddr(egl_wgl->base.dyn_lib,
+                                           gl_3_2_check_funcs[j])) {
+            YAGL_LOG_INFO("Failed to find function \"%s\", using OpenGL 2.1",
+                          gl_3_2_check_funcs[j]);
+            *version = yagl_gl_2;
+            res = true;
+            goto out7;
+        }
+    }
+
     GetStringi = yagl_dyn_lib_get_ogl_procaddr(egl_wgl->base.dyn_lib,
                                                "glGetStringi");
 
index 22e66cb..57b3107 100644 (file)
@@ -103,6 +103,7 @@ typedef enum DisplayType
 #ifdef CONFIG_MARU
     DT_MARU_SDL,
     DT_MARU_SHM,
+    DT_MARU_QT,
 #endif
     DT_NONE,
 } DisplayType;
index 0433b2e..2898620 100644 (file)
@@ -1,7 +1,9 @@
 #ifndef CONSOLE_H
 #define CONSOLE_H
 
+#ifndef __cplusplus
 #include "ui/qemu-pixman.h"
+#endif
 #include "qom/object.h"
 #include "qapi/qmp/qdict.h"
 #include "qemu/notify.h"
@@ -369,5 +371,4 @@ int index_from_key(const char *key);
 /* gtk.c */
 void early_gtk_display_init(void);
 void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover);
-
 #endif
index b9f59d4..e045a00 100755 (executable)
@@ -199,6 +199,7 @@ echo "##### QEMU configuring for emulator"
 echo "##### QEMU configure append:" $CONFIGURE_APPEND
 exec ./configure \
  --enable-werror \
+ --extra-ldflags=-Wl,--export-dynamic \
  --audio-drv-list=alsa \
  --disable-vnc \
  --disable-pie \
@@ -217,6 +218,7 @@ exec ./configure \
  --extra-cflags=-Wno-error=format-extra-args \
  --extra-cflags=-Wno-error=redundant-decls \
  --extra-ldflags=-Wl,--large-address-aware \
+ --extra-ldflags=-Wl,--export-all-symbols \
  --cc=gcc \
  --audio-drv-list=winwave \
  --enable-hax \
@@ -224,6 +226,7 @@ exec ./configure \
  $CONFIGURE_APPEND \
 ;;
 Darwin*)
+# FIXME: "-export_dynamic" causes error on old version clang
 cd ..
 echo ""
 echo "##### QEMU configuring for emulator"
@@ -238,5 +241,7 @@ echo "##### QEMU configure append:" $CONFIGURE_APPEND
  --disable-cocoa \
  --disable-sdl \
  $CONFIGURE_APPEND \
+
+# --extra-ldflags="-Xlinker -export_dynamic" \
 ;;
 esac
index 78ca6b3..97058f1 100644 (file)
@@ -337,6 +337,14 @@ ifdef CONFIG_DARWIN
                install_name_tool -change /opt/local/lib/libcurl.4.dylib @loader_path/libcurl.4.dylib $(DIBS_X86_DIR)/bin/emulator-x86 ;\
                install_name_tool -change /opt/local/lib/libpixman-1.0.dylib @loader_path/libpixman-1.0.dylib $(DIBS_X86_DIR)/bin/emulator-x86 ;\
                install_name_tool -change /opt/local/lib/libpng16.16.dylib @loader_path/libpng16.dylib $(DIBS_X86_DIR)/bin/emulator-x86; \
+ifdef CONFIG_QT
+               install_name_tool -change /opt/local/Library/Frameworks/QtQml.framework/Versions/5/QtQml @loader_path/QtQml $(DIBS_X86_DIR)/bin/emulator-x86; \
+               install_name_tool -change /opt/local/Library/Frameworks/QtNetwork.framework/Versions/5/QtNetwork @loader_path/QtNetwork $(DIBS_X86_DIR)/bin/emulator-x86; \
+               install_name_tool -change /opt/local/Library/Frameworks/QtOpenGL.framework/Versions/5/QtOpenGL @loader_path/QtOpenGL $(DIBS_X86_DIR)/bin/emulator-x86; \
+               install_name_tool -change /opt/local/Library/Frameworks/QtWidgets.framework/Versions/5/QtWidgets @loader_path/QtWidgets $(DIBS_X86_DIR)/bin/emulator-x86; \
+               install_name_tool -change /opt/local/Library/Frameworks/QtGui.framework/Versions/5/QtGui @loader_path/QtGui $(DIBS_X86_DIR)/bin/emulator-x86; \
+               install_name_tool -change /opt/local/Library/Frameworks/QtCore.framework/Versions/5/QtCore @loader_path/QtCore $(DIBS_X86_DIR)/bin/emulator-x86; \
+endif
                ;; \
        arm-softmmu) \
                ;; \
index c3127b7..14a547a 100644 (file)
@@ -8,6 +8,9 @@ obj-y += emulator.o emulator_legacy.o emulator_options.o emul_state.o
 # utils
 obj-y += util/
 
+# ui
+obj-y += ui/
+
 # maru display
 obj-y += display/
 
index 796f508..b8e49dc 100644 (file)
@@ -4,4 +4,9 @@ obj-$(CONFIG_USE_SHM) += maru_shm.o
 
 obj-$(CONFIG_SDL) += maru_sdl.o maru_sdl_processing.o maru_finger.o
 
+obj-$(CONFIG_QT) += qt5.o
+obj-$(CONFIG_QT) += qt5_supplement.o
+
 $(obj)/maru_display.o $(obj)/maru_sdl.o $(obj)/maru_sdl_processing.o $(obj)/maru_finger.o: QEMU_CFLAGS += $(SDL_CFLAGS)
+
+$(obj)/qt5_supplement.o: QEMU_CFLAGS += $(QT_CFLAGS)
index ddc34cd..b3aa9c2 100644 (file)
@@ -36,7 +36,7 @@
 
 MULTI_DEBUG_CHANNEL(tizen, display);
 
-MaruScreenShot* screenshot = NULL;
+MaruScreenShot *screenshot;
 
 static MaruDisplayChangeListener *mdcl;
 
@@ -53,16 +53,32 @@ static void maru_display_fini(void)
     g_free(mdcl);
 }
 
-static void maru_display_notify_exit(Notifier *notifier, void *data) {
+static void maru_display_notify_exit(Notifier *notifier, void *data)
+{
     maru_display_fini();
 }
+
 static Notifier maru_display_exit = { .notify = maru_display_notify_exit };
 
-void maru_display_init(DisplayState *ds, DisplayType display_type, int full_screen)
+void maru_display_early_init(DisplayType display_type)
+{
+    switch (display_type) {
+#ifdef CONFIG_QT
+    case DT_MARU_QT:
+        maru_qt5_display_early_init();
+        break;
+#endif
+    default:
+        break;
+    }
+}
+
+void maru_display_init(DisplayState *ds, DisplayType display_type,
+                       int full_screen)
 {
     INFO("init qemu display\n");
 
-    mdcl = g_malloc0(sizeof(MaruDisplayChangeListener));
+    mdcl = g_new0(MaruDisplayChangeListener, 1);
 
     switch (display_type) {
 #ifdef CONFIG_SDL
@@ -75,13 +91,18 @@ void maru_display_init(DisplayState *ds, DisplayType display_type, int full_scre
         maru_shm_pre_init(mdcl);
         break;
 #endif
+#ifdef CONFIG_QT
+    case DT_MARU_QT:
+        maru_qt5_display_init(mdcl, full_screen);
+        break;
+#endif
     default:
         ERR("can not enter here.\n");
-        // can not enter here...
+        /* can not enter here... */
         break;
     }
 
-    screenshot = g_malloc0(sizeof(MaruScreenShot));
+    screenshot = g_new0(MaruScreenShot, 1);
     screenshot->pixels = NULL;
     screenshot->request = false;
     screenshot->ready = false;
@@ -118,12 +139,13 @@ void maru_display_set_interpolation(bool on)
 }
 
 void maru_ds_surface_init(uint64 swt_handle,
-    unsigned int display_width, unsigned int display_height,
-    bool blank_guide)
+                          unsigned int display_width,
+                          unsigned int display_height,
+                          bool blank_guide)
 {
     if (mdcl->surface_init) {
         mdcl->surface_init(swt_handle, display_width,
-                display_height, blank_guide);
+                           display_height, blank_guide);
     }
 }
 
index 8c746f2..c58a4af 100644 (file)
@@ -52,7 +52,9 @@ typedef struct MaruScreenShot {
     bool ready;
 } MaruScreenShot;
 
-void maru_display_init(DisplayState *ds, DisplayType display_type, int full_screen);
+void maru_display_early_init(DisplayType display_type);
+void maru_display_init(DisplayState *ds, DisplayType display_type,
+                       int full_screen);
 void maru_display_resize(void);
 void maru_display_update(void);
 void maru_display_set_invalidate(bool on);
@@ -65,10 +67,16 @@ void maru_ds_surface_init(uint64 swt_handle,
 MaruScreenShot *get_screenshot(void);
 void save_screenshot(DisplaySurface *surface);
 
-// maru_sdl
+/* maru_sdl */
 void maru_sdl_pre_init(MaruDisplayChangeListener *mdcl);
 
-// maru_shm
+/* maru_shm */
 void maru_shm_pre_init(MaruDisplayChangeListener *mdcl);
 
+/* maru_qt */
+void maru_qt5_display_early_init(void);
+
+void maru_qt5_display_init(MaruDisplayChangeListener *mdcl, int full_screen);
+
+void maru_qt5_display_quit(void);
 #endif /* __MARU_DISPLAY_H__ */
index e628b5d..05b7943 100644 (file)
@@ -230,16 +230,6 @@ void init_multi_touch_state(void)
     mts->finger_point_surface = (void *)point;
 }
 
-void set_multi_touch_enable(int enable)
-{
-    get_emul_multi_touch_state()->multitouch_enable = enable;
-}
-
-int get_multi_touch_enable(void)
-{
-    return get_emul_multi_touch_state()->multitouch_enable;
-}
-
 int add_finger_point(int origin_x, int origin_y, int x, int y)
 {
     MultiTouchState *mts = get_emul_multi_touch_state();
index d5f071e..3815d3a 100644 (file)
@@ -62,8 +62,6 @@ typedef struct MultiTouchState {
 
 
 void init_multi_touch_state(void);
-void set_multi_touch_enable(int enable);
-int get_multi_touch_enable(void);
 FingerPoint *get_finger_point_from_slot(int index);
 FingerPoint *get_finger_point_search(int x, int y);
 int add_finger_point(int origin_x, int origin_y, int x, int y);
index 2b00794..ef7fc6d 100644 (file)
@@ -289,7 +289,6 @@ static void maru_shm_init(uint64 swt_handle,
     INFO("Memory attached at 0x%X\n", (int)shared_memory);
 }
 
-
 void maru_shm_pre_init(MaruDisplayChangeListener *mdcl)
 {
     dcl = g_malloc0(sizeof(DisplayChangeListener));
diff --git a/tizen/src/display/qt5.c b/tizen/src/display/qt5.c
new file mode 100644 (file)
index 0000000..495a17d
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * Sangho Park <sangho1206.park@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 "ui/console.h"
+#include "emul_state.h"
+#include "maru_display.h"
+#include "qt5_supplement.h"
+
+extern QemuMutex sdl_mutex;
+extern QemuCond sdl_cond;
+
+/* static Notifier mouse_mode_notifier; */
+static int qt5_num_outputs;
+
+static struct qt5_state {
+    DisplayChangeListener dcl;
+    DisplaySurface *surface;
+
+    int idx;
+} *qt5_console;
+
+void qt5_graphic_hw_invalidate(void)
+{
+    graphic_hw_invalidate(NULL);
+}
+
+int qt5_graphic_hw_display(void)
+{
+    console_ch_t displayed = 0;
+    graphic_hw_text_update(NULL, &displayed);
+    return displayed;
+}
+
+static void qt5_update(DisplayChangeListener *dcl,
+                       int x, int y, int w, int h)
+{
+    DisplaySurface *surf = qemu_console_surface(dcl->con);
+    if (!surf) {
+        return;
+    }
+
+    qt5_update_internal(surface_data(surf),
+                        surface_width(surf),
+                        surface_height(surf));
+}
+
+static void qt5_switch(DisplayChangeListener *dcl,
+                       DisplaySurface *new_surface)
+{
+}
+
+static void qt5_refresh(DisplayChangeListener *dcl)
+{
+    graphic_hw_update(dcl->con);
+    qt5_refresh_internal();
+}
+
+static void qt5_mouse_warp(DisplayChangeListener *dcl,
+                           int x, int y, int on)
+{
+}
+
+static void qt5_mouse_define(DisplayChangeListener *dcl,
+                             QEMUCursor *c)
+{
+}
+
+static const DisplayChangeListenerOps dcl_ops = {
+    .dpy_name          = "qt5",
+    .dpy_gfx_update    = qt5_update,
+    .dpy_gfx_switch    = qt5_switch,
+    .dpy_refresh       = qt5_refresh,
+    .dpy_mouse_set     = qt5_mouse_warp,
+    .dpy_cursor_define = qt5_mouse_define,
+};
+
+#ifdef CONFIG_DARWIN
+void ns_run_in_event_loop(void (*func)());
+void set_application_icon(char *path);
+#endif
+
+void maru_qt5_display_early_init(void)
+{
+#ifdef CONFIG_DARWIN
+    ns_run_in_event_loop(&qt5_early_prepare);
+
+    /* set emulator icon */
+#define ICON_RESOURCE_PATH "../icons/"
+#define ICON_FILE_NAME "emulator_icon.ico"
+    const int path_len = strlen(get_bin_path()) +
+        strlen(ICON_RESOURCE_PATH) + strlen(ICON_FILE_NAME) + 1;
+
+    char *icon_path = g_malloc0(sizeof(char) * path_len);
+    snprintf(icon_path, path_len, "%s%s%s",
+        get_bin_path(), ICON_RESOURCE_PATH, ICON_FILE_NAME);
+    fprintf(stdout, "application icon path : %s\n", icon_path);
+
+    set_application_icon(icon_path);
+    g_free(icon_path);
+#else
+    qt5_early_prepare();
+#endif
+}
+
+void maru_qt5_display_quit(void)
+{
+    qt5_destroy();
+
+    if (qt5_console) {
+        g_free(qt5_console);
+        qt5_console = NULL;
+    }
+}
+
+void maru_qt5_display_init(MaruDisplayChangeListener *mdcl, int full_screen)
+{
+    int i;
+
+#ifdef SDL_THREAD
+    qemu_mutex_init(&sdl_mutex);
+    qemu_cond_init(&sdl_cond);
+#endif
+
+    /* prepare gui */
+#ifdef CONFIG_DARWIN
+    ns_run_in_event_loop(&qt5_prepare);
+#else
+    qt5_prepare();
+#endif
+
+    for (i = 0;; i++) {
+        QemuConsole *con = qemu_console_lookup_by_index(i);
+        if (!con || !qemu_console_is_graphic(con)) {
+            break;
+        }
+    }
+    qt5_num_outputs = i;
+    qt5_console = g_new0(struct qt5_state, qt5_num_outputs);
+    for (i = 0; i < qt5_num_outputs; i++) {
+        QemuConsole *con = qemu_console_lookup_by_index(i);
+        qt5_console[i].dcl.ops = &dcl_ops;
+        qt5_console[i].dcl.con = con;
+        register_displaychangelistener(&qt5_console[i].dcl);
+        qt5_console[i].idx = i;
+    }
+    mdcl->fini = maru_qt5_display_quit;
+
+    if (full_screen) {
+        /* TODO */
+    }
+
+    /* TODO
+    mouse_mode_notifier.notify = qt2_mouse_mode_change;
+    qemu_add_mouse_mode_change_notifier(&mouse_mode_notifier);
+    */
+
+    /* TODO: cursor control */
+}
diff --git a/tizen/src/display/qt5_supplement.cpp b/tizen/src/display/qt5_supplement.cpp
new file mode 100644 (file)
index 0000000..34906e1
--- /dev/null
@@ -0,0 +1,546 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * Sangho Park <sangho1206.park@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 <QApplication>
+#include <QQmlComponent>
+#include <QQmlEngine>
+#include <QQmlProperty>
+
+#include "qt5_supplement.h"
+#include "mainwindow.h"
+#include "uiinformation.h"
+#include "hardwarekey.h"
+#include "floatingcontroller.h"
+#include "ui/xml/emulatoruitype.h"
+#include "uiutil.h"
+
+extern "C" {
+#include "emul_state.h"
+}
+
+//using namespace std;
+void qMessageOutput(QtMsgType, const QMessageLogContext &, const QString &);
+void loadMainFormFromXML(QFile *, UIInformation *);
+void loadConFormFromXML(QFile *, UIInformation *);
+
+QApplication *qt5App = NULL;
+
+static int argc = 0;
+static char *argv[0];
+
+static void *captureRequestListener;
+static void (*captureRequestHandler)(void *);
+
+static MainWindow *mainwindow;
+static UIInformation *uiInfo;
+
+#define SKIN_PROPERTIES_FILE_NAME ".skin.properties"
+#define SKIN_PROPERTY_WINDOW_X "window.x"
+#define SKIN_PROPERTY_WINDOW_Y "window.y"
+#define SKIN_PROPERTY_WINDOW_SCALE "window.scale"
+#define SKIN_PROPERTY_WINDOW_TOPMOST "window.ontop"
+#define SKIN_PROPERTY_CONTROLLER_INDEX "controller.index"
+#define SKIN_PROPERTY_CONTROLLER_DOCK "controller.dock"
+
+#define SKIN_INFO_FILE_NAME "info.ini"
+#define FORM_FILE_NAME "layout.qml"
+#define CON_FORM_SUBPATH "controller"
+
+class ConFile {
+public:
+    QFile *formFile;
+    int priority;
+};
+
+void qt5_gui_init(void)
+{
+    QCoreApplication::setApplicationName("Tizen Emulator");
+
+    qDebug() << "* Qt version :" << QT_VERSION_STR;
+    qDebug() << "* working path :" << QDir::currentPath();
+    qDebug() << "* binary path :" << QCoreApplication::applicationDirPath();
+
+    uiInfo = new UIInformation();
+
+    /* parameter parsing */
+    // TODO:
+
+    uiInfo->vmName = QString(get_emul_vm_name()).trimmed();
+    uiInfo->resolution.setWidth(get_emul_resolution_width());
+    uiInfo->resolution.setHeight(get_emul_resolution_height());
+    uiInfo->basePort = get_emul_vm_base_port();
+
+    uiInfo->vmDataPath = get_emul_vm_data_path();
+    if (uiInfo->vmDataPath.endsWith(QDir::separator()) == false) {
+        uiInfo->vmDataPath += QDir::separator();
+    }
+
+    uiInfo->skinPath = QDir(get_emul_skin_path()).canonicalPath();
+    if (uiInfo->skinPath.endsWith(QDir::separator()) == false) {
+        uiInfo->skinPath += QDir::separator();
+    }
+
+    /* read skin information */
+    QSettings skinInfo(uiInfo->skinPath + SKIN_INFO_FILE_NAME,
+        QSettings::IniFormat);
+    QString skinName = skinInfo.value("skin.name").toString();
+    if (skinName.isEmpty() == true) {
+        skinName = "Undefined";
+    }
+    uiInfo->skinName = skinName;
+
+    /* read MRU information */
+    QSettings mruInfo(uiInfo->vmDataPath + SKIN_PROPERTIES_FILE_NAME,
+        QSettings::IniFormat);
+    int scale = mruInfo.value(SKIN_PROPERTY_WINDOW_SCALE).toInt();
+    qDebug("previous scale value is %d", scale);
+
+    if (scale <= 0) {
+        scale = 50; /* default scale */
+    }
+    uiInfo->uiState.mainFormScale = scale;
+
+    /* XML */
+    // TODO: convert QML to XML
+
+    /* Register custom QML elements */
+    qmlRegisterType<RegionType>("EmulatorComponent", 1, 0, "Region");
+    qmlRegisterType<HardwareKeyType>("EmulatorComponent", 1, 0, "Key");
+    qmlRegisterType<KeyListType>("EmulatorComponent", 1, 0, "KeyList");
+
+    /* load main form */
+    QFile mainXMLFile(uiInfo->skinPath + FORM_FILE_NAME);
+    loadMainFormFromXML(&mainXMLFile, uiInfo);
+
+    /* load controller forms */
+    QDir skinDir(uiInfo->skinPath + CON_FORM_SUBPATH);
+    QFileInfoList entries = skinDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
+
+    if (entries.isEmpty() == false) {
+        /* sort by priority */
+        QList<ConFile *> conFileList;
+
+        for (int i = 0; i < entries.size(); i++) {
+            ConFile *conFile = new ConFile();
+
+            QString conPath = entries.at(i).filePath() + QDir::separator();
+            conFile->formFile = new QFile(conPath + FORM_FILE_NAME);
+            QSettings conInfo(conPath + SKIN_INFO_FILE_NAME, QSettings::IniFormat);
+            conFile->priority = conInfo.value("priority").toInt();
+
+            int j = 0;
+            for ( ; j < conFileList.size(); j++) {
+                if (conFileList.at(j)->priority > conFile->priority) {
+                    break;
+                }
+            }
+            conFileList.insert(j, conFile);
+        }
+
+        /* loading */
+        for (int i = 0; i < conFileList.size(); i++) {
+            loadConFormFromXML(conFileList.at(i)->formFile, uiInfo);
+            delete conFileList.at(i)->formFile;
+            delete conFileList.at(i);
+        }
+    }
+
+    /* GUI */
+    qDebug("start!");
+
+    mainwindow = new MainWindow(uiInfo);
+    mainwindow->setCaptureRequestHandler(captureRequestListener, captureRequestHandler);
+
+    /* position */
+    QRect hostBounds = UIUtil::getHostScreenBounds();
+    qDebug() << "host geometry : " << hostBounds;
+
+    int defaultValueX = hostBounds.x() - 1;
+    int defaultValueY = hostBounds.y() - 1;
+    int xx = mruInfo.value(SKIN_PROPERTY_WINDOW_X, defaultValueX).toInt();
+    int yy = mruInfo.value(SKIN_PROPERTY_WINDOW_Y, defaultValueY).toInt();
+
+    if (xx == defaultValueX || yy == defaultValueY) {
+        xx = yy = 80 + (uiInfo->basePort % 100); /* default position */
+    } else {
+        qDebug("previous position value : (%d, %d)", xx, yy);
+
+        xx = qMax(xx, hostBounds.x());
+        xx = qMin(xx, hostBounds.x() + hostBounds.width() - 100);
+        yy = qMax(yy, hostBounds.y());
+        yy = qMin(yy, hostBounds.y() + hostBounds.height() - 100);
+    }
+
+    mainwindow->move(xx, yy);
+    qDebug("current position value : (%d, %d)", xx, yy);
+
+    bool onTop = mruInfo.value(SKIN_PROPERTY_WINDOW_TOPMOST).toBool();
+    if (onTop == true) {
+        mainwindow->setTopMost(true);
+    }
+
+    mainwindow->show();
+
+    /* controller */
+    const int defaultDockPos = Qt::AlignRight | Qt::AlignCenter;
+    mainwindow->getUIState()->conState.recentlyDockPos = defaultDockPos;
+
+    int conIndex = mruInfo.value(SKIN_PROPERTY_CONTROLLER_INDEX).toInt();
+    if (conIndex >= 0 && conIndex < uiInfo->conFormList.count()) {
+        int conDockPos = mruInfo.value(SKIN_PROPERTY_CONTROLLER_DOCK).toInt();
+        if (conDockPos <= 0) {
+            conDockPos = defaultDockPos;
+        }
+
+        mainwindow->openController(conIndex, conDockPos);
+    }
+
+    mainwindow->startSwapper();
+}
+
+void qt5_destroy()
+{
+    qDebug("qt5 destroy");
+
+    /* write MRU information */
+    QSettings mruInfo(uiInfo->vmDataPath + SKIN_PROPERTIES_FILE_NAME,
+        QSettings::IniFormat);
+    mruInfo.setValue(SKIN_PROPERTY_WINDOW_X, mainwindow->pos().x());
+    mruInfo.setValue(SKIN_PROPERTY_WINDOW_Y, mainwindow->pos().y());
+    mruInfo.setValue(SKIN_PROPERTY_WINDOW_SCALE, uiInfo->uiState.mainFormScale);
+    mruInfo.setValue(SKIN_PROPERTY_WINDOW_TOPMOST, uiInfo->uiState.isOnTop());
+    mruInfo.setValue(SKIN_PROPERTY_CONTROLLER_INDEX, uiInfo->uiState.conState.conFormIndex);
+
+    DockingController *con = uiInfo->uiState.conState.dockingCon;
+    if (con != NULL) {
+        mruInfo.setValue(SKIN_PROPERTY_CONTROLLER_DOCK, con->getDockPos());
+    } else {
+        mruInfo.setValue(SKIN_PROPERTY_CONTROLLER_DOCK, 0);
+    }
+
+    /* clean up */
+    mainwindow->terminateSwapper();
+
+    mainwindow->closeController();
+
+    /* TODO : destroy mainwindow and qt5App */
+
+    delete uiInfo;
+}
+
+void qt5_early_prepare(void)
+{
+    Q_INIT_RESOURCE(resource);
+    qInstallMessageHandler(qMessageOutput);
+
+#ifdef CONFIG_DARWIN
+#define LIBQCOCOA "libqcocoa.dylib"
+    /* load libqcocoa.dylib */
+    QStringList libPaths = QCoreApplication::libraryPaths();
+    qDebug() << "default Qt plugin library path : " << libPaths;
+
+    int i = 0;
+    for ( ; i < libPaths.count(); i++) {
+        QFileInfo libFileInfo(libPaths.at(i) + QDir::separator() +
+            "platforms" + QDir::separator() + LIBQCOCOA);
+        if (libFileInfo.exists() == true) {
+            break;
+        }
+    }
+
+    if (i >= libPaths.count()) {
+        qDebug() << LIBQCOCOA << " file not found. " <<
+            "Qt plugin library path is converted to current path.";
+        QCoreApplication::setLibraryPaths(QStringList(QDir::currentPath()));
+    }
+#endif
+
+    qt5App = new QApplication(argc, argv);
+}
+
+void qt5_prepare(void)
+{
+    qt5_gui_init();
+}
+
+void qt5_update_internal(void *data, int width, int height)
+{
+    QPixmap pixmap = QPixmap();
+    QLabel *screenWidget = mainwindow->getScreenWidget();
+
+    /*
+     * TODO: support rotation.
+     */
+
+    QImage image = QImage((uchar *)data, width, height, QImage::Format_RGB32);
+    pixmap.convertFromImage(image);
+    screenWidget->setPixmap(pixmap.scaled(screenWidget->size(),
+        Qt::KeepAspectRatio, Qt::SmoothTransformation));
+}
+
+void qt5_switch_internal(void)
+{
+}
+
+void qt5_refresh_internal(void)
+{
+    qt5App->processEvents();
+}
+
+void qt5_register_capture_request_listener(void *listener, void (*handler)(void *))
+{
+    if (mainwindow) {
+        mainwindow->setCaptureRequestHandler(listener, handler);
+    }
+
+    captureRequestListener = listener;
+    captureRequestHandler = handler;
+}
+
+void qt5_unregister_capture_request_listener(void *listener)
+{
+    if (mainwindow) {
+        mainwindow->unsetCaptureRequestHandler(listener);
+    }
+
+    captureRequestListener = NULL;
+    captureRequestHandler = NULL;
+}
+
+void qt5_process_captured(bool captured, void *pixels, int width, int height)
+{
+    if (mainwindow) {
+        mainwindow->processCaptured(captured, pixels, width, height);
+    }
+}
+
+void qMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
+{
+    QByteArray localMsg = msg.toLocal8Bit();
+    QByteArray dateMsg = QDateTime::currentDateTime().toString("hh:mm:ss").toLocal8Bit();
+
+    switch (type) {
+    case QtDebugMsg:
+        fprintf(stdout, "%s [Debug:%s:%u] %s\n", dateMsg.constData(),
+            context.category, context.line, localMsg.trimmed().constData());
+        break;
+    case QtWarningMsg:
+        fprintf(stdout, "%s [Warning:%s:%u] %s\n", dateMsg.constData(),
+            context.category, context.line, localMsg.trimmed().constData());
+        break;
+    case QtCriticalMsg:
+        fprintf(stderr, "%s [Critical:%s:%u] %s\n", dateMsg.constData(),
+            context.category, context.line, localMsg.trimmed().constData());
+        break;
+    case QtFatalMsg:
+        fprintf(stderr, "%s [Fatal:%s:%u] %s\n", dateMsg.constData(),
+            context.category, context.line, localMsg.trimmed().constData());
+
+        QString err;
+        QMessageBox::critical(0, "Emulator",
+                              QString("An internal error occurred.\n: ") +
+                              err.sprintf("%s", (localMsg.trimmed()).constData()) +
+                              "\n\nEmulator will now exit.");
+        abort();
+    }
+}
+
+void loadMainFormFromXML(QFile *file, UIInformation *uiInfo/* out */)
+{
+    if (file->exists() == false) {
+        qFatal("%s is not found", qPrintable(file->fileName()));
+    }
+
+    qDebug("main form is loaded from %s", qPrintable(file->fileName()));
+
+    qmlRegisterType<EmulatorUIType>("EmulatorComponent", 1, 0, "EmulatorUI");
+    qmlRegisterType<FormListType>("EmulatorComponent", 1, 0, "FormList");
+    qmlRegisterType<FormType>("EmulatorComponent", 1, 0, "Form");
+
+    /* QML */
+    QQmlEngine *engine = new QQmlEngine();
+    QQmlComponent *component = new QQmlComponent(engine);
+
+    component->loadUrl(QUrl::fromLocalFile(file->fileName()));
+    if (!component->isReady()) {
+        qWarning("%s", qPrintable(component->errorString()));
+    }
+
+    QObject *object = component->create();
+    if (object != NULL) {
+        QFileInfo fileInfo(*file);
+        qDebug() << "xml version :" << QQmlProperty::read(object, "version").toString();
+
+        EmulatorUIType *uiType = (EmulatorUIType *)object;
+        FormType *formType = NULL;
+        KeyListType *keyListType = NULL;
+        HardwareKeyType *hwKeyType = NULL;
+
+        FormListType *formListType = uiType->formListType();
+        for (int index = 0; index < formListType->getFormList()->count(); index++) {
+            MainForm *mainForm = new MainForm(); /* dst */
+
+            formType = (FormType *)formListType->getFormList()->at(index); /* src */
+
+            mainForm->displayRegion = formType->getDisplayRegion();
+            mainForm->skinImg[MainForm::normal].load(fileInfo.absolutePath()
+                + QDir::separator() + formType->mainImageName());
+            mainForm->skinImg[MainForm::pressed].load(fileInfo.absolutePath()
+                + QDir::separator() + formType->pressedImageName());
+
+            keyListType = formType->keyListType();
+            if (keyListType != NULL) {
+                for (int i = 0; i < keyListType->getKeyList()->count(); i++) {
+                    hwKeyType = keyListType->getKeyList()->at(i);
+                    if (hwKeyType != NULL) {
+                        mainForm->keyList.append(new HardwareKey(hwKeyType->objectName(),
+                            hwKeyType->keycode(), hwKeyType->region(), hwKeyType->tooltip()));
+                    }
+                }
+            }
+
+            uiInfo->mainFormList.append(mainForm);
+        }
+
+        delete object;
+    }
+
+    delete component;
+    delete engine;
+}
+
+void loadConFormFromXML(QFile *file, UIInformation *uiInfo/* out */)
+{
+    if (file->exists() == false) {
+        qWarning("%s is not found", qPrintable(file->fileName()));
+        return;
+    }
+
+    qDebug("controller form is loaded from %s", qPrintable(file->fileName()));
+
+    /* QML */
+    QQmlEngine *engine = new QQmlEngine();
+    QQmlComponent *component = new QQmlComponent(engine);
+
+    component->loadUrl(QUrl::fromLocalFile(file->fileName()));
+    if (!component->isReady()) {
+        qWarning("%s", qPrintable(component->errorString()));
+    }
+
+    QObject *object = component->create();
+    if (object != NULL) {
+        QFileInfo fileInfo(*file);
+        qDebug() << "xml version :" << QQmlProperty::read(object, "version").toString();
+
+        FormType *formType = (FormType *)object;
+        KeyListType *keyListType = NULL;
+        HardwareKeyType *hwKeyType = NULL;
+
+        QString conName = QQmlProperty::read(object, "name").toString();
+        ControllerForm *conForm = new ControllerForm(
+            conName.isEmpty() ? fileInfo.dir().dirName() : conName);
+
+        conForm->conImg[ControllerForm::normal].load(fileInfo.absolutePath()
+            + QDir::separator() + formType->mainImageName());
+        conForm->conImg[ControllerForm::pressed].load(fileInfo.absolutePath()
+            + QDir::separator() + formType->pressedImageName());
+
+        keyListType = formType->keyListType();
+        if (keyListType != NULL) {
+            for (int i = 0; i < keyListType->getKeyList()->count(); i++) {
+                hwKeyType = keyListType->getKeyList()->at(i);
+                if (hwKeyType != NULL) {
+                    conForm->keyList.append(new HardwareKey(hwKeyType->objectName(),
+                        hwKeyType->keycode(), hwKeyType->region(), hwKeyType->tooltip()));
+                }
+            }
+        }
+
+        uiInfo->conFormList.append(conForm);
+
+        delete object;
+    }
+
+    delete component;
+    delete engine;
+}
+
+#if 0
+#define CONTROL_PRIORITY_MAX 10
+
+int getControlIndex()
+{
+    int controlIndex = 0;
+    int controlPriority = 0;
+    int priority = CONTROL_PRIORITY_MAX;
+
+    if (!uiInfo) {
+        return controlIndex;
+    }
+
+    /* find high priority*/
+    QString line;
+    QDir skinDir(uiInfo->skinPath + CON_FORM_SUBPATH);
+    QFileInfoList entries = skinDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
+    for (int i = 0; i < entries.size(); i++) {
+        QFile iniFile(entries.at(i).filePath() + QDir::separator() + "info.ini");
+        if (iniFile.exists()) {
+            controlPriority = getPriority(&iniFile);
+            if (controlPriority < priority) {
+                controlIndex = i;
+                priority = controlPriority;
+            }
+        }
+    }
+
+    return controlIndex;
+}
+
+int getPriority(QFile *file)
+{
+    int priority = CONTROL_PRIORITY_MAX;
+    QRegExp rx("=");
+
+    /* read priority in info.ini file */
+    if (file->open(QFile::ReadOnly)) {
+        QTextStream in(file);
+        do {
+            QString line = in.readLine();
+            QStringList list = line.split(rx, QString::SkipEmptyParts);
+            if (QString::compare(list.at(0), "priority",  Qt::CaseInsensitive) == 0) {
+                priority = list.at(1).toInt();
+            }
+        } while(!in.atEnd());
+        file->close();
+    }
+
+    return priority;
+}
+#endif
diff --git a/tizen/src/display/qt5_supplement.h b/tizen/src/display/qt5_supplement.h
new file mode 100644 (file)
index 0000000..74b96a8
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * Sangho Park <sangho1206.park@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 __QT5_INTERNAL_H__
+#define __QT5_INTERNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void qt5_graphic_hw_invalidate(void);
+int qt5_graphic_hw_display(void);
+void qt5_early_prepare(void);
+void qt5_prepare(void);
+void qt5_destroy(void);
+
+void qt5_update_internal(void *data, int width, int height);
+void qt5_switch_internal(void);
+void qt5_refresh_internal(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __QT5_INTERNAL_H__
index 1d9e4c6..21dbe7c 100644 (file)
 
 #if defined(CONFIG_LINUX)
 #include <X11/XKBlib.h>
-#elif defined (CONFIG_WIN32)
+extern bool kvm_allowed;
+#elif defined(CONFIG_WIN32)
 #include <windows.h>
+extern bool hax_allowed;
+#elif defined(CONFIG_DARWIN)
+extern bool hax_allowed;
 #endif
 
 DECLARE_DEBUG_CHANNEL(emul_state);
@@ -321,6 +325,16 @@ MultiTouchState *get_emul_multi_touch_state(void)
     return &(_emul_state.qemu_mts);
 }
 
+void set_multi_touch_enable(int enable)
+{
+    _emul_state.qemu_mts.multitouch_enable = enable;
+}
+
+int get_multi_touch_enable(void)
+{
+    return _emul_state.qemu_mts.multitouch_enable;
+}
+
 /* retrieves the status of the host lock key */
 int get_host_lock_key_state(int key)
 {
@@ -457,3 +471,71 @@ bool get_sdb_connection(void)
     return _emul_state.sdb_connection;
 }
 
+/* emualtor skin path */
+void set_emul_skin_path(char *path)
+{
+    _emul_info.skin_path = path;
+
+    LOG_INFO("skin path : %s\n", _emul_info.skin_path);
+}
+
+char* get_emul_skin_path(void)
+{
+    return _emul_info.skin_path;
+}
+
+/* GPU virtualization */
+void set_emul_gpu_accel(bool enable)
+{
+    _emul_info.gpu_accel_enable = enable;
+}
+
+bool get_emul_gpu_accel(void)
+{
+    return _emul_info.gpu_accel_enable;
+}
+
+/* CPU virtualization */
+bool get_emul_cpu_accel(void)
+{
+#ifdef CONFIG_LINUX
+    return kvm_allowed;
+#else
+    return hax_allowed;
+#endif
+
+    return false;
+}
+
+/* VM ram size */
+void set_emul_ram_size(const char *size)
+{
+    _emul_info.vm_ram_size = size;
+}
+
+const char* get_emul_ram_size(void)
+{
+    return _emul_info.vm_ram_size;
+}
+
+/* file sharing path */
+void set_emul_file_sharing_path(const char *path)
+{
+    _emul_info.file_sharing_path = path;
+}
+
+const char* get_emul_file_sharing_path(void)
+{
+    return _emul_info.file_sharing_path;
+}
+
+/* VM data path */
+void set_emul_vm_data_path(const char *path)
+{
+    _emul_info.vm_data_path = path;
+}
+
+const char* get_emul_vm_data_path(void)
+{
+    return _emul_info.vm_data_path;
+}
index 904f269..88ef3c7 100644 (file)
@@ -103,8 +103,13 @@ typedef  struct EmulatorConfigInfo {
     int spice_port;
     int websocket_port;
     char *vm_name;
-    /* add here */
+    char *skin_path;
+    bool gpu_accel_enable;
+    const char *file_sharing_path;
+    const char *vm_ram_size;
     int serial_port;
+    const char *vm_data_path;
+    /* add here */
 } EmulatorConfigInfo;
 
 typedef struct EmulatorConfigState {
@@ -146,6 +151,11 @@ void set_emul_vm_base_port(int port);
 void set_emul_ecs_port(int port);
 void set_emul_guest_ip(char *ip);
 void set_emul_vm_name(char *vm_name);
+void set_emul_skin_path(char *path);
+void set_emul_gpu_accel(bool enable);
+void set_emul_file_sharing_path(const char *path);
+void set_emul_ram_size(const char *size);
+void set_emul_vm_data_path(const char *path);
 
 void set_emulator_condition(int state);
 void set_emul_rotation(short rotation_type);
@@ -175,10 +185,15 @@ int get_emul_serial_port(void);
 char* get_emul_vm_name(void);
 int get_emul_spice_port(void);
 int get_emul_websocket_port(void);
+char* get_emul_skin_path(void);
+bool get_emul_gpu_accel(void);
+bool get_emul_cpu_accel(void);
+const char* get_emul_file_sharing_path(void);
+const char* get_emul_ram_size(void);
+const char* get_emul_vm_data_path(void);
 
 int get_emulator_condition(void);
 short get_emul_rotation(void);
-MultiTouchState *get_emul_multi_touch_state(void);
 int get_host_lock_key_state(int key);
 int get_host_lock_key_state_darwin(int key);
 int get_emul_caps_lock_state(void);
@@ -193,4 +208,9 @@ char* get_emul_profile(void);
 bool get_emuld_connection(void);
 bool get_sdb_connection(void);
 
+/* multi-touch */
+MultiTouchState *get_emul_multi_touch_state(void);
+void set_multi_touch_enable(int enable);
+int get_multi_touch_enable(void);
+
 #endif /* __EMUL_STATE_H__ */
index 14642f6..5b6ff90 100644 (file)
@@ -279,7 +279,7 @@ static int emulator_main(int argc, char *argv[], char **envp)
     }
 #endif
 
-#ifdef CONFIG_WIN32
+#if defined(CONFIG_WIN32) && defined(CONFIG_SDL)
     // SDL_init() routes stdout and stderr to the respective files in win32.
     // So we revert it.
     freopen("CON", "w", stdout);
@@ -395,7 +395,7 @@ static int emulator_main(int argc, char *argv[], char **envp)
     return 0;
 }
 
-#ifdef CONFIG_DARWIN
+#if defined(CONFIG_DARWIN) && !defined(CONFIG_QT)
 int g_argc;
 
 static void* main_thread(void* args)
@@ -430,7 +430,9 @@ int main(int argc, char *argv[], char **envp)
 #else // WIN32
 int main(int argc, char *argv[])
 {
+#ifndef CONFIG_DARWIN
     maru_register_exception_handler();
+#endif
     return emulator_main(argc, argv, NULL);
 }
 #endif
index 5786038..0bbb00c 100644 (file)
@@ -64,6 +64,7 @@ MULTI_DEBUG_CHANNEL(qemu, main);
 #define LOGFILE             "emulator.log"
 #define DISPLAY_WIDTH_PREFIX "width="
 #define DISPLAY_HEIGHT_PREFIX "height="
+#define SKIN_PATH_PREFIX "skin.path="
 #define INPUT_TOUCH_PARAMETER "virtio-touchscreen-pci"
 
 #define MIDBUF  128
@@ -142,7 +143,9 @@ static void set_image_and_log_path(char *qemu_argv)
         strcpy(tizen_target_path, g_path_get_dirname(path));
     }
 
+    set_emul_vm_data_path(tizen_target_path);
     set_emul_vm_name(g_path_get_basename(tizen_target_path));
+
     strcpy(tizen_target_img_path, path);
     free(path);
 
@@ -232,11 +235,14 @@ static void extract_skin_info(int skin_argc, char **skin_argv)
             h = atoi(height_arg);
 
             INFO("display height option : %d\n", h);
+        } else if (strstr(skin_argv[i], SKIN_PATH_PREFIX) != NULL) {
+            char *path = skin_argv[i] + strlen(SKIN_PATH_PREFIX);
+
+            set_emul_skin_path(path);
         }
 
         if (w != 0 && h != 0) {
             set_emul_resolution(w, h);
-            break;
         }
     }
 }
index 54655c9..e277ee4 100644 (file)
@@ -3,4 +3,8 @@
 
 void ns_event_loop(int* keepRunning);
 
+void ns_run_in_event_loop(void (*func)());
+
+void set_application_icon(char *path);
+
 #endif /* _NS_EVENT_H_ */
index 69928df..62a097c 100644 (file)
@@ -13,3 +13,35 @@ void ns_event_loop(int* keepRunning)
     while (*keepRunning && [theRunLoop runMode:NSDefaultRunLoopMode beforeDate:distantFuture]);
     // return [[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 1]];
 }
+
+@interface Runner : NSObject
+{
+    @public void (*func)();
+}
+- (void)run;
+@end
+
+@implementation Runner
+- (void)run;
+{
+    self->func();
+}
+@end
+
+void ns_run_in_event_loop(void (*func)())
+{
+    Runner *runner = [[Runner alloc] init];
+    runner->func = func;
+    [runner performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:YES];
+    [runner release];
+}
+
+void set_application_icon(char *path)
+{
+    NSString *iconPath = [[NSString alloc] initWithUTF8String:path];
+    NSImage *iconImage = [[NSImage alloc] initWithContentsOfFile:iconPath];
+    [[NSApplication sharedApplication] setApplicationIconImage:iconImage];
+
+    [iconImage release];
+    [iconPath release];
+}
index 96f9719..77beb63 100644 (file)
@@ -85,7 +85,6 @@ enum JAVA_KEYCODE {
     JAVA_KEY_DELETE = 127
 };
 
-
 #define KEY_MAX 0777
 
 #define KEY_F0 0410
@@ -102,8 +101,9 @@ enum JAVA_KEYCODE {
 
 #define KEY_BTAB 0541
 
-
 #define SHIFT 0
+
+/* for Java skin*/
 static const int vkkey2scancode[KEY_MAX] = {
     [0 ... (KEY_MAX - 1)] = -1,
 
index 0d5378c..6d255c8 100644 (file)
@@ -185,6 +185,21 @@ void do_mouse_event(int button_type, int event_type,
     }
 }
 
+void do_qt_keyboard_key_event(int event_type, int keycode) {
+    if (is_host_keyboard_attached() == false) {
+        TRACE("ignore key event because keyboard device was dettached\n");
+        return;
+    }
+
+    if (KEY_PRESSED == event_type) {
+        TRACE("key pressed: %d\n", keycode);
+        virtio_keyboard_event(keycode);
+    } else if (KEY_RELEASED == event_type) {
+        TRACE("key released: %d\n", keycode);
+        virtio_keyboard_event(keycode | 0x80);
+    }
+}
+
 void do_keyboard_key_event(int event_type,
     int keycode, int state_mask, int key_location)
 {
index b434f6c..d4470f9 100644 (file)
@@ -51,6 +51,7 @@ void start_display(uint64_t handle_id,
 void do_grabbing_enable(bool on);
 void do_mouse_event(int button_type, int event_type,
     int origin_x, int origin_y, int x, int y, int z);
+void do_qt_keyboard_key_event(int event_type, int keycode);
 void do_keyboard_key_event(int event_type,
     int keycode, int state_mask, int key_location);
 void do_hw_key_event(int event_type, int keycode);
index fcc7b8d..359028e 100644 (file)
@@ -132,7 +132,6 @@ static uint16_t svr_port = 0;
 static int server_sock = 0;
 static int client_sock = 0;
 static int stop_server = 0;
-static int is_sdbd_initialized = 0;
 static int ready_server = 0;
 static int ignore_heartbeat = 0;
 static int is_force_close_client = 0;
@@ -141,6 +140,8 @@ static int is_started_heartbeat = 0;
 static int stop_heartbeat = 0;
 static int recv_heartbeat_count = 0;
 
+int is_sdbd_initialized = 0;
+
 /* 0: not drawing, 1: drawing */
 int draw_display_state = 0;
 
index 0db67fc..5d0a4c1 100644 (file)
@@ -30,6 +30,8 @@
 #ifndef MARUSKIN_SERVER_H_
 #define MARUSKIN_SERVER_H_
 
+extern int is_sdbd_initialized;
+
 int start_skin_server(int argc, char** argv, int qemu_argc, char** qemu_argv);
 
 void notify_draw_frame(void);
diff --git a/tizen/src/ui/Makefile.objs b/tizen/src/ui/Makefile.objs
new file mode 100644 (file)
index 0000000..417087e
--- /dev/null
@@ -0,0 +1,49 @@
+TIZEN_UI = $(SRC_PATH)/tizen/src/ui
+QEMU_CFLAGS += $(QT_CFLAGS) -I$(TIZEN_UI)
+
+$(obj)/qrc_resource.o: $(obj)/qrc_resource.cpp
+$(obj)/qrc_resource.cpp: $(TIZEN_UI)/resource/resource.qrc
+       rcc -name resource $< -o $@
+
+obj-$(CONFIG_QT) += controllerform.o
+obj-$(CONFIG_QT) += dockingcontroller.o moc_dockingcontroller.o
+obj-$(CONFIG_QT) += dockingconview.o
+obj-$(CONFIG_QT) += floatingcontroller.o moc_floatingcontroller.o
+obj-$(CONFIG_QT) += floatingconview.o
+obj-$(CONFIG_QT) += displaybase.o
+obj-$(CONFIG_QT) += displayglwidget.o moc_displayglwidget.o
+obj-$(CONFIG_QT) += displayswwidget.o moc_displayswwidget.o
+obj-$(CONFIG_QT) += hardwarekey.o
+obj-$(CONFIG_QT) += mainwindow.o moc_mainwindow.o
+obj-$(CONFIG_QT) += skinbezelitem.o
+obj-$(CONFIG_QT) += skinkeyitem.o moc_skinkeyitem.o
+obj-$(CONFIG_QT) += mainform.o
+obj-$(CONFIG_QT) += keyboardhelper.o
+obj-$(CONFIG_QT) += skinview.o
+obj-$(CONFIG_QT) += uiinformation.o
+obj-$(CONFIG_QT) += uistate.o
+obj-$(CONFIG_QT) += uiutil.o
+obj-$(CONFIG_QT) += qrc_resource.o
+
+obj-$(CONFIG_QT) += xml/
+
+obj-$(CONFIG_QT) += menu/
+
+$(obj)/moc_dockingcontroller.o: $(obj)/moc_dockingcontroller.cpp
+$(obj)/moc_dockingcontroller.cpp: $(obj)/dockingcontroller.h
+       moc $< -o $@
+$(obj)/moc_floatingcontroller.o: $(obj)/moc_floatingcontroller.cpp
+$(obj)/moc_floatingcontroller.cpp: $(obj)/floatingcontroller.h
+       moc $< -o $@
+$(obj)/moc_displayglwidget.o: $(obj)/moc_displayglwidget.cpp
+$(obj)/moc_displayglwidget.cpp: $(obj)/displayglwidget.h
+       moc $< -o $@
+$(obj)/moc_displayswwidget.o: $(obj)/moc_displayswwidget.cpp
+$(obj)/moc_displayswwidget.cpp: $(obj)/displayswwidget.h
+       moc $< -o $@
+$(obj)/moc_mainwindow.o: $(obj)/moc_mainwindow.cpp
+$(obj)/moc_mainwindow.cpp: $(obj)/mainwindow.h
+       moc $< -o $@
+$(obj)/moc_skinkeyitem.o: $(obj)/moc_skinkeyitem.cpp
+$(obj)/moc_skinkeyitem.cpp: $(obj)/skinkeyitem.h
+       moc $< -o $@
diff --git a/tizen/src/ui/controllerform.cpp b/tizen/src/ui/controllerform.cpp
new file mode 100644 (file)
index 0000000..808d119
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "controllerform.h"
+
+ControllerForm::ControllerForm(QString name)
+{
+    this->name = name;
+}
+
+ControllerForm::~ControllerForm()
+{
+    qDebug("destroy con layout");
+}
diff --git a/tizen/src/ui/controllerform.h b/tizen/src/ui/controllerform.h
new file mode 100644 (file)
index 0000000..02c9b73
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 CONTROLLERFORM_H
+#define CONTROLLERFORM_H
+
+#include <QWidget>
+
+#include "hardwarekey.h"
+
+class ControllerForm
+{
+    Q_ENUMS(ConImgType)
+
+public:
+    ControllerForm(QString name);
+    ~ControllerForm();
+
+    QString name;
+    QImage conImg[2];
+    QList<HardwareKey *> keyList;
+
+    enum ConImgType {
+        normal = 0,
+        pressed = 1
+    };
+};
+
+#endif // CONTROLLERFORM_H
diff --git a/tizen/src/ui/displaybase.cpp b/tizen/src/ui/displaybase.cpp
new file mode 100644 (file)
index 0000000..344a165
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@samsung.com>
+ * Stanislav Vorobiov
+ *
+ * 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 "displaybase.h"
+#include "mainwindow.h"
+
+uint32_t qt5_window_width = 0;
+uint32_t qt5_window_height = 0;
+int qt5_window_angle = 0;
+
+DisplayBase::DisplayBase(QSize resolution, QWidget *w)
+: resolution(resolution),
+  widget(w),
+  isDragging(false)
+{
+    /* initialize */
+    // TODO: compare display region with resolution
+
+    MainWindow *win = ((MainWindow *)w->parent()->parent());
+    rotateAngle = win->getUIState()->mainFormAngle;
+    scaleFactor = win->getUIState()->getScaleFactor();
+}
+
+DisplayBase::~DisplayBase()
+{
+    qDebug("destory display");
+}
+
+void DisplayBase::rotate(int angle)
+{
+    qDebug("display rotate : %d", angle);
+
+    rotateAngle = angle;
+
+    qt5_window_angle = angle;
+
+    /* adjustSize() doesn't work */
+    widget->resize(0, 0);
+
+    widget->repaint();
+}
+
+void DisplayBase::scale(int scale)
+{
+    qDebug("display scale : %d", scale);
+
+    scaleFactor = ((qreal)scale) / 100;
+
+    /* adjustSize() doesn't work */
+    widget->resize(0, 0);
+
+    widget->repaint();
+}
+
+void DisplayBase::update()
+{
+    qt5_graphic_hw_invalidate();
+}
+
+void DisplayBase::handlePaint(QPaintEvent *event)
+{
+}
+
+void DisplayBase::handleResize(QResizeEvent *event)
+{
+    qDebug("resize display");
+
+    MainWindow *win = ((MainWindow *)widget->parent()->parent());
+    MainForm *form = win->uiInfo->getMainForm();
+
+    const qreal sx = scaleFactor;
+    const qreal sy = scaleFactor;
+
+    widget->setGeometry(form->displayRegion.x() * sx,
+                   form->displayRegion.y() * sy,
+                   form->displayRegion.width() * sx,
+                   form->displayRegion.height() * sy);
+
+    qt5_window_width = widget->width();
+    qt5_window_height = widget->height();
+
+    qt5_graphic_hw_invalidate();
+}
+
+void DisplayBase::handleMousePress(QMouseEvent *event)
+{
+    if (event->button() == Qt::LeftButton) {
+        isDragging = true;
+
+        sendTouchEvent(TOUCH_PRESS, event->x(), event->y());
+    }
+}
+
+void DisplayBase::handleMouseRelease(QMouseEvent *event)
+{
+    if (event->button() == Qt::LeftButton) {
+        if (isDragging) {
+            isDragging = false;
+        }
+
+        sendTouchEvent(TOUCH_RELEASE, event->x(), event->y());
+    }
+}
+
+void DisplayBase::handleMouseMove(QMouseEvent *event)
+{
+    if (isDragging == true) {
+        int event_type = TOUCH_PRESS;
+        int clientX = event->x();
+        int clientY = event->y();
+
+        if (clientX < 0) {
+            event_type = TOUCH_RELEASE;
+            clientX = 0;
+            isDragging = false;
+        } else if (clientX >= widget->width()) {
+            event_type = TOUCH_RELEASE;
+            clientX = widget->width() - 1;
+            isDragging = false;
+        }
+
+        if (clientY < 0) {
+            event_type = TOUCH_RELEASE;
+            clientY = 0;
+            isDragging = false;
+        } else if (clientY >= widget->height()) {
+            event_type = TOUCH_RELEASE;
+            clientY = widget->height() - 1;
+            isDragging = false;
+        }
+
+        sendTouchEvent(event_type, clientX, clientY);
+    }
+}
+
+void DisplayBase::sendTouchEvent(int eventType, int clientX, int clientY)
+{
+    int xx = clientX / scaleFactor;
+    int yy = clientY / scaleFactor;
+    int absX = xx;
+    int absY = yy;
+
+    /* TODO: x*cos(rad)-y*sin(rad) */
+    switch(rotateAngle) {
+    case 90: /* Reverse Landscape */
+        absX = yy;
+        absY = resolution.height() - xx;
+        break;
+    case 180: /* Reverse Portrait */
+        absX = resolution.width() - xx;
+        absY = resolution.height() - yy;
+        break;
+    case 270: /* Landscape */
+        absX = resolution.width() - yy;
+        absY = xx;
+        break;
+    case 0:
+    default:
+        break;
+    }
+
+    do_mouse_event(0, eventType, clientX, clientY, absX, absY, 0);
+}
diff --git a/tizen/src/ui/displaybase.h b/tizen/src/ui/displaybase.h
new file mode 100644 (file)
index 0000000..2ca4ec8
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@samsung.com>
+ * Stanislav Vorobiov
+ *
+ * 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 DISPLAYBASE_H
+#define DISPLAYBASE_H
+
+#include <QWidget>
+
+extern "C" {
+void qt5_graphic_hw_invalidate(void);
+}
+
+enum {
+    TOUCH_PRESS = 1,
+    TOUCH_RELEASE = 2,
+};
+
+class DisplayBase
+{
+public:
+    void rotate(int angle);
+    void scale(int scale);
+    void update();
+
+protected:
+    DisplayBase(QSize resolution, QWidget *w);
+    virtual ~DisplayBase();
+
+    void setRotate(int angle);
+    void setScale(int scale);
+
+    void handlePaint(QPaintEvent *event);
+    void handleResize(QResizeEvent *event);
+
+    void handleMousePress(QMouseEvent *event);
+    void handleMouseRelease(QMouseEvent *event);
+    void handleMouseMove(QMouseEvent *event);
+
+private:
+    void sendTouchEvent(int eventType, int clientX, int clientY);
+
+    QSize resolution;
+    QWidget *widget;
+    int rotateAngle;
+    qreal scaleFactor;
+
+    bool isDragging;
+};
+
+#endif
diff --git a/tizen/src/ui/displayglwidget.cpp b/tizen/src/ui/displayglwidget.cpp
new file mode 100644 (file)
index 0000000..1198fe0
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@samsung.com>
+ * Stanislav Vorobiov
+ *
+ * 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 <QtWidgets>
+
+#include "displayglwidget.h"
+
+DisplayGLWidget::DisplayGLWidget(QSize resolution, QGLContext *context, QWidget *parent) :
+    QGLWidget(context, parent),
+    DisplayBase(resolution, this)
+{
+    setAutoBufferSwap(false);
+}
+
+void DisplayGLWidget::initializeGL()
+{
+    qDebug("initialize GL");
+}
+
+void DisplayGLWidget::paintEvent(QPaintEvent *event)
+{
+    /*
+     * We offload rendering to separate thread, this must be
+     * a no-op, see: http://qt-project.org/doc/qt-5/QGLWidget.html:
+     * "3. Using QPainter to draw into a QGLWidget in a thread"
+     */
+
+    handlePaint(event);
+}
+
+void DisplayGLWidget::resizeEvent(QResizeEvent *event)
+{
+    /*
+     * We offload rendering to separate thread, this must be
+     * a no-op, see: http://qt-project.org/doc/qt-5/QGLWidget.html:
+     * "3. Using QPainter to draw into a QGLWidget in a thread"
+     */
+
+    handleResize(event);
+}
+
+void DisplayGLWidget::mousePressEvent(QMouseEvent *event)
+{
+    handleMousePress(event);
+}
+
+void DisplayGLWidget::mouseReleaseEvent(QMouseEvent *event)
+{
+    handleMouseRelease(event);
+}
+
+void DisplayGLWidget::mouseMoveEvent(QMouseEvent *event)
+{
+    handleMouseMove(event);
+}
+
+DisplayGLWidget::~DisplayGLWidget()
+{
+}
diff --git a/tizen/src/ui/displayglwidget.h b/tizen/src/ui/displayglwidget.h
new file mode 100644 (file)
index 0000000..9a1b8d8
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@samsung.com>
+ * Stanislav Vorobiov
+ *
+ * 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 DISPLAYGLWIDGET_H
+#define DISPLAYGLWIDGET_H
+
+#include "displaybase.h"
+#include <QGLWidget>
+
+class DisplayGLWidget : public QGLWidget,
+                        public DisplayBase
+{
+    Q_OBJECT
+
+public:
+    DisplayGLWidget(QSize resolution, QGLContext *context, QWidget *parent = 0);
+    ~DisplayGLWidget();
+
+protected:
+    void initializeGL();
+
+    void paintEvent(QPaintEvent *event);
+    void resizeEvent(QResizeEvent *event);
+
+    void mousePressEvent(QMouseEvent *event);
+    void mouseReleaseEvent(QMouseEvent *event);
+    void mouseMoveEvent(QMouseEvent *event);
+};
+
+#endif // DISPLAYGLWIDGET_H
diff --git a/tizen/src/ui/displayswwidget.cpp b/tizen/src/ui/displayswwidget.cpp
new file mode 100644 (file)
index 0000000..3cb3b23
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@samsung.com>
+ * Stanislav Vorobiov
+ *
+ * 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 <QtWidgets>
+
+#include "displayswwidget.h"
+
+DisplaySWWidget::DisplaySWWidget(QSize resolution, QWidget *parent) :
+    QLabel(parent),
+    DisplayBase(resolution, this)
+{
+}
+
+void DisplaySWWidget::paintEvent(QPaintEvent *event)
+{
+    QLabel::paintEvent(event);
+    handlePaint(event);
+}
+
+void DisplaySWWidget::resizeEvent(QResizeEvent *event)
+{
+    QLabel::resizeEvent(event);
+    handleResize(event);
+}
+
+void DisplaySWWidget::mousePressEvent(QMouseEvent *event)
+{
+    handleMousePress(event);
+}
+
+void DisplaySWWidget::mouseReleaseEvent(QMouseEvent *event)
+{
+    handleMouseRelease(event);
+}
+
+void DisplaySWWidget::mouseMoveEvent(QMouseEvent *event)
+{
+    handleMouseMove(event);
+}
+
+DisplaySWWidget::~DisplaySWWidget()
+{
+}
diff --git a/tizen/src/ui/displayswwidget.h b/tizen/src/ui/displayswwidget.h
new file mode 100644 (file)
index 0000000..69454eb
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@samsung.com>
+ * Stanislav Vorobiov
+ *
+ * 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 DISPLAYSWWIDGET_H
+#define DISPLAYSWWIDGET_H
+
+#include "displaybase.h"
+#include <QLabel>
+
+class DisplaySWWidget : public QLabel,
+                        public DisplayBase
+{
+    Q_OBJECT
+
+public:
+    DisplaySWWidget(QSize resolution, QWidget *parent = 0);
+    ~DisplaySWWidget();
+
+protected:
+    void paintEvent(QPaintEvent *event);
+    void resizeEvent(QResizeEvent *event);
+
+    void mousePressEvent(QMouseEvent *event);
+    void mouseReleaseEvent(QMouseEvent *event);
+    void mouseMoveEvent(QMouseEvent *event);
+};
+
+#endif // DISPLAYSWWIDGET_H
diff --git a/tizen/src/ui/dockingcontroller.cpp b/tizen/src/ui/dockingcontroller.cpp
new file mode 100644 (file)
index 0000000..283e6ba
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "dockingcontroller.h"
+#include "mainwindow.h"
+
+DockingController::DockingController(ControllerForm *conForm,
+    QAction *menu, int dockPos, QWidget *parent) : QWidget(parent)
+{
+    this->conForm = conForm;
+    this->menu = menu;
+    this->dockPos = dockPos;
+
+    setStyleSheet("border-style: none");
+    setAttribute(Qt::WA_DeleteOnClose);
+
+    QVBoxLayout *layout = new QVBoxLayout(this);
+    layout->setMargin(0);
+    layout->setSpacing(0);
+
+    if (dockPos & Qt::AlignCenter) {
+        layout->setAlignment(Qt::AlignCenter);
+    } else if (dockPos & Qt::AlignTop) {
+        layout->setAlignment(Qt::AlignTop);
+    } else if (dockPos & Qt::AlignBottom) {
+        layout->setAlignment(Qt::AlignBottom);
+    }
+
+    QGraphicsScene *conScene = new QGraphicsScene(this);
+    conScene->setBackgroundBrush(Qt::black);
+
+    conView = new DockingConView(conForm, conScene, this);
+    conView->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+    layout->addWidget(conView);
+}
+
+DockingConView *DockingController::getConView()
+{
+    return conView;
+}
+
+int DockingController::getDockPos()
+{
+    return dockPos;
+}
+
+void DockingController::showEvent(QShowEvent *event)
+{
+    if (menu != NULL) {
+        menu->setChecked(true);
+    }
+}
+
+void DockingController::closeEvent(QCloseEvent *event) {
+    if (menu != NULL) {
+        menu->setChecked(false);
+    }
+
+    MainWindow *win = ((MainWindow *)this->parent());
+    win->getUIState()->conState.dockingCon = NULL;
+}
+
+DockingController::~DockingController()
+{
+    qDebug("destroy docking contoller");
+}
diff --git a/tizen/src/ui/dockingcontroller.h b/tizen/src/ui/dockingcontroller.h
new file mode 100644 (file)
index 0000000..a388030
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 DOCKINGCONTROLLER_H
+#define DOCKINGCONTROLLER_H
+
+#include <QDialog>
+
+#include "controllerform.h"
+#include "dockingconview.h"
+
+class DockingController : public QWidget
+{
+    Q_OBJECT
+
+public:
+    explicit DockingController(ControllerForm *conForm,
+        QAction *menu, int dockPos, QWidget *parent = 0);
+    ~DockingController();
+
+    DockingConView *getConView();
+    int getDockPos();
+
+protected:
+    void showEvent(QShowEvent *event);
+    void closeEvent(QCloseEvent *event);
+
+private:
+    DockingConView *conView;
+    ControllerForm *conForm;
+    QAction *menu;
+    int dockPos;
+};
+
+#endif // DOCKINGCONTROLLER_H
diff --git a/tizen/src/ui/dockingconview.cpp b/tizen/src/ui/dockingconview.cpp
new file mode 100644 (file)
index 0000000..dee2b3f
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "dockingconview.h"
+#include "mainwindow.h"
+#include "skinkeyitem.h"
+
+DockingConView::DockingConView(ControllerForm *conForm, QGraphicsScene *scene, QWidget *parent)
+    : QGraphicsView(scene, parent)
+{
+    this->parent = (DockingController *)parent;
+
+    setStyleSheet("background: transparent");
+    setStyleSheet("border-style: none");
+
+    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    setAlignment(Qt::AlignLeft | Qt::AlignTop);
+
+    rubberPos = QPoint(-1, -1);
+    grabPos = QPoint(-1, -1);
+    rubberBand = new QRubberBand(QRubberBand::Rectangle, NULL);
+
+    createItems(conForm);
+}
+
+void DockingConView::createItems(ControllerForm *conForm)
+{
+    /* bezel */
+    bezelItem = new SkinBezelItem(conForm->conImg[ControllerForm::normal]);
+    scene()->addItem(bezelItem);
+
+    /* HW keys */
+    QList<HardwareKey *> keyList = conForm->keyList;
+
+    HardwareKey *hwKey = NULL;
+    for (int i = 0; i < keyList.count(); i++) {
+        hwKey = keyList.at(i);
+        if (hwKey != NULL) {
+            new SkinKeyItem(conForm->conImg[ControllerForm::pressed].copy(hwKey->region),
+                    hwKey, bezelItem);
+        }
+    }
+}
+
+void DockingConView::resizeEvent(QResizeEvent *event)
+{
+    //qDebug("resize con view");
+
+    Q_UNUSED(event)
+}
+
+void DockingConView::mousePressEvent(QMouseEvent *event)
+{
+    QGraphicsView::mousePressEvent(event);
+
+    if (bezelItem->isKeyHandling() == true) {
+        /* do nothing */
+        return;
+    }
+
+    if (event->button() == Qt::LeftButton) {
+        QWidget *win = ((QWidget *)parent->parent());
+
+        grabPos = event->globalPos();
+        eventPos = event->pos();
+        rubberPos.setX(win->pos().x() + parent->pos().x());
+        rubberPos.setY(win->pos().y() + pos().y());
+
+        if (rubberBand != NULL) {
+            rubberBand->setGeometry(QRect(rubberPos, size()));
+            rubberBand->show();
+        }
+    }
+}
+
+void DockingConView::mouseReleaseEvent(QMouseEvent *event)
+{
+    QGraphicsView::mouseReleaseEvent(event);
+
+    if (bezelItem->isKeyHandling() == true) {
+        /* do nothing */
+        return;
+    }
+
+    if (event->button() == Qt::LeftButton) {
+        if (grabPos != QPoint(-1, -1)) {
+            if (rubberBand != NULL) {
+                rubberBand->hide();
+            }
+
+            /* toggle */
+            MainWindow *win = ((MainWindow *)parent->parent());
+            win->getUIState()->conState.recentlyFloatPos = event->globalPos() - eventPos;
+
+            win->openController(win->getUIState()->conState.conFormIndex, -1);
+            return;
+        }
+    }
+}
+
+void DockingConView::mouseMoveEvent(QMouseEvent *event)
+{
+    QGraphicsView::mouseMoveEvent(event);
+
+    if (bezelItem->isKeyHandling() == true) {
+        /* do nothing */
+        return;
+    }
+
+    if (grabPos != QPoint(-1, -1) && rubberBand != NULL) {
+        rubberBand->setGeometry(
+            QRect(rubberPos + (event->globalPos() - grabPos), size()));
+    }
+}
+
+DockingConView::~DockingConView()
+{
+    qDebug("destroy docking controller view");
+
+    if (rubberBand != NULL) {
+        rubberBand->close();
+        delete rubberBand;
+        rubberBand = NULL;
+    }
+}
diff --git a/tizen/src/ui/dockingconview.h b/tizen/src/ui/dockingconview.h
new file mode 100644 (file)
index 0000000..691400d
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 DOCKINGCONVIEW_H
+#define DOCKINGCONVIEW_H
+
+#include <QRubberBand>
+
+#include "skinview.h"
+#include "skinbezelitem.h"
+#include "controllerform.h"
+
+class DockingController;
+
+class DockingConView : public QGraphicsView
+{
+public:
+    DockingConView(ControllerForm *conForm, QGraphicsScene *scene, QWidget *parent = 0);
+    ~DockingConView();
+
+protected:
+    void resizeEvent(QResizeEvent *event);
+    void mousePressEvent(QMouseEvent *event);
+    void mouseReleaseEvent(QMouseEvent *event);
+    void mouseMoveEvent(QMouseEvent *event);
+
+    QPoint grabPos;
+    QPoint eventPos;
+    QPoint rubberPos;
+
+private:
+    void createItems(ControllerForm *conForm);
+
+    DockingController *parent;
+    SkinBezelItem *bezelItem;
+    QRubberBand *rubberBand;
+};
+
+#endif // DOCKINGCONVIEW_H
diff --git a/tizen/src/ui/floatingcontroller.cpp b/tizen/src/ui/floatingcontroller.cpp
new file mode 100644 (file)
index 0000000..0616eff
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "floatingcontroller.h"
+#include "mainwindow.h"
+
+FloatingController::FloatingController(ControllerForm *conForm,
+    QAction *menu, QWidget *parent) : QDialog(parent)
+{
+    this->conForm = conForm;
+    this->menu = menu;
+
+    setStyleSheet("border-style: none");
+    setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
+    setAttribute(Qt::WA_DeleteOnClose);
+
+    setWindowTitle(conForm->name);
+
+    QHBoxLayout *layout = new QHBoxLayout(this);
+    layout->setMargin(0);
+    layout->setSpacing(0);
+
+    QGraphicsScene *conScene = new QGraphicsScene(this);
+    conScene->setBackgroundBrush(Qt::black);
+
+    conView = new FloatingConView(conForm, conScene, this);
+    conView->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+    layout->addWidget(conView);
+}
+
+FloatingConView *FloatingController::getConView()
+{
+    return conView;
+}
+
+void FloatingController::showEvent(QShowEvent *event)
+{
+    if (menu != NULL) {
+        menu->setChecked(true);
+    }
+
+    setRegion(&(conForm->conImg[ControllerForm::normal]));
+}
+
+void FloatingController::closeEvent(QCloseEvent *event) {
+    if (menu != NULL) {
+        menu->setChecked(false);
+    }
+
+    MainWindow *win = ((MainWindow *)this->parent());
+    win->getUIState()->conState.floatingCon = NULL;
+}
+
+void FloatingController::setRegion(QImage *baseImage)
+{
+    qDebug("set region");
+
+    if (baseImage->isNull() == true) {
+        qWarning("invalid image for region");
+        return;
+    }
+
+    setMask(QRegion(QBitmap::fromImage(baseImage->createAlphaMask())));
+}
+
+FloatingController::~FloatingController()
+{
+    qDebug("destroy floating contoller");
+}
diff --git a/tizen/src/ui/floatingcontroller.h b/tizen/src/ui/floatingcontroller.h
new file mode 100644 (file)
index 0000000..d9e7bf5
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 FLOATINGCONTROLLER_H
+#define FLOATINGCONTROLLER_H
+
+#include <QDialog>
+
+#include "controllerform.h"
+#include "floatingconview.h"
+
+class FloatingController : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit FloatingController(ControllerForm *conForm, QAction *menu, QWidget *parent = 0);
+    ~FloatingController();
+
+    FloatingConView *getConView();
+
+protected:
+    void showEvent(QShowEvent *event);
+    void closeEvent(QCloseEvent *event);
+
+    void setRegion(QImage *baseImage);
+
+private:
+    FloatingConView *conView;
+    ControllerForm *conForm;
+    QAction *menu;
+};
+
+#endif // FLOATINGCONTROLLER_H
diff --git a/tizen/src/ui/floatingconview.cpp b/tizen/src/ui/floatingconview.cpp
new file mode 100644 (file)
index 0000000..a6572dc
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "floatingconview.h"
+#include "mainwindow.h"
+#include "skinkeyitem.h"
+
+#define DOCKABLE_AREA_WIDTH 30
+
+FloatingConView::FloatingConView(ControllerForm *conForm, QGraphicsScene *scene, QWidget *parent)
+    : QGraphicsView(scene, parent)
+{
+    this->parent = (FloatingController *)parent;
+
+    setStyleSheet("background: transparent");
+    setStyleSheet("border-style: none");
+
+    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    setAlignment(Qt::AlignLeft | Qt::AlignTop);
+
+    conPos = QPoint(-1, -1);
+    grabPos = QPoint(-1, -1);
+    rubberBand = new QRubberBand(QRubberBand::Rectangle, NULL);
+
+    createItems(conForm);
+}
+
+void FloatingConView::createItems(ControllerForm *conForm)
+{
+    /* bezel */
+    bezelItem = new SkinBezelItem(conForm->conImg[ControllerForm::normal]);
+    scene()->addItem(bezelItem);
+
+    /* HW keys */
+    QList<HardwareKey *> keyList = conForm->keyList;
+
+    HardwareKey *hwKey = NULL;
+    for (int i = 0; i < keyList.count(); i++) {
+        hwKey = keyList.at(i);
+        if (hwKey != NULL) {
+            new SkinKeyItem(conForm->conImg[ControllerForm::pressed].copy(hwKey->region),
+                    hwKey, bezelItem);
+        }
+    }
+}
+
+void FloatingConView::resizeEvent(QResizeEvent *event)
+{
+    //qDebug("resize con view");
+
+    Q_UNUSED(event)
+}
+
+int FloatingConView::isDockable(QWidget *object, QWidget *subject)
+{
+    const int heightOneThird = object->size().height() / 3;
+
+    /* MainWindow */
+    QRect rectDockableRC(object->pos().x() + object->size().width() - 1,
+        object->pos().y() + heightOneThird,
+        DOCKABLE_AREA_WIDTH,
+        heightOneThird);
+
+    QRect rectDockableRT(object->pos().x() + object->size().width() - 1,
+            object->pos().y(),
+            DOCKABLE_AREA_WIDTH,
+            heightOneThird);
+
+    QRect rectDockableRB(object->pos().x() + object->size().width() - 1,
+            object->pos().y() + (heightOneThird * 2),
+            DOCKABLE_AREA_WIDTH,
+            heightOneThird);
+
+    /* ControllerWidget */
+    QRect rectTarget(subject->pos().x() - 1,
+        subject->pos().y(),
+        DOCKABLE_AREA_WIDTH,
+        subject->size().height());
+
+    // TODO: define recursive function
+    QRect interRC = rectTarget.intersected(rectDockableRC);
+    QRect interRT = rectTarget.intersected(rectDockableRT);
+    QRect interRB = rectTarget.intersected(rectDockableRB);
+
+    QRect *interBiggest = NULL;
+
+    if ((interRC.width() * interRC.height()) < (interRT.width() * interRT.height())) {
+        interBiggest = &interRT;
+    } else {
+        interBiggest = &interRC;
+    }
+
+    if ((interBiggest->width() * interBiggest->height()) < (interRB.width() * interRB.height())) {
+        interBiggest = &interRB;
+    }
+
+    if (interBiggest != NULL &&
+        interBiggest->isNull() == false && interBiggest->isEmpty() == false) {
+        if (interBiggest == &interRC) {
+            return Qt::AlignRight | Qt::AlignCenter;
+        } else if (interBiggest == &interRT) {
+            return Qt::AlignRight | Qt::AlignTop;
+        } else if (interBiggest == &interRB) {
+            return Qt::AlignRight | Qt::AlignBottom;
+        }
+    }
+
+    return -1;
+}
+
+void FloatingConView::mousePressEvent(QMouseEvent *event)
+{
+    QGraphicsView::mousePressEvent(event);
+
+    if (bezelItem->isKeyHandling() == true) {
+        /* do nothing */
+        return;
+    }
+
+    if (event->button() == Qt::LeftButton) {
+        grabPos = event->globalPos();
+        conPos = parent->pos();
+    }
+}
+
+void FloatingConView::mouseReleaseEvent(QMouseEvent *event)
+{
+    QGraphicsView::mouseReleaseEvent(event);
+
+    if (bezelItem->isKeyHandling() == true) {
+        /* do nothing */
+        return;
+    }
+
+    if (event->button() == Qt::LeftButton) {
+        grabPos = QPoint(-1, -1);
+        if (rubberBand != NULL) {
+            rubberBand->hide();
+        }
+    }
+
+    const FloatingController *con = parent;
+    MainWindow *win = ((MainWindow *)con->parent());
+
+    int dockPos = isDockable((QWidget *)win, (QWidget *)parent);
+    if (dockPos != -1) {
+        /* toggle */
+        win->openController(win->getUIState()->conState.conFormIndex, dockPos);
+        return;
+    }
+}
+
+void FloatingConView::mouseMoveEvent(QMouseEvent *event)
+{
+    QGraphicsView::mouseMoveEvent(event);
+
+    if (bezelItem->isKeyHandling() == true) {
+        /* do nothing */
+        return;
+    }
+
+    if (grabPos != QPoint(-1, -1)) {
+        /* draw guide for dockable position */
+        const FloatingController *con = parent;
+        MainWindow *win = ((MainWindow *)con->parent());
+
+        if (rubberBand != NULL) {
+            int dockPos = isDockable((QWidget *)win, (QWidget *)con);
+            if (dockPos != -1) {
+                int vShift = 0;
+
+                if (win->size().height() > size().height()) {
+                    if (dockPos & Qt::AlignCenter) {
+                        vShift = (win->size().height() / 2) - (size().height() / 2);
+                    } else if (dockPos & Qt::AlignBottom) {
+                        vShift = win->size().height() - size().height();
+                    }
+                }
+
+                QPoint rubberPos(win->pos().x() + win->size().width(),
+                    win->pos().y() + vShift);
+                rubberBand->setGeometry(QRect(rubberPos, size()));
+                rubberBand->show();
+            } else {
+                rubberBand->hide();
+            }
+        }
+
+        parent->move(conPos + (event->globalPos() - grabPos));
+    }
+}
+
+FloatingConView::~FloatingConView()
+{
+    qDebug("destroy floating controller view");
+
+    if (rubberBand != NULL) {
+        rubberBand->close();
+        delete rubberBand;
+        rubberBand = NULL;
+    }
+}
diff --git a/tizen/src/ui/floatingconview.h b/tizen/src/ui/floatingconview.h
new file mode 100644 (file)
index 0000000..f2e996f
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 FLOATINGCONVIEW_H
+#define FLOATINGCONVIEW_H
+
+#include <QRubberBand>
+
+#include "skinview.h"
+#include "skinbezelitem.h"
+#include "controllerform.h"
+
+class FloatingController;
+
+class FloatingConView : public QGraphicsView
+{
+public:
+    FloatingConView(ControllerForm *conForm, QGraphicsScene *scene, QWidget *parent = 0);
+    ~FloatingConView();
+
+protected:
+    void resizeEvent(QResizeEvent *event);
+    void mousePressEvent(QMouseEvent *event);
+    void mouseReleaseEvent(QMouseEvent *event);
+    void mouseMoveEvent(QMouseEvent *event);
+
+    int isDockable(QWidget *object, QWidget *subject);
+
+    QPoint grabPos;
+    QPoint conPos;
+
+private:
+    void createItems(ControllerForm *conForm);
+
+    FloatingController *parent;
+    SkinBezelItem *bezelItem;
+    QRubberBand *rubberBand;
+};
+
+#endif // FLOATINGCONVIEW_H
diff --git a/tizen/src/ui/hardwarekey.cpp b/tizen/src/ui/hardwarekey.cpp
new file mode 100644 (file)
index 0000000..336f277
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "hardwarekey.h"
+
+HardwareKey::HardwareKey(QString name, int keycode, QRect region, QString tooltip)
+{
+    this->name = name;
+    this->keycode = keycode;
+    this->region = region;
+    this->tooltip = tooltip;
+}
+
+HardwareKey::~HardwareKey()
+{
+    qDebug("destroy HW key");
+}
diff --git a/tizen/src/ui/hardwarekey.h b/tizen/src/ui/hardwarekey.h
new file mode 100644 (file)
index 0000000..6fabe42
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 HARDWAREKEY_H
+#define HARDWAREKEY_H
+
+#include <QWidget>
+
+class HardwareKey
+{
+public:
+    HardwareKey(QString name, int keycode, QRect region, QString tooltip);
+    ~HardwareKey();
+
+    QString name;
+    int keycode;
+    QRect region;
+    QString tooltip;
+};
+
+#endif // HARDWAREKEY_H
diff --git a/tizen/src/ui/keyboardhelper.cpp b/tizen/src/ui/keyboardhelper.cpp
new file mode 100644 (file)
index 0000000..37ac16e
--- /dev/null
@@ -0,0 +1,464 @@
+/*
+ * Qt keyboard helper
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Sungmin Ha <sungmin82.ha@samsung.com>
+ * Sangho Park <sangho1206.park@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 <Qt>
+#include <QtWidgets>
+
+#include "keyboardhelper.h"
+
+extern "C" {
+#include "emul_state.h"
+#include "skin/maruskin_operation.h"
+
+void virtio_keyboard_event(int keycode);
+}
+
+KeyboardHelper::KeyboardHelper()
+{
+    createKeyMap();
+    createKeypadMap();
+
+    this->numLockState = false;
+    this->capsLockState = false;
+}
+
+void KeyboardHelper::createKeypadMap()
+{
+    keypadMap.insert(48, Qt::Key_Insert);
+    keypadMap.insert(49, Qt::Key_End);
+    keypadMap.insert(50, Qt::Key_Down);
+    keypadMap.insert(51, Qt::Key_PageDown);
+    keypadMap.insert(52, Qt::Key_Left);
+    keypadMap.insert(53, Qt::Key_Clear);
+    keypadMap.insert(54, Qt::Key_Right);
+    keypadMap.insert(55, Qt::Key_Home);
+    keypadMap.insert(56, Qt::Key_Up);
+    keypadMap.insert(57, Qt::Key_PageUp);
+    keypadMap.insert(46, Qt::Key_Delete);
+    keypadMap.insert(42, 106);  /* * */
+    keypadMap.insert(45, 109);  /* - */
+
+    keypadMap.insert(Qt::Key_Insert, 48);
+    keypadMap.insert(Qt::Key_End, 49);
+    keypadMap.insert(Qt::Key_Down, 50);
+    keypadMap.insert(Qt::Key_PageDown, 51);
+    keypadMap.insert(Qt::Key_Left, 52);
+    keypadMap.insert(Qt::Key_Clear, 53);
+    keypadMap.insert(Qt::Key_Right, 54);
+    keypadMap.insert(Qt::Key_Home, 55);
+    keypadMap.insert(Qt::Key_Up, 56);
+    keypadMap.insert(Qt::Key_PageUp, 57);
+    keypadMap.insert(Qt::Key_Delete, 46);
+}
+
+void KeyboardHelper::createKeyMap()
+{
+    /* characters */
+    /* q ~ p */
+    keyMap.insert(81, 16);
+    keyMap.insert(87, 17);
+    keyMap.insert(69, 18);
+    keyMap.insert(82, 19);
+    keyMap.insert(84, 20);
+    keyMap.insert(89, 21);
+    keyMap.insert(85, 22);
+    keyMap.insert(73, 23);
+    keyMap.insert(79, 24);
+    keyMap.insert(80, 25);
+
+    /* a ~ l */
+    keyMap.insert(65, 30);
+    keyMap.insert(83, 31);
+    keyMap.insert(68, 32);
+    keyMap.insert(70, 33);
+    keyMap.insert(71, 34);
+    keyMap.insert(72, 35);
+    keyMap.insert(74, 36);
+    keyMap.insert(75, 37);
+    keyMap.insert(76, 38);
+
+    /* z ~ m */
+    keyMap.insert(90, 44);
+    keyMap.insert(88, 45);
+    keyMap.insert(67, 46);
+    keyMap.insert(86, 47);
+    keyMap.insert(66, 48);
+    keyMap.insert(78, 49);
+    keyMap.insert(77, 50);
+
+    /* signs */
+    keyMap.insert(32, 57); /* space */
+    keyMap.insert(44, 51); /* , */
+    keyMap.insert(46, 52); /* . */
+    keyMap.insert(59, 39); /* ; */
+    keyMap.insert(47, 53); /* / */
+    keyMap.insert(42, 55); /* * */
+    keyMap.insert(106, 55); /* * */
+    keyMap.insert(45, 12); /* - */
+    keyMap.insert(109, 74); /* - */
+    keyMap.insert(61, 13); /* = */
+    keyMap.insert(91, 26); /* [ */
+    keyMap.insert(93, 27); /* ] */
+    keyMap.insert(92, 43); /* \ */
+    keyMap.insert(43, 78); /* + */
+    keyMap.insert(39, 40); /* Single quote */
+    keyMap.insert(96, 41); /* ` */
+
+    /* special keys */
+    keyMap.insert(Qt::Key_Return, 28); /* return */
+    keyMap.insert(Qt::Key_Enter, 28); /* enter */
+    keyMap.insert(Qt::Key_Escape, 1); /* escape */
+    keyMap.insert(Qt::Key_Tab, 15); /* tab */
+    keyMap.insert(Qt::Key_Backtab, 15); /* shift tab */
+    keyMap.insert(Qt::Key_Backspace, 14); /* backspace */
+    keyMap.insert(Qt::Key_Pause, 198); /* pause/break */
+    keyMap.insert(Qt::Key_PageUp, 73); /* PgUp */
+    keyMap.insert(Qt::Key_PageDown, 81); /* PgDn */
+    keyMap.insert(Qt::Key_Home, 71); /* Home */
+    keyMap.insert(Qt::Key_End, 79); /* End */
+    keyMap.insert(Qt::Key_Insert, 82); /* Insert */
+    keyMap.insert(Qt::Key_Delete, 83); /* delete */
+
+    /* arrow keys */
+    keyMap.insert(Qt::Key_Up, 72); /* up arrow */
+    keyMap.insert(Qt::Key_Down, 80); /* down arrow */
+    keyMap.insert(Qt::Key_Left, 75); /* left arrow */
+    keyMap.insert(Qt::Key_Right, 77); /* right arrow */
+
+    /* modifiers */
+    keyMap.insert(Qt::Key_Shift, 42); /* shift */
+    keyMap.insert(Qt::Key_Control, 29); /* ctrl */
+    keyMap.insert(Qt::Key_Alt, 56); /* alt */
+
+    /* numbers */
+    keyMap.insert(48, 11); /* 0 */
+    keyMap.insert(49, 2);  /* 1 */
+    keyMap.insert(50, 3);  /* 2 */
+    keyMap.insert(51, 4);  /* 3 */
+    keyMap.insert(52, 5);  /* 4 */
+    keyMap.insert(53, 6);  /* 5 */
+    keyMap.insert(54, 7);  /* 6 */
+    keyMap.insert(55, 8);  /* 7 */
+    keyMap.insert(56, 9);  /* 8 */
+    keyMap.insert(57, 10); /* 9 */
+
+    /* shift + numbers */
+    keyMap.insert(126, 41); /* ~ */
+    keyMap.insert(33, 2); /* ! */
+    keyMap.insert(64, 3); /* @ */
+    keyMap.insert(35, 4); /* # */
+    keyMap.insert(36, 5); /* $ */
+    keyMap.insert(37, 6); /* % */
+    keyMap.insert(94, 7); /* ^ */
+    keyMap.insert(38, 8); /* & */
+    keyMap.insert(40, 10); /* ( */
+    keyMap.insert(41, 11); /* ) */
+
+    /* shift + signs */
+    keyMap.insert(95, 12); /* _ */
+    keyMap.insert(124, 43); /* | */
+    keyMap.insert(123, 26); /* { */
+    keyMap.insert(125, 27); /* } */
+    keyMap.insert(58, 39); /* : */
+    keyMap.insert(34, 40); /* " */
+    keyMap.insert(60, 51); /* < */
+    keyMap.insert(62, 52); /* > */
+    keyMap.insert(63, 53); /* ? */
+
+    /* function keys */
+    keyMap.insert(Qt::Key_F1, 59); /* f1 */
+    keyMap.insert(Qt::Key_F2, 60); /* f2 */
+    keyMap.insert(Qt::Key_F3, 61); /* f3 */
+    keyMap.insert(Qt::Key_F4, 62); /* f4 */
+    keyMap.insert(Qt::Key_F5, 63); /* f5 */
+    keyMap.insert(Qt::Key_F6, 64); /* f6 */
+    keyMap.insert(Qt::Key_F7, 65); /* f7 */
+    keyMap.insert(Qt::Key_F8, 66); /* f8 */
+    keyMap.insert(Qt::Key_F9, 67); /* f9 */
+    keyMap.insert(Qt::Key_F10, 68); /* f10 */
+    keyMap.insert(Qt::Key_F11, 87); /* f11 */
+    keyMap.insert(Qt::Key_F12, 88); /* f12 */
+}
+
+void KeyboardHelper::autoKeyRelease(void)
+{
+    while (!this->keyCodeList.isEmpty()) {
+        qDebug() << "auto release scancode: " << this->keyCodeList.last();
+        do_qt_keyboard_key_event(KEY_RELEASED, this->keyCodeList.last());
+        this->keyCodeList.removeLast();
+    }
+
+#if 0
+    clear_finger_slot(false);
+    qDebug() << "disable multi-touch";
+#endif
+}
+
+int KeyboardHelper::keyCodeOperation(QKeyEvent *event, int keyCode)
+{
+    /* keypad and specialKey translation */
+    if (!this->numLockState && (event->modifiers() == (Qt::KeypadModifier | Qt::ShiftModifier))) {
+        QMap<int, int>::iterator keypadIter = this->keypadMap.find(keyCode);
+        while (keypadIter != this->keypadMap.end()) {
+            if (keypadIter.key() == keyCode) {
+                keyCode = keypadIter.value();
+                break;
+            }
+        }
+    }
+
+    if (this->isSpecialKey(keyCode)) {
+        virtio_keyboard_event(224);
+    }
+
+    QMap<int, int>::iterator keyMapIter = this->keyMap.find(keyCode);
+    while (keyMapIter != this->keyMap.end()) {
+        if (keyMapIter.key() == keyCode) {
+            break;
+        }
+    }
+
+    if (keyMapIter == this->keyMap.end()) {
+        qDebug() << "unsupported keycode pressed: " << keyCode;
+        return -1;
+    }
+
+    return keyMapIter.value();
+}
+
+bool KeyboardHelper::isSpecialKey(int keyCode)
+{
+    switch(keyCode) {
+        case Qt::Key_PageDown:
+        case Qt::Key_PageUp:
+        case Qt::Key_Home:
+        case Qt::Key_End:
+        case Qt::Key_Insert:
+        case Qt::Key_Delete:
+        case Qt::Key_Up:
+        case Qt::Key_Down:
+        case Qt::Key_Left:
+        case Qt::Key_Right:
+            return true;
+        default:
+            break;
+    }
+
+    return false;
+}
+
+void KeyboardHelper::keyPressed(QKeyEvent *event)
+{
+    int keyCode = event->key();
+    qDebug() << "key pressed :" << event->key() << event->text() << event->nativeScanCode() << event->modifiers() << event->nativeModifiers();
+
+#if 0
+    /* TODO: multi-touch */
+    if (get_emul_max_touch_point() > 1) {
+        /* multi-touch checking */
+        if (event->modifiers() == (Qt::ShiftModifier|Qt::ControlModifier)) {
+            get_emul_multi_touch_state()->multitouch_enable = 2;
+            /* add a finger before start the multi-touch processing
+            if already exist the pressed touch in display */
+            qDebug() << "enable multi-touch = mode 2";
+        } else if (event->modifiers() == Qt::ShiftModifier ||
+            event->modifiers() == Qt::ControlModifier) {
+            get_emul_multi_touch_state()->multitouch_enable = 1;
+            qDebug() << "enable multi-touch = mode 1";
+        }
+    }
+#endif
+
+    /* NumLock or CapsLock key */
+    if (keyCode == Qt::Key_NumLock) {
+#ifdef CONFIG_WIN32
+        if (event->nativeModifiers() == 0x1000200) {
+            this->numLockState = ON;
+        } else if (event->nativeModifiers() == 0x1000000) {
+            this->numLockState = OFF;
+        }
+#else
+        if (event->nativeModifiers() == 0) {
+            this->numLockState = ON;
+        } else if (event->nativeModifiers() == 16) {
+            this->numLockState = OFF;
+        }
+#endif
+        qDebug() << "num_lock state: " << this->numLockState << "pressed";
+        return;
+    } else if (keyCode == Qt::Key_CapsLock) {
+#ifdef CONFIG_WIN32
+        if (event->nativeModifiers() == 256) {
+            this->capsLockState = ON;
+        } else if (event->nativeModifiers() == 0) {
+            this->capsLockState = OFF;
+        }
+#else
+        if (event->nativeModifiers() == 18) {
+            this->capsLockState = ON;
+        } else if (event->nativeModifiers() == 16) {
+            this->capsLockState = OFF;
+        }
+#endif
+        qDebug() << "caps_lock state: " << this->capsLockState << "pressed";
+        return;
+    }
+
+    /* host numlock check for sync */
+    if ((event->modifiers() & Qt::KeypadModifier)) {
+        if (this->isSpecialKey(keyCode) || keyCode == Qt::Key_Clear) {
+            if (!(event->modifiers() & Qt::ShiftModifier)) {
+                this->numLockState = OFF;
+            } else {
+                this->numLockState = ON;
+            }
+        } else {
+            if (!(event->modifiers() & Qt::ShiftModifier || keyCode == 42 || keyCode == 43 || keyCode == 45 || keyCode == 47)) { /* (42 = *, 43 = +, 45 = -, 47 = /) on keypad */
+                this->numLockState = ON;
+            } else {
+                this->numLockState = OFF;
+            }
+        }
+    }
+    if (event->key() >= 65 && event->key() <= 90) {
+#ifdef CONFIG_WIN32
+        if (event->nativeModifiers() & 256) {
+#else
+        if (event->nativeModifiers() & 0x02) {
+#endif
+            this->capsLockState = ON;
+        } else {
+            this->capsLockState = OFF;
+        }
+    }
+
+    if (get_emul_caps_lock_state() != this->capsLockState) {
+        virtio_keyboard_event(58);
+        virtio_keyboard_event(58 | 0x80);
+        set_emul_caps_lock_state(get_emul_caps_lock_state() ^ 1);
+        qDebug() << "qemu CapsLock state was synchronized with host key value (" <<
+            get_emul_caps_lock_state() << ")";
+    }
+    if (get_emul_num_lock_state() != this->numLockState) {
+        virtio_keyboard_event(69);
+        virtio_keyboard_event(69 | 0x80);
+        set_emul_num_lock_state(get_emul_num_lock_state() ^ 1);
+        qDebug() << "qemu NumLock state was synchronized with host key value (" <<
+            get_emul_num_lock_state() << ")";
+    }
+
+    int ret = this->keyCodeOperation(event, keyCode);
+    if (ret != -1) {
+        /* for auto release */
+        this->keyCodeList.append(ret);
+        do_qt_keyboard_key_event(KEY_PRESSED, ret);
+    }
+}
+
+void KeyboardHelper::keyReleased(QKeyEvent *event)
+{
+    int keyCode = event->key();
+    qDebug() << "key released :" <<  event->key() << event->text() << event->nativeScanCode() << event->modifiers() << event->nativeModifiers();
+
+#if 0
+    /* TODO: multi-touch */
+    if (event->key() == Qt::Key_Shift && event->modifiers() == Qt::ControlModifier) {
+        get_emul_multi_touch_state()->multitouch_enable = 1;
+        qDebug() << "enabled multi-touch = mode 1";
+    } else if (event->key() == Qt::Key_Shift || event->key() == Qt::Key_Control) {
+        clear_finger_slot(false);
+        qDebug() << "disable multi-touch";
+    }
+#endif
+
+    if (keyCode == Qt::Key_NumLock) {
+        qDebug() << "num_lock state: " << this->numLockState << "released";
+        return;
+    } else if (keyCode == Qt::Key_CapsLock) {
+        qDebug() << "caps_lock state: " << this->capsLockState << "released";
+        return;
+    }
+
+#ifdef CONFIG_LINUX
+    /* for keypad keycode translation */
+    if (this->numLockState && event->modifiers() == Qt::KeypadModifier) {
+        if (this->isSpecialKey(keyCode) || keyCode == Qt::Key_Clear) {
+            switch(keyCode) {
+                case Qt::Key_Delete:
+                    keyCode = 46; /* . */
+                    break;
+                case Qt::Key_Insert:
+                    keyCode = 48; /* 0 */
+                    break;
+                case Qt::Key_End:
+                    keyCode = 49; /* 1 */
+                    break;
+                case Qt::Key_Down:
+                    keyCode = 50; /* 2 */
+                    break;
+                case Qt::Key_PageDown:
+                    keyCode = 51; /* 3 */
+                    break;
+                case Qt::Key_Left:
+                    keyCode = 52; /* 4 */
+                    break;
+                case Qt::Key_Clear:
+                    keyCode = 53; /* 5 */
+                    break;
+                case Qt::Key_Right:
+                    keyCode = 54; /* 6 */
+                    break;
+                case Qt::Key_Home:
+                    keyCode = 55; /* 7 */
+                    break;
+                case Qt::Key_Up:
+                    keyCode = 56; /* 8 */
+                    break;
+                case Qt::Key_PageUp:
+                    keyCode = 57; /* 9 */
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+#endif
+
+    int ret = this->keyCodeOperation(event, keyCode);
+    if (ret != -1) {
+        do_qt_keyboard_key_event(KEY_RELEASED, ret);
+        /* remove keycode from list */
+        this->keyCodeList.removeOne(ret);
+    }
+}
+
+KeyboardHelper::~KeyboardHelper()
+{
+    qDebug("destroy keyboard helper");
+}
diff --git a/tizen/src/ui/keyboardhelper.h b/tizen/src/ui/keyboardhelper.h
new file mode 100644 (file)
index 0000000..7eef329
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Qt keyboard helper
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Sungmin Ha <sungmin82.ha@samsung.com>
+ * Sangho Park <sangho1206.park@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 KEYBOARDHELPER_H
+#define KEYBOARDHELPER_H
+
+#include <QMap>
+
+enum KbdLedState {
+    OFF,
+    ON
+};
+
+class KeyboardHelper
+{
+public:
+    KeyboardHelper();
+    ~KeyboardHelper();
+
+    void keyPressed(QKeyEvent *event);
+    void keyReleased(QKeyEvent *event);
+    void autoKeyRelease(void);
+    bool isSpecialKey(int keyCode);
+    int keyCodeOperation(QKeyEvent *event, int keyCode);
+
+protected:
+    QList<int> keyCodeList;
+    QMap<int, int> keyMap;
+    QMap<int, int> keypadMap;
+    bool numLockState;
+    bool capsLockState;
+
+private:
+    void createKeyMap();
+    void createKeypadMap();
+};
+
+#endif // KEYBOARDHELPER_H
diff --git a/tizen/src/ui/mainform.cpp b/tizen/src/ui/mainform.cpp
new file mode 100644 (file)
index 0000000..c707786
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "mainform.h"
+
+MainForm::MainForm() :
+    displayRegion(0, 0, 0, 0)
+{
+}
+
+MainForm::~MainForm()
+{
+    qDebug("destroy main form");
+
+    for (int i = 0; i < keyList.count(); i++) {
+        delete keyList.at(i);
+    }
+    keyList.clear();
+}
diff --git a/tizen/src/ui/mainform.h b/tizen/src/ui/mainform.h
new file mode 100644 (file)
index 0000000..28bcede
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 MAINFORM_H
+#define MAINFORM_H
+
+#include <QtWidgets>
+
+#include "hardwarekey.h"
+
+class MainForm
+{
+    Q_ENUMS(SkinImgType)
+
+public:
+    MainForm();
+    ~MainForm();
+
+    QImage skinImg[2];
+    QRect displayRegion;
+    QList<HardwareKey *> keyList;
+
+    enum SkinImgType {
+        normal = 0,
+        pressed = 1
+    };
+};
+
+#endif // MAINFORM_H
diff --git a/tizen/src/ui/mainwindow.cpp b/tizen/src/ui/mainwindow.cpp
new file mode 100644 (file)
index 0000000..2646346
--- /dev/null
@@ -0,0 +1,406 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Hyunjin Lee <hyunjin816.lee@samsung.com>
+ * SungMin Ha <sungmin82.ha@samsung.com>
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@samsung.com>
+ * Stanislav Vorobiov
+ *
+ * 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 "mainwindow.h"
+#include "mainform.h"
+#include "displayglwidget.h"
+#include "displayswwidget.h"
+
+extern "C" {
+int qt5_graphic_hw_display(void);
+}
+
+QOpenGLContext *qt5GLContext = NULL;
+QSurfaceFormat qt5GLFormat;
+
+DisplaySwapper::DisplaySwapper(QGLContext* context, QObject* parent)
+    : QObject(parent), context(context), terminating(false)
+{
+    /* do nothing */
+}
+
+void DisplaySwapper::display()
+{
+    /*
+     * TODO: Currently qt5 skin doesn't terminate properly,
+     * check this once proper termination is implemented.
+     */
+
+    if (context) {
+        while (!terminating) {
+            context->makeCurrent();
+            if (qt5_graphic_hw_display()) {
+                context->swapBuffers();
+            }
+            context->doneCurrent();
+        }
+    } else {
+        while (!terminating) {
+            qt5_graphic_hw_display();
+        }
+    }
+}
+
+MainWindow::MainWindow(UIInformation *uiInfo, QWidget *parent)
+    : QWidget(parent)
+{
+    /* initialize */
+    this->uiInfo = uiInfo;
+    this->popupMenu = NULL;
+    this->skinView = NULL;
+    this->display = NULL;
+    this->screenWidget = NULL;
+
+    captureRequestHandler = NULL;
+    captureRequestData = NULL;
+
+    /* windowing */
+    setWindowTitle("Emulator");
+    setWindowIcon(QIcon(QPixmap(":/icons/emulator_icon.ico")));
+
+    //setStyleSheet("background:transparent;");
+    //setAttribute(Qt::WA_TranslucentBackground);
+    setWindowFlags(Qt::FramelessWindowHint);
+
+    winLayout = new QHBoxLayout(this);
+    winLayout->setMargin(0);
+    winLayout->setSpacing(0);
+
+    /* scene */
+    skinScene = new QGraphicsScene(this);
+    skinScene->setBackgroundBrush(Qt::black);
+
+    /* view */
+    skinView = new SkinView(skinScene, this);
+    winLayout->addWidget(skinView);
+
+    /* display */
+    QGLContext *context = NULL;
+    if (qt5GLContext) { /* on-screen rendering */
+        QGLContext *wrapperContext = QGLContext::fromOpenGLContext(qt5GLContext);
+
+        /*
+         * Qt5 bug, wrapperContext->requestedFormat() doesn't return
+         * originating format, it returns actual format, this may result
+         * in wrong OpenGL context version here.
+         */
+
+        QGLFormat format = QGLFormat::fromSurfaceFormat(qt5GLFormat);
+
+        /*
+         * Qt5 bug, format set here doesn't always have effect, must
+         * set it after QGLWidget is created.
+         */
+        context = new QGLContext(format);
+
+        display = new DisplayGLWidget(uiInfo->resolution, context, skinView);
+
+        context->setFormat(format);
+
+        context->create(wrapperContext);
+    } else { /* off-screen rendering */
+        DisplaySWWidget *w = new DisplaySWWidget(uiInfo->resolution, skinView);
+
+        display = w;
+        screenWidget = w;
+    }
+
+    /* popup menu */
+    popupMenu = new ContextMenu(this);
+
+    setContextMenuPolicy(Qt::CustomContextMenu);
+    connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
+        SLOT(showContextMenu(const QPoint&)));
+
+    /* swapper */
+    swapperThread = new QThread(this);
+
+    if (context) {
+        context->doneCurrent();
+        context->moveToThread(swapperThread);
+    }
+
+    swapper = new DisplaySwapper(context);
+    swapper->moveToThread(swapperThread);
+    connect(swapperThread, &QThread::finished, swapper, &QObject::deleteLater);
+
+    swapperThread->start();
+}
+
+void MainWindow::startSwapper()
+{
+    QMetaObject::invokeMethod(swapper, "display", Qt::QueuedConnection);
+}
+
+void MainWindow::terminateSwapper()
+{
+    swapper->setTerminating();
+    qt5_graphic_hw_invalidate();
+}
+
+QLabel *MainWindow::getScreenWidget()
+{
+    return screenWidget;
+}
+
+void MainWindow::showContextMenu(const QPoint& pos)
+{
+    QAction* selectedItem = 0;
+    popupMenu->popup(mapToGlobal(pos), selectedItem);
+    if (selectedItem) {
+        //qDebug("%s", selectedItem->text().toLocal8Bit().data());
+    } else {
+        qDebug("do nothing");
+    }
+}
+
+UIState *MainWindow::getUIState()
+{
+    return &(uiInfo->uiState);
+}
+
+DockingController *MainWindow::getDockingCon()
+{
+    return getUIState()->conState.dockingCon;
+}
+
+FloatingController *MainWindow::getFloatingCon()
+{
+    return getUIState()->conState.floatingCon;
+}
+
+void MainWindow::openController(int index, int dockPos)
+{
+    if (dockPos == (Qt::AlignRight | Qt::AlignCenter)) {
+        qDebug("open right-center docking controller %d", index);
+    } else if (dockPos == (Qt::AlignRight | Qt::AlignTop)) {
+        qDebug("open right-top docking controller %d", index);
+    } else if (dockPos == (Qt::AlignRight | Qt::AlignBottom)) {
+        qDebug("open right-bottom docking controller %d", index);
+    } else if (dockPos == -1) {
+        qDebug("open floating controller %d", index);
+    } else {
+        qDebug("invalid dock position : %d", dockPos);
+        dockPos = -1;
+    }
+
+    closeController();
+
+    if (uiInfo->conFormList.count() <= index) {
+        qWarning("controller index out of range");
+        return;
+    }
+
+    ControllerForm *conForm = uiInfo->conFormList.at(index);
+    if (conForm == NULL) {
+        qWarning("controller is null");
+        return;
+    }
+
+    QAction *action = NULL;
+    if (popupMenu != NULL) {
+        action = (QAction *)popupMenu->getControllerMapper()->mapping(index);
+    }
+
+    /* create */
+    if (dockPos == -1) {
+        getUIState()->conState.floatingCon =
+            new FloatingController(conForm, action, this);
+    } else {
+        getUIState()->conState.dockingCon =
+            new DockingController(conForm, action, dockPos, this);
+        getUIState()->conState.recentlyDockPos = dockPos;
+    }
+
+    /* update layout */
+    getUIState()->conState.conFormIndex = index;
+    adjustSize();
+
+    /* arrange */
+    if (dockPos == -1) {
+        if (getUIState()->conState.recentlyFloatPos == QPoint(-1, -1)) {
+            QPoint globalPos = mapToGlobal(QPoint(0, 0));
+            getFloatingCon()->move(globalPos.x() + size().width(), globalPos.y());
+        } else {
+            getFloatingCon()->move(getUIState()->conState.recentlyFloatPos);
+            getUIState()->conState.recentlyFloatPos = QPoint(-1, -1);
+        }
+
+        getFloatingCon()->show();
+    } else {
+        winLayout->addWidget(getDockingCon());
+    }
+
+    /* Some part of QGLWidget's surface might be lost on Windows when view changing.
+     * So, we need an additional updating for display. */
+    display->update();
+}
+
+void MainWindow::closeController()
+{
+    if (getDockingCon() != NULL) {
+        qDebug("close docking controller");
+
+        getUIState()->conState.recentlyDockPos = -1;
+        winLayout->removeWidget(getDockingCon());
+        getDockingCon()->close();
+
+        getUIState()->conState.dockingCon = NULL;
+
+        adjustSize();
+    }
+
+    if (getFloatingCon() != NULL) {
+        qDebug("close floating controller");
+
+        getUIState()->conState.recentlyFloatPos = getFloatingCon()->pos();
+        getFloatingCon()->close();
+
+        getUIState()->conState.floatingCon = NULL;
+    }
+
+    /* Some part of QGLWidget's surface might be lost on Windows when view changing.
+     * So, we need an additional updating for display. */
+    display->update();
+}
+
+void MainWindow::resizeEvent(QResizeEvent *event)
+{
+    qDebug("resize main window");
+
+    resize(uiInfo->getUiSize());
+
+    setRegion();
+}
+
+void MainWindow::setRegion()
+{
+    //qDebug("set region");
+
+    setMask(uiInfo->getUiRegion());
+}
+
+void MainWindow::rotate(int angle)
+{
+    qDebug("window rotate : %d", angle);
+
+    getUIState()->mainFormAngle = angle;
+
+    skinView->rotate();
+    display->rotate(getUIState()->mainFormAngle);
+
+    adjustSize();
+}
+
+void MainWindow::scale(int scale)
+{
+    qDebug("window scale : %d", scale);
+
+    getUIState()->mainFormScale = scale;
+
+    skinView->adjustSize();
+    display->scale(getUIState()->mainFormScale);
+
+    adjustSize();
+}
+
+void MainWindow::capture(void)
+{
+    qDebug("window screen capture: handler(%p), data(%p)",
+           captureRequestHandler, captureRequestData);
+
+    if (captureRequestHandler && captureRequestData) {
+        captureRequestHandler(captureRequestData);
+    }
+}
+
+void MainWindow::setCaptureRequestHandler(void *data, void (*handler)(void *))
+{
+    captureRequestHandler = handler;
+    captureRequestData = data;
+}
+
+void MainWindow::unsetCaptureRequestHandler(void *data)
+{
+    captureRequestHandler = NULL;
+    captureRequestData = NULL;
+}
+
+void MainWindow::processCaptured(bool captured, void *pixels,
+        int width, int height)
+{
+    qDebug("window process captured: %d pixel: %p [%dx%d]",
+            captured, pixels, width, height);
+
+    if (captured) {
+        QImage image = QImage((uchar *)pixels, width, height, QImage::Format_RGB32);
+        QPixmap pixmap = QPixmap::fromImage(image); /* deep copy the data */
+
+        QMetaObject::invokeMethod(popupMenu, "slotShowScreenshot",
+                                      Qt::QueuedConnection,
+                                      Q_ARG(QPixmap, pixmap));
+        qDebug("Image saved: %p", pixels);
+    } else {
+        QPixmap pixmap(uiInfo->resolution.width(),  uiInfo->resolution.height());
+        QMetaObject::invokeMethod(popupMenu, "slotShowScreenshot", Qt::QueuedConnection, Q_ARG(QPixmap, pixmap));
+        qDebug("Blank Image saved");
+    }
+
+}
+
+void MainWindow::setTopMost(bool on)
+{
+    popupMenu->slotTopMost(on);
+}
+
+MainWindow::~MainWindow()
+{
+    qDebug("destory main window");
+
+    swapperThread->quit();
+    swapperThread->wait();
+}
+
+void MainWindow::closeEvent(QCloseEvent *event)
+{
+    int r = QMessageBox::warning(this,
+                                 "Emulator",
+                                 "Do you really want to quit this program?",
+                                 QMessageBox::Yes | QMessageBox::Default,
+                                 QMessageBox::No);
+    if (r == QMessageBox::Yes) {
+        /* force close */
+        shutdown_qemu_gracefully();
+    } else {
+        event->ignore();
+    }
+}
diff --git a/tizen/src/ui/mainwindow.h b/tizen/src/ui/mainwindow.h
new file mode 100644 (file)
index 0000000..6fa2563
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Hyunjin Lee <hyunjin816.lee@samsung.com>
+ * SungMin Ha <sungmin82.ha@samsung.com>
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@samsung.com>
+ * Stanislav Vorobiov
+ *
+ * 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 MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QWidget>
+#include <QGLContext>
+
+#include "menu/contextmenu.h"
+#include "skinview.h"
+#include "displaybase.h"
+#include "skinbezelitem.h"
+#include "uiinformation.h"
+#include "dockingcontroller.h"
+#include "floatingcontroller.h"
+
+extern "C" {
+#include "skin/maruskin_operation.h"
+}
+
+class DisplaySwapper : public QObject
+{
+    Q_OBJECT
+
+public:
+    DisplaySwapper(QGLContext* context, QObject* parent = 0);
+
+    inline void setTerminating() { terminating = true; }
+
+public slots:
+    void display();
+
+private:
+    QGLContext *context;
+    bool terminating;
+};
+
+class MainWindow : public QWidget
+{
+    Q_OBJECT
+
+public:
+    explicit MainWindow(UIInformation *uiInfo, QWidget *parent = 0);
+    ~MainWindow();
+
+    UIState *getUIState(void);
+    QLabel *getScreenWidget();
+    void rotate(int angle);
+    void scale(int scale);
+    void capture(void);
+    void setCaptureRequestHandler(void *data, void (*handler)(void *));
+    void unsetCaptureRequestHandler(void *data);
+    void processCaptured(bool captured, void *pixels, int width, int height);
+    void setTopMost(bool on);
+    DockingController *getDockingCon();
+    FloatingController *getFloatingCon();
+    void openController(int index, int dockPos);
+    void closeController();
+    void startSwapper();
+    void terminateSwapper();
+
+    UIInformation *uiInfo;
+
+public slots:
+    void showContextMenu(const QPoint& pos);
+
+protected:
+    void resizeEvent(QResizeEvent *event);
+    void closeEvent(QCloseEvent *);
+
+    void setRegion();
+    QLabel *screenWidget;
+
+private:
+    /* windowing */
+    QHBoxLayout *winLayout;
+    QGraphicsScene *skinScene;
+    SkinView* skinView;
+    DisplayBase *display;
+    ContextMenu *popupMenu;
+    QThread *swapperThread;
+    DisplaySwapper *swapper;
+
+    void (*captureRequestHandler)(void *data);
+    void *captureRequestData;
+};
+
+#endif // MAINWINDOW_H
diff --git a/tizen/src/ui/menu/Makefile.objs b/tizen/src/ui/menu/Makefile.objs
new file mode 100644 (file)
index 0000000..7e5454e
--- /dev/null
@@ -0,0 +1,18 @@
+obj-$(CONFIG_QT) += aboutdialog.o moc_aboutdialog.o
+obj-$(CONFIG_QT) += screenshot.o moc_screenshot.o
+obj-$(CONFIG_QT) += detailedinfodialog.o moc_detailedinfodialog.o
+obj-$(CONFIG_QT) += contextmenu.o moc_contextmenu.o
+obj-$(CONFIG_QT) += screenshotview.o
+
+$(obj)/moc_aboutdialog.o: $(obj)/moc_aboutdialog.cpp
+$(obj)/moc_aboutdialog.cpp: $(obj)/aboutdialog.h
+       moc $< -o $@
+$(obj)/moc_detailedinfodialog.o: $(obj)/moc_detailedinfodialog.cpp
+$(obj)/moc_detailedinfodialog.cpp: $(obj)/detailedinfodialog.h
+       moc $< -o $@
+$(obj)/moc_contextmenu.o: $(obj)/moc_contextmenu.cpp
+$(obj)/moc_contextmenu.cpp: $(obj)/contextmenu.h
+       moc $< -o $@
+$(obj)/moc_screenshot.o: $(obj)/moc_screenshot.cpp
+$(obj)/moc_screenshot.cpp: $(obj)/screenshot.h
+       moc $< -o $@
diff --git a/tizen/src/ui/menu/aboutdialog.cpp b/tizen/src/ui/menu/aboutdialog.cpp
new file mode 100644 (file)
index 0000000..14f5d16
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "aboutdialog.h"
+#include "build_info.h"
+
+#define SDK_NAME "Tizen SDK"
+#define URL_TIZEN_ORG "<a href=\"https://developer.tizen.org\">https://developer.tizen.org</a>";
+
+AboutDialog::AboutDialog(QWidget *parent) :
+    QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint)
+{
+    setWindowTitle("About Emulator");
+
+    QVBoxLayout *baseLayout = new QVBoxLayout(this);
+    baseLayout->setMargin(0);
+    baseLayout->setSpacing(5);
+
+    /* upside */
+    QHBoxLayout *upsideLayout = new QHBoxLayout();
+    upsideLayout->setMargin(0);
+    upsideLayout->setSpacing(0);
+
+    QLabel *imageLabel = new QLabel(this);
+    imageLabel->setPixmap(QPixmap(":about.png"));
+    upsideLayout->addWidget(imageLabel);
+
+    QSettings sdkVersion("../../../sdk.version", QSettings::IniFormat);
+    QString version = sdkVersion.value("TIZEN_SDK_VERSION").toString();
+    if (version.isEmpty() == true) {
+        qWarning("failed to load SDK version");
+        version = "Undefined";
+    }
+
+    QString SnapshotName = "Undefined";
+    QFile file("../../../install-manager/installmanager.conf");
+    if (file.open(QIODevice::ReadOnly | QIODevice::Text) == true) {
+        QTextStream in(&file);
+        while (!in.atEnd()) {
+            QString line = in.readLine();
+            if (line.startsWith("Snapshot-Path", Qt::CaseInsensitive) == true) {
+                QStringList snapshotPath = line.split(":", QString::SkipEmptyParts)[1].split("/");
+                SnapshotName = snapshotPath.last().trimmed();
+                qDebug() << "Snapshot Name :" << SnapshotName;
+            }
+        }
+
+        file.close();
+    } else {
+        qWarning("failed to load snapshot name");
+    }
+
+    QString aboutText = QString(SDK_NAME) + "<p>"
+        + "Version : " + version + "<br>"
+        + "Snapshot : " + SnapshotName + "<br>"
+        + "Build Date : " + QString(build_date) + "<p><br>"
+        + "Visit " + URL_TIZEN_ORG;
+
+    QLabel *textLabel = new QLabel(this);
+    textLabel->setStyleSheet("background-color: white");
+    textLabel->setTextFormat(Qt::RichText);
+    //textLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
+    textLabel->setOpenExternalLinks(true);
+    textLabel->setMargin(10);
+    textLabel->setText(aboutText);
+    upsideLayout->addWidget(textLabel);
+
+    baseLayout->addLayout(upsideLayout);
+
+    /* downside */
+    QHBoxLayout *downsideLayout = new QHBoxLayout();
+    downsideLayout->setAlignment(Qt::AlignRight);
+    downsideLayout->setMargin(10);
+
+    QPushButton *okBtn = new QPushButton("OK", this);
+    connect(okBtn, SIGNAL(clicked()), this, SLOT(close()));
+    downsideLayout->addWidget(okBtn);
+
+    baseLayout->addLayout(downsideLayout);
+}
+
+void AboutDialog::showEvent(QShowEvent *event)
+{
+    Q_UNUSED(event)
+
+    QWidget *win = ((QWidget *)this->parent());
+    move(win->geometry().center().x() - (geometry().size().width() / 2),
+        win->geometry().center().y() - (geometry().size().height() / 2));
+}
+
+AboutDialog::~AboutDialog()
+{
+    qDebug("destroy about dialog");
+}
diff --git a/tizen/src/ui/menu/aboutdialog.h b/tizen/src/ui/menu/aboutdialog.h
new file mode 100644 (file)
index 0000000..f81c96d
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 ABOUTDIALOG_H
+#define ABOUTDIALOG_H
+
+#include <QtWidgets>
+
+class AboutDialog : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit AboutDialog(QWidget *parent = 0);
+    ~AboutDialog();
+
+protected:
+    void showEvent(QShowEvent *event);
+};
+
+#endif // ABOUTDIALOG_H
diff --git a/tizen/src/ui/menu/contextmenu.cpp b/tizen/src/ui/menu/contextmenu.cpp
new file mode 100644 (file)
index 0000000..85f4002
--- /dev/null
@@ -0,0 +1,663 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * SungMin Ha <sungmin82.ha@samsung.com>
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 <QtWidgets>
+
+#include "contextmenu.h"
+#include "mainwindow.h"
+
+#ifdef CONFIG_WIN32
+#include <windows.h>
+#elif defined (CONFIG_LINUX)
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#endif
+
+ContextMenu::ContextMenu(QWidget *parent) : QMenu(parent)
+{
+    this->parent = (MainWindow *)parent;
+    this->infoDialog = NULL;
+    this->aboutDialog = NULL;
+    this->screenshotDialog = NULL;
+    this->vmName = ((MainWindow *)parent)->uiInfo->vmName + " : "
+        + QString::number(get_device_serial_number());
+
+    actionDetailedInfo = NULL;
+    actionTopMost = NULL;
+    actionShell = NULL;
+    actionControlPanel = NULL;
+    actionAbout = NULL;
+    actionForceClose = NULL;
+    actionClose = NULL;
+
+    longPressTimer = new QTimer(this);
+
+    createItems();
+
+    installEventFilter(this);
+}
+
+void ContextMenu::createItems() {
+    MainWindow *win = parent;
+    QAction *action = NULL;
+
+    /* Detailed Info menu */
+    actionDetailedInfo = addAction(vmName);
+    actionDetailedInfo->setIcon(QIcon(QPixmap(":/icons/detailed_info.png")));
+    connect(actionDetailedInfo, SIGNAL(triggered()), this, SLOT(slotDetailedInfo()));
+
+    addSeparator();
+
+    /* Always On Top menu */
+    actionTopMost = addAction("&Always on Top");
+    actionTopMost->setCheckable(true);
+    connect(actionTopMost, SIGNAL(triggered(bool)), this, SLOT(slotTopMost(bool)));
+
+    /* = Rotate menu = */
+    if (win->uiInfo->mainFormList.count() > 1) {
+        QMenu *rotateMenu = addMenu(QIcon(QPixmap(":/icons/rotate.png")), "&Rotate");
+        QActionGroup *rotateGroup = new QActionGroup(this);
+        rotateMapper = new QSignalMapper(this);
+        connect(rotateMapper, SIGNAL(mapped(int)), this, SLOT(slotRotate(int)));
+
+        action = rotateMenu->addAction("Portrait");
+        action->setActionGroup(rotateGroup);
+        action->setCheckable(true);
+        rotateMapper->setMapping(action, 0);
+        connect(action, SIGNAL(triggered()), rotateMapper, SLOT(map()));
+
+        action = rotateMenu->addAction("Landscape");
+        action->setActionGroup(rotateGroup);
+        action->setCheckable(true);
+        rotateMapper->setMapping(action, 270);
+        connect(action, SIGNAL(triggered()), rotateMapper, SLOT(map()));
+
+        action = rotateMenu->addAction("Reverse Portrait");
+        action->setActionGroup(rotateGroup);
+        action->setCheckable(true);
+        rotateMapper->setMapping(action, 180);
+        connect(action, SIGNAL(triggered()), rotateMapper, SLOT(map()));
+
+        action = rotateMenu->addAction("Reverse Landscape");
+        action->setActionGroup(rotateGroup);
+        action->setCheckable(true);
+        rotateMapper->setMapping(action, 90);
+        connect(action, SIGNAL(triggered()), rotateMapper, SLOT(map()));
+
+        action = (QAction *)rotateMapper->mapping(win->getUIState()->mainFormAngle);
+        action->setChecked(true);
+    }
+    /* =============== */
+
+    /* = Scale menu = */
+    QMenu *scaleMenu = addMenu(QIcon(QPixmap(":/icons/scale.png")), "&Scale");
+    QActionGroup *scaleGroup = new QActionGroup(this);
+    scaleMapper = new QSignalMapper(this);
+    connect(scaleMapper, SIGNAL(mapped(int)), this, SLOT(slotScale(int)));
+
+    action = scaleMenu->addAction("1x");
+    action->setActionGroup(scaleGroup);
+    action->setCheckable(true);
+    scaleMapper->setMapping(action, 100);
+    connect(action, SIGNAL(triggered()), scaleMapper, SLOT(map()));
+
+    action = scaleMenu->addAction("3/4x");
+    action->setActionGroup(scaleGroup);
+    action->setCheckable(true);
+    scaleMapper->setMapping(action, 75);
+    connect(action, SIGNAL(triggered()), scaleMapper, SLOT(map()));
+
+    action = scaleMenu->addAction("1/2x");
+    action->setActionGroup(scaleGroup);
+    action->setCheckable(true);
+    scaleMapper->setMapping(action, 50);
+    connect(action, SIGNAL(triggered()), scaleMapper, SLOT(map()));
+
+    action = scaleMenu->addAction("1/4x");
+    action->setActionGroup(scaleGroup);
+    action->setCheckable(true);
+    scaleMapper->setMapping(action, 25);
+    connect(action, SIGNAL(triggered()), scaleMapper, SLOT(map()));
+
+    // TODO: interpolation
+
+    action = (QAction *)scaleMapper->mapping(win->getUIState()->mainFormScale);
+    action->setChecked(true);
+    /* ============== */
+
+    /* = Controller menu = */
+    QMenu *controllerMenu = NULL;
+    if (win->uiInfo->conFormList.isEmpty() == false) {
+        controllerMenu = addMenu("Controller");
+        QActionGroup *controllerGroup = new QActionGroup(this);
+        controllerMapper = new QSignalMapper(this);
+        connect(controllerMapper, SIGNAL(mapped(int)), this, SLOT(slotController(int)));
+
+        action = controllerMenu->addAction("None");
+        action->setActionGroup(controllerGroup);
+        action->setCheckable(true);
+        action->setChecked(true);
+        connect(action, SIGNAL(triggered()), this, SLOT(slotCloseCon()));
+
+        for (int i = 0; i < win->uiInfo->conFormList.count(); i++) {
+            action = controllerMenu->addAction(win->uiInfo->conFormList.at(i)->name);
+            action->setActionGroup(controllerGroup);
+            action->setCheckable(true);
+            controllerMapper->setMapping(action, i);
+            connect(action, SIGNAL(triggered()), controllerMapper, SLOT(map()));
+        }
+    }
+
+    addSeparator();
+
+    /* = Advanced menu = */
+    QMenu *advancedMenu = addMenu(QIcon(QPixmap(":/icons/advanced.png")), "Ad&vanced");
+
+    /* Advanced > Screen Shot menu */
+    action = advancedMenu->addAction("Screen Shot");
+    action->setIcon(QIcon(QPixmap(":/icons/screen_shot.png")));
+    connect(action, SIGNAL(triggered()), this, SLOT(slotRequestScreenshot()));
+
+    /* = Host Keyboard menu = */
+    QMenu *keyboardMenu = advancedMenu->addMenu(
+        QIcon(QPixmap(":/icons/host_keyboard.png")), "&Host Keyboard");
+    QActionGroup *keyboardGroup = new QActionGroup(this);
+
+    action = keyboardMenu->addAction("On");
+    action->setActionGroup(keyboardGroup);
+    action->setCheckable(true);
+    connect(action, SIGNAL(toggled(bool)), this, SLOT(slotHostKeyboard(bool)));
+
+    action = keyboardMenu->addAction("Off");
+    action->setActionGroup(keyboardGroup);
+    action->setCheckable(true);
+    action->setChecked(true);
+
+    advancedMenu->addSeparator();
+
+    /* Advanced > About menu */
+    actionAbout = advancedMenu->addAction("&About");
+    actionAbout->setIcon(QIcon(QPixmap(":/icons/about.png")));
+    connect(actionAbout, SIGNAL(triggered()), this, SLOT(slotAbout()));
+
+    /* Advanced > Force Close menu */
+    actionForceClose = advancedMenu->addAction("&Force Close");
+    actionForceClose->setIcon(QIcon(QPixmap(":/icons/force_close.png")));
+    connect(actionForceClose, SIGNAL(triggered()), this, SLOT(slotForceClose()));
+    /* ================= */
+
+    /* Shell menu */
+    actionShell = addAction("S&hell");
+    actionShell->setIcon(QIcon(QPixmap(":/icons/shell.png")));
+    connect(actionShell, SIGNAL(triggered()), this, SLOT(slotShell()));
+
+    /* Control Panel menu */
+    actionControlPanel = addAction("Control &Panel");
+    actionControlPanel->setIcon(QIcon(QPixmap(":/icons/control_panel.png")));
+    connect(actionControlPanel, SIGNAL(triggered()), this, SLOT(slotControlPanel()));
+
+    addSeparator();
+
+    /* Close menu */
+    actionClose = addAction("&Close");
+    actionClose->setIcon(QIcon(QPixmap(":/icons/close.png")));
+    connect(actionClose, SIGNAL(triggered()), this, SLOT(slotClose()));
+}
+
+bool ContextMenu::eventFilter(QObject *obj, QEvent *event)
+{
+    ContextMenu *menu = dynamic_cast<ContextMenu *>(obj);
+
+    if (menu != NULL &&
+        (event->type() == QEvent::MouseButtonPress ||
+            event->type() == QEvent::MouseButtonRelease)) {
+        QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent*>(event);
+
+        if (mouseEvent != NULL && mouseEvent->button() == Qt::RightButton) {
+            mouseEvent->ignore(); /* filtering */
+            return true;
+        }
+    }
+
+    return QObject::eventFilter(obj, event);
+}
+
+void ContextMenu::slotDetailedInfo()
+{
+    qDebug("VM info");
+
+    if (infoDialog == NULL) {
+        infoDialog = new DetailedInfoDialog((QWidget *)parent);
+    }
+
+    infoDialog->show();
+}
+
+void ContextMenu::slotTopMost(bool on)
+{
+    qDebug("stays on top : %s", on? "on" : "off");
+
+#ifdef CONFIG_WIN32
+    HWND hWnd = (HWND)parent->winId();
+    HWND hWndInsertAfter = ((on == true) ? HWND_TOPMOST : HWND_NOTOPMOST);
+    SetWindowPos(hWnd, hWndInsertAfter, parent->pos().x(), parent->pos().y(), 0, 0, SWP_NOSIZE);
+#elif defined(CONFIG_LINUX)
+    Display* display = XOpenDisplay(NULL);
+    if (display == NULL) {
+        qDebug("Error: XOpenDisplay() Failed. Always on top failed.");
+        return;
+    }
+
+    XClientMessageEvent event;
+    memset(&event, 0, sizeof(event));
+    event.type = ClientMessage;
+    event.window = parent->winId();
+    event.message_type = XInternAtom(display, "_NET_WM_STATE", False);
+    event.format = 32;
+    event.data.l[0] = on ? 1 : 0; /* 1:_NET_WM_STATE_ADD, 0:_NET_WM_STATE_REMOVE */
+    event.data.l[1] = XInternAtom(display, "_NET_WM_STATE_ABOVE", False);
+    event.data.l[2] = 0; /* unused */
+    event.data.l[3] = 0;
+    event.data.l[4] = 0;
+
+    XSendEvent(display, DefaultRootWindow(display), False,
+        SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&event);
+    XFlush(display);
+
+    XCloseDisplay(display);
+#elif defined(CONFIG_DARWIN)
+    if (on == true) {
+        parent->setWindowFlags(parent->windowFlags() | Qt::WindowStaysOnTopHint);
+    } else {
+        parent->setWindowFlags(parent->windowFlags() & ~(Qt::WindowStaysOnTopHint));
+    }
+
+    parent->show();
+#endif
+
+    actionTopMost->setChecked(on);
+    parent->getUIState()->setOnTop(on);
+}
+
+void ContextMenu::slotRotate(int angle)
+{
+    qDebug("rotate : %d", angle);
+
+    parent->rotate(angle);
+}
+
+void ContextMenu::slotScale(int scale)
+{
+    qDebug("scale : %d", scale);
+
+    parent->scale(scale);
+}
+
+void ContextMenu::slotController(int index)
+{
+    qDebug("controller : %d", index);
+
+    parent->openController(index,
+        parent->getUIState()->conState.recentlyDockPos);
+}
+
+void ContextMenu::slotCloseCon()
+{
+    qDebug("controller : None");
+
+    parent->closeController();
+    parent->getUIState()->conState.conFormIndex = -1;
+}
+
+void ContextMenu::slotShell()
+{
+    qDebug("SDB shell");
+
+    if (is_sdbd_initialized == 0) {
+        QString msg = "SDB is not ready.\nPlease wait until the emulator is completely boot up.";
+        qDebug() << msg;
+
+        QMessageBox *msgBox = new QMessageBox(QMessageBox::Information,
+            "Emulator", msg, QMessageBox::Ok, (QWidget*)parent);
+        msgBox->setAttribute(Qt::WA_DeleteOnClose);
+        msgBox->setModal(false);
+        msgBox->show();
+
+        return;
+    }
+
+    QString sdbPort = QString::number(get_device_serial_number());
+    QString sdbSerialName = "emulator-" + sdbPort;
+
+    QString sdbPath = QCoreApplication::applicationDirPath();
+#ifdef CONFIG_WIN32
+    sdbPath += "\\..\\..\\ansicon.exe";
+#else
+    sdbPath += "/../../sdb";
+#endif
+
+    QFileInfo sdbFileInfo(sdbPath);
+    if (sdbFileInfo.exists() == false) {
+        QString msg = "SDB file does not exist in the following path.\n"
+            + sdbFileInfo.absoluteFilePath();
+        qWarning() << msg;
+
+        QMessageBox *msgBox = new QMessageBox(QMessageBox::Warning,
+            "Emulator", msg, QMessageBox::Ok, (QWidget*)parent);
+        msgBox->setAttribute(Qt::WA_DeleteOnClose);
+        msgBox->setModal(false);
+        msgBox->show();
+
+        return;
+    }
+
+    QString command;
+    QStringList arguments;
+
+#ifdef CONFIG_WIN32
+    command = "cmd.exe";
+    arguments << "/c" << "start" << sdbPath << "sdb" << "-s" << sdbSerialName << "shell";
+#elif defined CONFIG_DARWIN
+    command = QCoreApplication::applicationDirPath() + "/sdbscript";
+    arguments << sdbSerialName;
+#else
+    command = "/usr/bin/gnome-terminal";
+    QString title = "--title=" + vmName;
+    arguments << title << "-x" << sdbPath << "-s" << sdbSerialName << "shell";
+#endif
+
+    qDebug() << command << arguments;
+
+    try {
+        QProcess::startDetached(command, arguments);
+    } catch (QString error) {
+        QString msg = "Failed to open Shell : " + error;
+        qDebug() << msg;
+
+        QMessageBox *msgBox = new QMessageBox(QMessageBox::Warning,
+            "Emulator", msg, QMessageBox::Ok ,(QWidget*)parent);
+        msgBox->setAttribute(Qt::WA_DeleteOnClose);
+        msgBox->setModal(false);
+        msgBox->show();
+
+        return;
+    }
+}
+
+#ifdef CONFIG_WIN32
+#define JAVA_MAX_COMMAND_LENGTH  1024
+#define MY_KEY_WOW64_64KEY       0x0100
+
+typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
+LPFN_ISWOW64PROCESS menu_fnIsWow64Process;
+
+static int menu_is_wow64(void)
+{
+    int result = 0;
+
+    /* IsWow64Process is not available on all supported versions of Windows.
+       Use GetModuleHandle to get a handle to the DLL that contains the function
+       and GetProcAddress to get a pointer to the function if available. */
+
+    menu_fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
+        GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
+
+    if (NULL != menu_fnIsWow64Process) {
+        if (!menu_fnIsWow64Process(GetCurrentProcess(),&result)) {
+            // handle error
+            //fprintf(stderr, "Cannot find 'IsWow64Process'\n");
+        }
+    }
+    return result;
+}
+
+static bool menu_get_java_path(char** java_path)
+{
+    HKEY hKeyNew;
+    HKEY hKey;
+    //char strJavaRuntimePath[JAVA_MAX_COMMAND_LENGTH] = {0};
+    char strChoosenName[JAVA_MAX_COMMAND_LENGTH] = {0};
+    char strSubKeyName[JAVA_MAX_COMMAND_LENGTH] = {0};
+    char strJavaHome[JAVA_MAX_COMMAND_LENGTH] = {0};
+    int index;
+    DWORD dwSubKeyNameMax = JAVA_MAX_COMMAND_LENGTH;
+    DWORD dwBufLen = JAVA_MAX_COMMAND_LENGTH;
+
+    RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                "SOFTWARE\\JavaSoft\\Java Runtime Environment",
+                0,
+                KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | MY_KEY_WOW64_64KEY,
+                &hKey);
+    RegEnumKeyEx(hKey, 0, (LPSTR)strSubKeyName, &dwSubKeyNameMax,
+                NULL, NULL, NULL, NULL);
+    strcpy(strChoosenName, strSubKeyName);
+
+    index = 1;
+    while (ERROR_SUCCESS ==
+            RegEnumKeyEx(hKey, index, (LPSTR)strSubKeyName, &dwSubKeyNameMax,
+            NULL, NULL, NULL, NULL)) {
+        if (strcmp(strChoosenName, strSubKeyName) < 0) {
+            strcpy(strChoosenName, strSubKeyName);
+        }
+        index++;
+    }
+
+    RegOpenKeyEx(hKey, strChoosenName, 0,
+                KEY_QUERY_VALUE | MY_KEY_WOW64_64KEY, &hKeyNew);
+    RegQueryValueEx(hKeyNew, "JavaHome", NULL,
+                    NULL, (LPBYTE)strJavaHome, &dwBufLen);
+    RegCloseKey(hKey);
+
+    if (strJavaHome[0] != '\0') {
+        sprintf(*java_path, "%s\\bin\\javaw.exe", strJavaHome);
+    } else {
+        return false;
+    }
+
+    return true;
+}
+#endif
+
+void ContextMenu::showPopup(QString msg)
+{
+    qDebug() << msg;
+
+    QMessageBox *msgBox = new QMessageBox(QMessageBox::Warning,
+        "Emulator", msg, QMessageBox::Ok, (QWidget*)parent);
+    msgBox->setAttribute(Qt::WA_DeleteOnClose);
+    msgBox->setModal(false);
+    msgBox->show();
+}
+
+void ContextMenu::slotControlPanel()
+{
+    qDebug("Control Panel");
+
+    MainWindow *win = (MainWindow *)parent;
+    QString basePortOpt = "base.port=" + QString::number(win->uiInfo->basePort);
+    QString vmNameOpt = "vmname=" + win->uiInfo->vmName;
+
+    QString ecpPath = QCoreApplication::applicationDirPath();
+#ifdef CONFIG_WIN32
+    ecpPath += "\\emulator-control-panel.jar";
+#else
+    ecpPath += "/emulator-control-panel.jar";
+#endif
+
+    QFileInfo ecpFileInfo(ecpPath);
+    if (!ecpFileInfo.exists()) {
+        showPopup("Control Panel file does not exist in the following path.\n"
+            + ecpFileInfo.absoluteFilePath());
+        return;
+    }
+
+    QString command;
+    QStringList arguments;
+#ifdef CONFIG_WIN32
+    char* path = (char*)malloc(JAVA_MAX_COMMAND_LENGTH);
+    memset(path, 0, sizeof(char) * JAVA_MAX_COMMAND_LENGTH);
+
+    if (menu_is_wow64()) {
+        arguments << "-d64";
+
+        if (menu_get_java_path(&path)) {
+            command = QString::fromLocal8Bit(path);
+        } else {
+            showPopup("Failed to get java path.");
+            free(path);
+            return;
+        }
+    } else {
+        command = "javaw.exe";
+    }
+    free(path);
+#else
+    command = "java";
+#endif
+
+#ifdef CONFIG_DARWIN
+    /* SWT Display must be created on main thread due to Cocoa restrictions */
+    arguments << "-XstartOnFirstThread";
+#endif
+    arguments << "-jar" << ecpPath << vmNameOpt << basePortOpt;
+
+    qDebug() << command << arguments;
+
+    try {
+        QProcess::startDetached(command, arguments);
+    } catch (QString error) {
+        showPopup("Failed to open Control Panel : " + error);
+        return;
+    }
+}
+
+void ContextMenu::slotRequestScreenshot()
+{
+    qDebug("request screenshot");
+
+    parent->capture();
+}
+
+void ContextMenu::slotShowScreenshot(const QPixmap &screenshot)
+{
+    qDebug("show screenshot");
+
+    if (screenshotDialog == NULL) {
+        screenshotDialog = new Screenshot(this, screenshot);
+    }
+
+    screenshotDialog->refresh(screenshot);
+    screenshotDialog->show();
+}
+
+void ContextMenu::slotHostKeyboard(bool on)
+{
+    qDebug("host keyboard : %s", on? "on" : "off");
+
+    do_host_kbd_enable(on);
+}
+
+void ContextMenu::slotAbout()
+{
+    qDebug("about");
+
+    if (aboutDialog == NULL) {
+        aboutDialog = new AboutDialog((QWidget *)parent);
+    }
+
+    aboutDialog->show();
+}
+
+void ContextMenu::slotForceClose()
+{
+    qDebug("force close");
+
+    QMessageBox *msg = new QMessageBox((QWidget*)parent);
+    msg->setAttribute(Qt::WA_DeleteOnClose);
+    msg->setWindowTitle("Emulator");
+    msg->setText("If you force stop an emulator, it may cause some problems.\n"
+        "Are you sure you want to continue?");
+    msg->setStandardButtons(QMessageBox::Yes|QMessageBox::No);
+    msg->setDefaultButton(QMessageBox::Yes);
+    msg->setIcon(QMessageBox::Question);
+    msg->setModal(false);
+    msg->show();
+    connect(msg, SIGNAL(buttonClicked(QAbstractButton *)),
+                            this, SLOT(slotForceCloseSelected(QAbstractButton *)));
+}
+
+void ContextMenu::slotForceCloseSelected(QAbstractButton *btn)
+{
+    if (btn->text().compare("&Yes") == 0) {
+        qDebug() << "exit!";
+        /* force close */
+        shutdown_qemu_gracefully();
+    } else {
+        qDebug() << "cancel";
+    }
+}
+
+void ContextMenu::slotPwkeyRelease()
+{
+    do_hw_key_event(KEY_RELEASED, HARD_KEY_POWER);
+}
+
+void ContextMenu::slotClose()
+{
+    qDebug("close");
+    do_hw_key_event(KEY_PRESSED, HARD_KEY_POWER);
+
+    longPressTimer->setInterval(CLOSE_POWER_KEY_INTERVAL);
+    longPressTimer->setSingleShot(true);
+    connect(longPressTimer, SIGNAL(timeout()), this, SLOT(slotPwkeyRelease()));
+    longPressTimer->start();
+}
+
+QSignalMapper *ContextMenu::getRotateMapper()
+{
+    return rotateMapper;
+}
+
+QSignalMapper *ContextMenu::getScaleMapper()
+{
+    return scaleMapper;
+}
+
+QSignalMapper *ContextMenu::getControllerMapper()
+{
+    return controllerMapper;
+}
+
+ContextMenu::~ContextMenu()
+{
+    qDebug("destroy menu");
+
+    longPressTimer->stop();
+}
diff --git a/tizen/src/ui/menu/contextmenu.h b/tizen/src/ui/menu/contextmenu.h
new file mode 100644 (file)
index 0000000..33a2b1d
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * SungMin Ha <sungmin82.ha@samsung.com>
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 CONTEXTMENU_H
+#define CONTEXTMENU_H
+
+#include <QtWidgets>
+
+#include "detailedinfodialog.h"
+#include "aboutdialog.h"
+#include "screenshot.h"
+
+class MainWindow;
+
+extern "C" {
+#include "skin/maruskin_operation.h"
+#include "skin/maruskin_server.h"
+#include "emul_state.h"
+}
+
+#define CLOSE_POWER_KEY_INTERVAL 1200 /* milli-seconds */
+
+class ContextMenu : public QMenu
+{
+    Q_OBJECT
+
+public:
+    explicit ContextMenu(QWidget *parent = 0);
+    ~ContextMenu();
+
+    QSignalMapper *getRotateMapper();
+    QSignalMapper *getScaleMapper();
+    QSignalMapper *getControllerMapper();
+    Screenshot *screenshotDialog;
+
+signals:
+
+public slots:
+    void slotDetailedInfo();
+    void slotTopMost(bool on);
+    void slotRotate(int angle);
+    void slotScale(int scale);
+    void slotController(int index);
+    void slotCloseCon();
+    void slotShell();
+    void slotControlPanel();
+    void slotRequestScreenshot();
+    void slotShowScreenshot(const QPixmap &);
+    void slotHostKeyboard(bool on);
+    void slotAbout();
+    void slotForceClose();
+    void slotForceCloseSelected(QAbstractButton *);
+    void slotClose();
+    void slotPwkeyRelease();
+
+protected:
+    void createItems();
+    bool eventFilter(QObject *obj, QEvent *event);
+
+private:
+    MainWindow *parent;
+
+    QString vmName;
+    DetailedInfoDialog *infoDialog;
+    AboutDialog *aboutDialog;
+    QTimer *longPressTimer;
+
+    QSignalMapper *rotateMapper;
+    QSignalMapper *scaleMapper;
+    QSignalMapper *controllerMapper;
+
+    QAction *actionDetailedInfo;
+    QAction *actionTopMost;
+    QAction *actionShell;
+    QAction *actionControlPanel;
+    QAction *actionAbout;
+    QAction *actionForceClose;
+    QAction *actionClose;
+
+    void showPopup(QString msg);
+};
+#endif // CONTEXTMENU_H
diff --git a/tizen/src/ui/menu/detailedinfodialog.cpp b/tizen/src/ui/menu/detailedinfodialog.cpp
new file mode 100644 (file)
index 0000000..1650546
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "detailedinfodialog.h"
+#include "mainwindow.h"
+
+extern int _qemu_argc;
+extern char **_qemu_argv;
+
+extern char tizen_target_img_path[]; //TODO: not legacy
+
+DetailedInfoDialog::DetailedInfoDialog(QWidget *parent) :
+    QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint)
+{
+    QStringList imagePathList = getImagePathList();
+    MainWindow *win = ((MainWindow *)parent);
+
+    setWindowTitle("Detailed Info");
+
+    baseLayout = new QVBoxLayout(this);
+    baseLayout->setMargin(10);
+    baseLayout->setSpacing(10);
+
+    /* upside */
+    upsideLayout = new QHBoxLayout(this);
+    upsideLayout->setMargin(0);
+    upsideLayout->setSpacing(0);
+
+    /* VM information table */
+    infoTable = new QTableWidget(this);
+    infoTable->setRowCount(11);
+    infoTable->setColumnCount(2);
+    infoTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
+    infoTable->setAlternatingRowColors(true);
+
+    infoTable->verticalHeader()->hide();
+    infoTable->resizeRowsToContents();
+    infoTable->horizontalHeader()->setStretchLastSection(true);
+    infoTable->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
+
+    QStringList header;
+    header << "Feature" << "Value";
+    infoTable->setHorizontalHeaderLabels(header);
+
+    /* table items */
+    int index = 0;
+    item = new QTableWidgetItem("VM Name");
+    infoTable->setItem(index, 0, item);
+    item = new QTableWidgetItem(win->uiInfo->vmName);
+    infoTable->setItem(index++, 1, item);
+
+    item = new QTableWidgetItem("Skin Name");
+    infoTable->setItem(index, 0, item);
+    item = new QTableWidgetItem(win->uiInfo->skinName);
+    infoTable->setItem(index++, 1, item);
+
+    item = new QTableWidgetItem("CPU");
+    infoTable->setItem(index, 0, item);
+    item = new QTableWidgetItem("x86");
+    infoTable->setItem(index++, 1, item);
+
+    item = new QTableWidgetItem("Ram Size");
+    infoTable->setItem(index, 0, item);
+    item = new QTableWidgetItem(QString(get_emul_ram_size()) + " MB");
+    infoTable->setItem(index++, 1, item);
+
+    item = new QTableWidgetItem("Display Resolution");
+    infoTable->setItem(index, 0, item);
+    item = new QTableWidgetItem(QString::number(win->uiInfo->resolution.width())
+        + "x" + QString::number(win->uiInfo->resolution.height()));
+    infoTable->setItem(index++, 1, item);
+
+#if 0
+    item = new QTableWidgetItem("Display Density");
+    infoTable->setItem(index, 0, item);
+    item = new QTableWidgetItem("0"); // TODO:
+    infoTable->setItem(index++, 1, item);
+#endif
+
+    item = new QTableWidgetItem("File Sharing Path");
+    infoTable->setItem(index, 0, item);
+    QString sharingPath(get_emul_file_sharing_path());
+    item = new QTableWidgetItem((sharingPath.isEmpty()) ? "None" : sharingPath);
+    infoTable->setItem(index++, 1, item);
+
+    item = new QTableWidgetItem("CPU Virtualization");
+    infoTable->setItem(index, 0, item);
+    item = new QTableWidgetItem((get_emul_cpu_accel()) ? "Enabled" : "Disabled");
+    infoTable->setItem(index++, 1, item);
+
+    item = new QTableWidgetItem("GPU Virtualization");
+    infoTable->setItem(index, 0, item);
+    item = new QTableWidgetItem((get_emul_gpu_accel()) ? "Enabled" : "Disabled");
+    infoTable->setItem(index++, 1, item);
+
+    for (int i = 0; i < imagePathList.size(); i++) {
+        item = new QTableWidgetItem("Image Path " + QString::number(i + 1));
+        infoTable->setItem(index, 0, item);
+        item = new QTableWidgetItem(imagePathList[i]);
+        item->setToolTip(imagePathList[i]);
+        infoTable->setItem(index++, 1, item);
+    }
+    item = new QTableWidgetItem("Log Path");
+    infoTable->setItem(index, 0, item);
+    item = new QTableWidgetItem(get_log_path());
+    item->setToolTip(get_log_path());
+    infoTable->setItem(index++, 1, item);
+
+    /* temp */
+    item = new QTableWidgetItem("Logging Telnet Port");
+    infoTable->setItem(index, 0, item);
+    item = new QTableWidgetItem(QString::number(get_emul_serial_port()));
+    infoTable->setItem(index++, 1, item);
+
+    /* add double click event listener */
+    connect(infoTable, SIGNAL(cellDoubleClicked(int, int)), this, SLOT(slotDoubleClicked(int, int)));
+
+    int tableHeight = infoTable->horizontalHeader()->height();
+    for (int i = 0; i < infoTable->rowCount(); i++) {
+            tableHeight += infoTable->rowHeight(i);
+    }
+    infoTable->setMinimumWidth(200);
+    infoTable->setMinimumHeight(tableHeight + 2/*border*/);
+    upsideLayout->addWidget(infoTable);
+
+    baseLayout->addLayout(upsideLayout);
+
+    /* downside */
+    downsideLayout = new QHBoxLayout(this);
+    downsideLayout->setAlignment(Qt::AlignRight);
+    downsideLayout->setMargin(0);
+
+    okBtn = new QPushButton("OK", this);
+    connect(okBtn, SIGNAL(clicked()), this, SLOT(close()));
+    downsideLayout->addWidget(okBtn);
+
+    baseLayout->addLayout(downsideLayout);
+}
+
+QStringList DetailedInfoDialog::getImagePathList()
+{
+    QStringList imagePathList;
+    for (int i = 0; i <_qemu_argc; i++) {
+        if (QString(_qemu_argv[i]).compare("-drive") == 0) {
+            i += 1;
+            QStringList splitString = QString(_qemu_argv[i]).split(",");
+            QStringList splitString2 = splitString[0].split("=");
+            QString drivePath = splitString2[splitString2.length() -1];
+            imagePathList << drivePath;
+        }
+    }
+    qDebug() << imagePathList;
+    return imagePathList;
+}
+
+void DetailedInfoDialog::slotDoubleClicked(int nRow, int nCol)
+{
+    QTableWidgetItem *item;
+    QString string;
+
+    /* Feature side double click event is occured, ignore it */
+    if (nCol == 0)
+        return;
+
+    item = infoTable->item(nRow, 0);
+    if (item->text().compare("File Sharing Path", Qt::CaseInsensitive) == 0 ||
+            item->text().compare("Image Path", Qt::CaseInsensitive) == 0 ||
+            item->text().compare("Log Path", Qt::CaseInsensitive) == 0) {
+        /* get path name */
+        item = infoTable->item(nRow, nCol);
+        if (item->text().compare("None", Qt::CaseInsensitive) == 0 ||
+                item->text().compare("", Qt::CaseInsensitive) == 0) {
+            /* ignore this event */
+            return;
+        }
+    } else {
+        /* ignore this event */
+        return;
+    }
+
+    if (QFileInfo(item->text()).isDir() == true) {
+        /* path name is a directory name */
+        QDesktopServices::openUrl(QUrl("file:///" + item->text(), QUrl::TolerantMode));
+    } else if (QFileInfo(item->text()).isFile() == true) {
+        /* path name is a file name */
+        QDesktopServices::openUrl(QUrl("file:///" + QFileInfo(item->text()).absolutePath(), QUrl::TolerantMode));
+    } else {
+        qDebug("wrong path name");
+    }
+
+    return;
+}
+
+void DetailedInfoDialog::showEvent(QShowEvent *event)
+{
+    Q_UNUSED(event)
+
+    QWidget *win = ((QWidget *)this->parent());
+    move(win->geometry().center().x() - (geometry().size().width() / 2),
+        win->geometry().center().y() - (geometry().size().height() / 2));
+}
+
+DetailedInfoDialog::~DetailedInfoDialog()
+{
+    QTableWidgetItem *item;
+
+    for (int i = 0; i < infoTable->rowCount(); i++) {
+        for (int j = 0; j < infoTable->columnCount(); j++) {
+            item = infoTable->item(i, j);
+            delete item;
+        }
+    }
+
+    qDebug("destroy detailed info dialog");
+}
diff --git a/tizen/src/ui/menu/detailedinfodialog.h b/tizen/src/ui/menu/detailedinfodialog.h
new file mode 100644 (file)
index 0000000..d20d299
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 DETAILEDINFODIALOG_H
+#define DETAILEDINFODIALOG_H
+
+#include <QtWidgets>
+#include <QDialog>
+
+class DetailedInfoDialog : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit DetailedInfoDialog(QWidget *parent = 0);
+    ~DetailedInfoDialog();
+
+protected:
+    void showEvent(QShowEvent *event);
+
+public slots:
+    void slotDoubleClicked(int nRow, int nCol);
+
+private:
+    QStringList getImagePathList();
+    QVBoxLayout *baseLayout;
+    QHBoxLayout *upsideLayout;
+    QTableWidget *infoTable;
+    QTableWidgetItem *item;
+    QHBoxLayout *downsideLayout;
+    QPushButton *okBtn;
+};
+
+#endif // DETAILEDINFODIALOG_H
diff --git a/tizen/src/ui/menu/screenshot.cpp b/tizen/src/ui/menu/screenshot.cpp
new file mode 100644 (file)
index 0000000..c672cd4
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * Qt Screenshot
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Munkyu Im <munkyu.im@samsung.com>
+ * Sangho Park <sangho1206.park@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 <QtWidgets>
+#include <qtoolbutton.h>
+#include "screenshot.h"
+#include "screenshotview.h"
+#include "mainwindow.h"
+
+void Screenshot::copy() {
+    qDebug("copy");
+    QClipboard* clipboard = QApplication::clipboard();
+    QPixmap pixmap(screenshotPixmap);
+    clipboard->clear();
+    clipboard->setPixmap(pixmap);
+}
+
+QString Screenshot::getRatio() {
+    return ratioStr;
+}
+
+void Screenshot::setRatio(int level) {
+    switch (level) {
+    case 0:
+        ratio = 0.125;
+        break;
+    case 1:
+        ratio = 0.25;
+        break;
+    case 2:
+        ratio = 0.50;
+        break;
+    case 3:
+        ratio = 1;
+        break;
+    case 4:
+        ratio = 2;
+        break;
+    case 5:
+        ratio = 4;
+        break;
+    }
+    ratioStr = QString::number(ratio * 100).append("%");
+}
+
+void Screenshot::scaleChanged(int level) {
+    qDebug("scale changed: %d", level);
+    sliderLevel = level;
+    QPixmap pixmap(screenshotPixmap);
+    setRatio(level);
+    scene->clear();
+    scene->addPixmap(pixmap.scaled(pixmap.size() * ratio, Qt::KeepAspectRatio, Qt::FastTransformation));
+    slider->setToolTip(ratioStr);
+
+    updateStatusBar();
+}
+
+int Screenshot::getSliderLevel() {
+    return sliderLevel;
+}
+
+void Screenshot::refresh(const QPixmap &pixmap) {
+    qDebug("refresh");
+
+    this->frameBuf = pixmap;
+
+    ratioStr = "100%";
+    sliderLevel = 3;
+    slider->setValue(3);
+    scene->clear();
+
+    QMatrix rm;
+    rm.rotate(getRotateAngle());
+    screenshotPixmap = screenshotPixmap.transformed(rm);
+    scene->addPixmap(screenshotPixmap);
+    slider->setToolTip(ratioStr);
+}
+
+void Screenshot::setStatusBar(qreal posX, qreal posY) {
+    this->posX = QString::number(posX);
+    this->posY = QString::number(posY);
+
+    statusBar->showMessage("x: " + this->posX + ", y:" + this->posY
+                           + " (Resolution: " +  QString::number(screenshotPixmap.width()) + "x" + QString::number(screenshotPixmap.height())
+                           + ", " + qPrintable(getRatio()) + ")");
+}
+
+void Screenshot::updateStatusBar() {
+    statusBar->showMessage("x: " + this->posX + ", y:" + this->posY
+                           + " (Resolution: " +  QString::number(screenshotPixmap.width()) + "x" + QString::number(screenshotPixmap.height())
+                           + ", " + qPrintable(getRatio()) + ")");
+}
+
+bool Screenshot::save() {
+    qDebug("save");
+    QString vmname = ((MainWindow *) this->parent()->parent())->uiInfo->vmName;
+    QDateTime currentDateTime = QDateTime::currentDateTime();
+    QString date = currentDateTime.toString("yyyy-MM-dd-HHmmss");
+    QString defaultFile = QDir::homePath() + QDir::separator() + vmname + "-" + date + ".png";
+    QString filterName = "Image files (*.png *.jpg *.jpeg *.bmp)";
+    QString filename = QFileDialog::getSaveFileName(this, "Save Image", defaultFile, filterName);
+
+    if(filename.isEmpty()) {
+        qDebug("can not have file");
+        return false;
+    } else {
+        QPixmap pixmap(screenshotPixmap);
+        qDebug() << filename;
+        pixmap.save(filename);
+        return true;
+    }
+}
+
+int Screenshot::getRotateAngle() {
+    int rotateAngle = ((MainWindow *)(this->parent()->parent()))->getUIState()->mainFormAngle;
+    // Too many logs are printed while mouse is moved.
+    // Thus comment out this line.
+    //qDebug("rotatedAngle: %d", rotateAngle);
+    return rotateAngle;
+}
+
+void Screenshot::makeWidgets() {
+    toolbar = new QToolBar(this);
+
+    slider = new QSlider(Qt::Horizontal, this);
+    slider->setRange(0, 5);
+    slider->setValue(3);
+    sliderLevel = 3;
+    slider->setFixedWidth(100);
+    slider->setToolTip("100%");
+    connect(slider, SIGNAL(valueChanged(int)), this, SLOT(scaleChanged(int)));
+
+    gridlayout = new QGridLayout;
+    gridlayout->setContentsMargins(0, 0, 0, 0);
+
+    saveAct = new QAction(tr("&Save"), this);
+    saveAct->setShortcuts(QKeySequence::Save);
+    saveAct->setIcon(QIcon(":/icons/save_screenshot_dialog.png"));
+    saveAct->setToolTip("Save to file");
+    connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));
+
+    copyAct = new QAction(tr("&Copy"), this);
+    copyAct->setShortcuts(QKeySequence::Copy);
+    copyAct->setIcon(QIcon(":/icons/copy_screenshot_dialog.png"));
+    copyAct->setToolTip("Copy to clipboard");
+    connect(copyAct, SIGNAL(triggered()), this, SLOT(copy()));
+
+    refreshAct = new QAction(tr("&Refresh"), this);
+    refreshAct->setShortcuts(QKeySequence::Refresh);
+    refreshAct->setIcon(QIcon(":/icons/refresh_screenshot_dialog.png"));
+    refreshAct->setToolTip("Refresh Image");
+    connect(refreshAct, SIGNAL(triggered()), this->parent(),
+            SLOT(slotRequestScreenshot()));
+}
+
+void Screenshot::setImage() {
+    scene = new QGraphicsScene(this);
+
+    qDebug() << screenshotPixmap;
+
+    QMatrix rm;
+    rm.rotate(getRotateAngle());
+    screenshotPixmap = screenshotPixmap.transformed(rm);
+    scene->addPixmap(screenshotPixmap);
+
+    view = new ScreenshotView(scene, this);
+    ratioStr = "100%";
+    view->setScene(scene);
+    view->setMouseTracking(true);
+
+    QScrollArea *area = new QScrollArea(this);
+    area->setFixedSize(screenshotPixmap.width(), screenshotPixmap.height());
+    view->setCornerWidget(area);
+    view->verticalScrollBar()->setValue(1);
+    view->horizontalScrollBar()->setValue(1);
+}
+
+Screenshot::Screenshot(QWidget *parent, const QPixmap &pixmap) :
+    QDialog(parent), screenshotPixmap(pixmap) {
+    QString vmname = ((MainWindow *) parent->parent())->uiInfo->vmName + " : "
+        + QString::number(get_device_serial_number());
+    MainWindow *mainWindow = (MainWindow *) parent->parent();
+    this->resize(mainWindow->uiInfo->getMainSize());
+    setWindowTitle("Screen Shot - " + vmname);
+
+    makeWidgets();
+
+    setImage();
+
+    statusBar = new QStatusBar;
+
+    toolbar->addAction(saveAct);
+    toolbar->addAction(copyAct);
+    toolbar->addAction(refreshAct);
+    toolbar->addWidget(slider);
+    gridlayout->addWidget(toolbar, 0, 0);
+    gridlayout->addWidget(view, 1, 0);
+    gridlayout->addWidget(statusBar, 2, 0);
+
+    this->setLayout(gridlayout);
+}
+
+void Screenshot::showEvent(QShowEvent *event) {
+    Q_UNUSED(event)
+
+    QWidget *win = ((QWidget *) this->parent());
+    move(win->geometry().center().x(),
+            win->geometry().center().y() - (geometry().size().height() / 2));
+}
+
+Screenshot::~Screenshot() {
+    qDebug("distructor");
+    ((ContextMenu *)this->parent())->screenshotDialog = NULL;
+}
diff --git a/tizen/src/ui/menu/screenshot.h b/tizen/src/ui/menu/screenshot.h
new file mode 100644 (file)
index 0000000..ff111af
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Qt Screenshot
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Munkyu Im <munkyu.im@samsung.com>
+ * Sangho Park <sangho1206.park@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 SCREENSHOT_H
+#define SCREENSHOT_H
+
+#include <QtWidgets>
+
+class Screenshot: public QDialog {
+Q_OBJECT
+
+public:
+    explicit Screenshot(QWidget *me, const QPixmap &screenshot);
+    ~Screenshot();
+    void setStatusBar(qreal posX, qreal poxY);
+    int getSliderLevel();
+    int getRotateAngle();
+    QString getRatio();
+    QPixmap frameBuf;
+
+public slots:
+    void refresh(const QPixmap &);
+
+protected:
+    void showEvent(QShowEvent *event);
+    QGraphicsScene* scene;
+
+private slots:
+    bool save();
+    void copy();
+    void scaleChanged(int level);
+
+private:
+    void makeWidgets();
+    void setImage();
+    void setRatio(int level);
+    void updateStatusBar();
+
+    QString posX;
+    QString posY;
+    QGridLayout *gridlayout;
+    QGraphicsView* view;
+    int sliderLevel;
+    QLabel *label;
+    QSlider* slider;
+    QPixmap screenshotPixmap;
+    QToolBar *toolbar;
+
+    QStatusBar *statusBar;
+    QMenu *fileMenu;
+    QMenu *editMenu;
+    QMenu *helpMenu;
+    QToolBar *toolBar;
+    float ratio;
+    QString ratioStr;
+    QAction *saveAct;
+    QAction *copyAct;
+    QAction *refreshAct;
+};
+
+#endif
diff --git a/tizen/src/ui/menu/screenshotview.cpp b/tizen/src/ui/menu/screenshotview.cpp
new file mode 100644 (file)
index 0000000..bc06e84
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Qt Screenshot
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Munkyu Im <munkyu.im@samsung.com>
+ * Sangho Park <sangho1206.park@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 "screenshotview.h"
+#include "screenshot.h"
+#include <QtCore/qmath.h>
+
+ScreenshotView::ScreenshotView(QGraphicsScene *scene, QWidget *parent) :
+        QGraphicsView(scene, parent) {
+}
+
+void ScreenshotView::mouseMoveEvent(QMouseEvent *event) {
+    int max_x;
+    int max_y;
+    Screenshot *screenshot = (Screenshot *)(this->parent());
+    QPointF fixedPos = this->mapToScene(event->pos());
+    int sliderLevel = screenshot->getSliderLevel();
+
+    switch (screenshot->getRotateAngle()) {
+    case 90:
+    case 270:
+        max_x = screenshot->frameBuf.size().height();
+        max_y = screenshot->frameBuf.size().width();
+        break;
+    case 0:
+    case 180:
+    default:
+        max_x = screenshot->frameBuf.size().width();
+        max_y = screenshot->frameBuf.size().height();
+        break;
+    }
+
+    // Too many logs are printed while mouse is moved.
+    // Thus comment out this line.
+    //qDebug("sliderLevel: %d", sliderLevel);
+    int x;
+    int y;
+    float expo = 0;
+    switch (sliderLevel) {
+    case 0:
+        expo = 3;
+        break;
+    case 1:
+        expo = 2;
+        break;
+    case 2:
+        expo = 1;
+        break;
+    case 3:
+        expo = 0;
+        break;
+    case 4:
+        expo = -1;
+        break;
+    case 5:
+        expo = -2;
+        break;
+    default:
+        break;
+    }
+
+    x = (int)(fixedPos.x() * pow(2, expo));
+    y = (int)(fixedPos.y() * pow(2, expo));
+    if(x > max_x) {
+        x = max_x;
+    }
+    if(y > max_y) {
+        y = max_y;
+    }
+
+    if (scene()->sceneRect().contains(fixedPos)) {
+        screenshot->setStatusBar(x, y);
+    }
+}
+
+ScreenshotView::~ScreenshotView() {
+}
diff --git a/tizen/src/ui/menu/screenshotview.h b/tizen/src/ui/menu/screenshotview.h
new file mode 100644 (file)
index 0000000..fda6a0b
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Qt Screenshot
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Munkyu Im <munkyu.im@samsung.com>
+ * Sangho Park <sangho1206.park@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 SCREENSHOTVIEW_H
+#define SCREENSHOTVIEW_H
+
+#include <QtWidgets>
+
+class ScreenshotView: public QGraphicsView {
+
+public:
+    ScreenshotView(QGraphicsScene *scene, QWidget *parent);
+    ~ScreenshotView();
+
+protected:
+    void mouseMoveEvent(QMouseEvent *event);
+
+};
+#endif
diff --git a/tizen/src/ui/resource/about.png b/tizen/src/ui/resource/about.png
new file mode 100644 (file)
index 0000000..b276703
Binary files /dev/null and b/tizen/src/ui/resource/about.png differ
diff --git a/tizen/src/ui/resource/icons/about.png b/tizen/src/ui/resource/icons/about.png
new file mode 100644 (file)
index 0000000..4f76588
Binary files /dev/null and b/tizen/src/ui/resource/icons/about.png differ
diff --git a/tizen/src/ui/resource/icons/advanced.png b/tizen/src/ui/resource/icons/advanced.png
new file mode 100644 (file)
index 0000000..14cf9fa
Binary files /dev/null and b/tizen/src/ui/resource/icons/advanced.png differ
diff --git a/tizen/src/ui/resource/icons/close.png b/tizen/src/ui/resource/icons/close.png
new file mode 100644 (file)
index 0000000..a1395ce
Binary files /dev/null and b/tizen/src/ui/resource/icons/close.png differ
diff --git a/tizen/src/ui/resource/icons/control_panel.png b/tizen/src/ui/resource/icons/control_panel.png
new file mode 100644 (file)
index 0000000..3da7e80
Binary files /dev/null and b/tizen/src/ui/resource/icons/control_panel.png differ
diff --git a/tizen/src/ui/resource/icons/copy_screenshot_dialog.png b/tizen/src/ui/resource/icons/copy_screenshot_dialog.png
new file mode 100644 (file)
index 0000000..a07a5f7
Binary files /dev/null and b/tizen/src/ui/resource/icons/copy_screenshot_dialog.png differ
diff --git a/tizen/src/ui/resource/icons/detailed_info.png b/tizen/src/ui/resource/icons/detailed_info.png
new file mode 100644 (file)
index 0000000..149ffa2
Binary files /dev/null and b/tizen/src/ui/resource/icons/detailed_info.png differ
diff --git a/tizen/src/ui/resource/icons/emulator_icon.ico b/tizen/src/ui/resource/icons/emulator_icon.ico
new file mode 100644 (file)
index 0000000..a170e86
Binary files /dev/null and b/tizen/src/ui/resource/icons/emulator_icon.ico differ
diff --git a/tizen/src/ui/resource/icons/force_close.png b/tizen/src/ui/resource/icons/force_close.png
new file mode 100644 (file)
index 0000000..a506b4d
Binary files /dev/null and b/tizen/src/ui/resource/icons/force_close.png differ
diff --git a/tizen/src/ui/resource/icons/host_keyboard.png b/tizen/src/ui/resource/icons/host_keyboard.png
new file mode 100644 (file)
index 0000000..69a87f3
Binary files /dev/null and b/tizen/src/ui/resource/icons/host_keyboard.png differ
diff --git a/tizen/src/ui/resource/icons/refresh_screenshot_dialog.png b/tizen/src/ui/resource/icons/refresh_screenshot_dialog.png
new file mode 100644 (file)
index 0000000..e1616d9
Binary files /dev/null and b/tizen/src/ui/resource/icons/refresh_screenshot_dialog.png differ
diff --git a/tizen/src/ui/resource/icons/rotate.png b/tizen/src/ui/resource/icons/rotate.png
new file mode 100644 (file)
index 0000000..b2fc00f
Binary files /dev/null and b/tizen/src/ui/resource/icons/rotate.png differ
diff --git a/tizen/src/ui/resource/icons/save_screenshot_dialog.png b/tizen/src/ui/resource/icons/save_screenshot_dialog.png
new file mode 100644 (file)
index 0000000..523fe9e
Binary files /dev/null and b/tizen/src/ui/resource/icons/save_screenshot_dialog.png differ
diff --git a/tizen/src/ui/resource/icons/scale.png b/tizen/src/ui/resource/icons/scale.png
new file mode 100644 (file)
index 0000000..1f3f872
Binary files /dev/null and b/tizen/src/ui/resource/icons/scale.png differ
diff --git a/tizen/src/ui/resource/icons/screen_shot.png b/tizen/src/ui/resource/icons/screen_shot.png
new file mode 100644 (file)
index 0000000..74c8515
Binary files /dev/null and b/tizen/src/ui/resource/icons/screen_shot.png differ
diff --git a/tizen/src/ui/resource/icons/shell.png b/tizen/src/ui/resource/icons/shell.png
new file mode 100644 (file)
index 0000000..e89f1b1
Binary files /dev/null and b/tizen/src/ui/resource/icons/shell.png differ
diff --git a/tizen/src/ui/resource/mobile-720x1280-3btn/default.dbi b/tizen/src/ui/resource/mobile-720x1280-3btn/default.dbi
new file mode 100644 (file)
index 0000000..1ba4d64
--- /dev/null
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<EmulatorUI xmlns="http://www.tizen.org/emulator/skin/dbi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <dbi_version>2.2</dbi_version>
+    <rotations>
+        <rotation name="Portrait">
+            <display id="0">
+                <region left="67" top="116" width="720" height="1280"/>
+            </display>
+            <imageList>
+                <mainImage>default_0.png</mainImage>
+                <keyPressedImage>default_0_p.png</keyPressedImage>
+            </imageList>
+            <keyMapList>
+                <keyMap>
+                    <region left="210" top="1401" width="84" height="84"/>
+                    <eventInfo>
+                        <keyCode>169</keyCode>
+                        <keyName>Menu</keyName>
+                    </eventInfo>
+                    <tooltip>Menu</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="390" top="1401" width="84" height="84"/>
+                    <eventInfo>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
+                    </eventInfo>
+                    <tooltip>Home</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="570" top="1401" width="84" height="84"/>
+                    <eventInfo>
+                        <keyCode>158</keyCode>
+                        <keyName>Back</keyName>
+                    </eventInfo>
+                    <tooltip>Back</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="841" top="1309" width="24" height="96" update="true"/>
+                    <eventInfo>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
+                    </eventInfo>
+                    <tooltip>Power</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="841" top="108" width="24" height="96" update="true"/>
+                    <eventInfo>
+                        <keyCode>115</keyCode>
+                        <keyName>Volume +</keyName>
+                    </eventInfo>
+                    <tooltip>Volume +</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="841" top="219" width="24" height="96" update="true"/>
+                    <eventInfo>
+                        <keyCode>114</keyCode>
+                        <keyName>Volume -</keyName>
+                    </eventInfo>
+                    <tooltip>Volume -</tooltip>
+                </keyMap>
+            </keyMapList>
+        </rotation>
+        <rotation name="Landscape">
+            <display id="0">
+                <region left="116" top="78" width="1280" height="720"/>
+            </display>
+            <imageList>
+                <mainImage>default_L90.png</mainImage>
+                <keyPressedImage>default_L90_p.png</keyPressedImage>
+            </imageList>
+            <keyMapList>
+                <keyMap>
+                    <region left="1400" top="570" width="84" height="84"/>
+                    <eventInfo>
+                        <keyCode>169</keyCode>
+                        <keyName>Menu</keyName>
+                    </eventInfo>
+                    <tooltip>Menu</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="1400" top="392" width="84" height="84"/>
+                    <eventInfo>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
+                    </eventInfo>
+                    <tooltip>Home</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="1400" top="210" width="84" height="84"/>
+                    <eventInfo>
+                        <keyCode>158</keyCode>
+                        <keyName>Back</keyName>
+                    </eventInfo>
+                    <tooltip>Back</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="1308" top="2" width="96" height="24" update="true"/>
+                    <eventInfo>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
+                    </eventInfo>
+                    <tooltip>Power</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="108" top="2" width="96" height="24" update="true"/>
+                    <eventInfo>
+                        <keyCode>115</keyCode>
+                        <keyName>Volume +</keyName>
+                    </eventInfo>
+                    <tooltip>Volume +</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="217" top="2" width="96" height="24" update="true"/>
+                    <eventInfo>
+                        <keyCode>114</keyCode>
+                        <keyName>Volume -</keyName>
+                    </eventInfo>
+                    <tooltip>Volume -</tooltip>
+                </keyMap>
+            </keyMapList>
+        </rotation>
+        <rotation name="Reverse Portrait">
+            <display id="0">
+                <region left="78" top="117" width="720" height="1280"/>
+            </display>
+            <imageList>
+                <mainImage>default_180.png</mainImage>
+                <keyPressedImage>default_180_p.png</keyPressedImage>
+            </imageList>
+            <keyMapList>
+                <keyMap>
+                    <region left="570" top="30" width="84" height="84"/>
+                    <eventInfo>
+                        <keyCode>169</keyCode>
+                        <keyName>Menu</keyName>
+                    </eventInfo>
+                    <tooltip>Menu</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="390" top="30" width="84" height="84"/>
+                    <eventInfo>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
+                    </eventInfo>
+                    <tooltip>Home</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="210" top="30" width="84" height="84"/>
+                    <eventInfo>
+                        <keyCode>158</keyCode>
+                        <keyName>Back</keyName>
+                    </eventInfo>
+                    <tooltip>Back</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="2" top="110" width="24" height="96" update="true"/>
+                    <eventInfo>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
+                    </eventInfo>
+                    <tooltip>Power</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="2" top="1310" width="24" height="96" update="true"/>
+                    <eventInfo>
+                        <keyCode>115</keyCode>
+                        <keyName>Volume +</keyName>
+                    </eventInfo>
+                    <tooltip>Volume +</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="2" top="1200" width="24" height="96" update="true"/>
+                    <eventInfo>
+                        <keyCode>114</keyCode>
+                        <keyName>Volume -</keyName>
+                    </eventInfo>
+                    <tooltip>Volume -</tooltip>
+                </keyMap>
+            </keyMapList>
+        </rotation>
+        <rotation name="Reverse Landscape">
+            <display id="0">
+                <region left="117" top="67" width="1280" height="720"/>
+            </display>
+            <imageList>
+                <mainImage>default_R90.png</mainImage>
+                <keyPressedImage>default_R90_p.png</keyPressedImage>
+            </imageList>
+            <keyMapList>
+                <keyMap>
+                    <region left="28" top="209" width="84" height="84"/>
+                    <eventInfo>
+                        <keyCode>169</keyCode>
+                        <keyName>Menu</keyName>
+                    </eventInfo>
+                    <tooltip>Menu</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="28" top="391" width="84" height="84"/>
+                    <eventInfo>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
+                    </eventInfo>
+                    <tooltip>Home</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="28" top="568" width="84" height="84"/>
+                    <eventInfo>
+                        <keyCode>158</keyCode>
+                        <keyName>Back</keyName>
+                    </eventInfo>
+                    <tooltip>Back</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="109" top="841" width="96" height="24" update="true"/>
+                    <eventInfo>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
+                    </eventInfo>
+                    <tooltip>Power</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="1309" top="841" width="96" height="24" update="true"/>
+                    <eventInfo>
+                        <keyCode>115</keyCode>
+                        <keyName>Volume +</keyName>
+                    </eventInfo>
+                    <tooltip>Volume +</tooltip>
+                </keyMap>
+                <keyMap>
+                    <region left="1199" top="841" width="96" height="24" update="true"/>
+                    <eventInfo>
+                        <keyCode>114</keyCode>
+                        <keyName>Volume -</keyName>
+                    </eventInfo>
+                    <tooltip>Volume -</tooltip>
+                </keyMap>
+            </keyMapList>
+        </rotation>
+    </rotations>
+    <hover>
+        <color B="255" G="255" R="255" />
+    </hover>
+    <popupMenu>
+        <keywindowItem visible="false" />
+        <hostKeyboardItem visible="false" />
+        <ramdumpItem visible="false" />
+    </popupMenu>
+</EmulatorUI>
diff --git a/tizen/src/ui/resource/mobile-720x1280-3btn/default_0.png b/tizen/src/ui/resource/mobile-720x1280-3btn/default_0.png
new file mode 100644 (file)
index 0000000..04e01d6
Binary files /dev/null and b/tizen/src/ui/resource/mobile-720x1280-3btn/default_0.png differ
diff --git a/tizen/src/ui/resource/mobile-720x1280-3btn/default_0_p.png b/tizen/src/ui/resource/mobile-720x1280-3btn/default_0_p.png
new file mode 100644 (file)
index 0000000..4049ae2
Binary files /dev/null and b/tizen/src/ui/resource/mobile-720x1280-3btn/default_0_p.png differ
diff --git a/tizen/src/ui/resource/mobile-720x1280-3btn/default_180.png b/tizen/src/ui/resource/mobile-720x1280-3btn/default_180.png
new file mode 100644 (file)
index 0000000..750d056
Binary files /dev/null and b/tizen/src/ui/resource/mobile-720x1280-3btn/default_180.png differ
diff --git a/tizen/src/ui/resource/mobile-720x1280-3btn/default_180_p.png b/tizen/src/ui/resource/mobile-720x1280-3btn/default_180_p.png
new file mode 100644 (file)
index 0000000..c3fefa6
Binary files /dev/null and b/tizen/src/ui/resource/mobile-720x1280-3btn/default_180_p.png differ
diff --git a/tizen/src/ui/resource/mobile-720x1280-3btn/default_L90.png b/tizen/src/ui/resource/mobile-720x1280-3btn/default_L90.png
new file mode 100644 (file)
index 0000000..6d0724c
Binary files /dev/null and b/tizen/src/ui/resource/mobile-720x1280-3btn/default_L90.png differ
diff --git a/tizen/src/ui/resource/mobile-720x1280-3btn/default_L90_p.png b/tizen/src/ui/resource/mobile-720x1280-3btn/default_L90_p.png
new file mode 100644 (file)
index 0000000..babe9d4
Binary files /dev/null and b/tizen/src/ui/resource/mobile-720x1280-3btn/default_L90_p.png differ
diff --git a/tizen/src/ui/resource/mobile-720x1280-3btn/default_R90.png b/tizen/src/ui/resource/mobile-720x1280-3btn/default_R90.png
new file mode 100644 (file)
index 0000000..462c544
Binary files /dev/null and b/tizen/src/ui/resource/mobile-720x1280-3btn/default_R90.png differ
diff --git a/tizen/src/ui/resource/mobile-720x1280-3btn/default_R90_p.png b/tizen/src/ui/resource/mobile-720x1280-3btn/default_R90_p.png
new file mode 100644 (file)
index 0000000..2d54428
Binary files /dev/null and b/tizen/src/ui/resource/mobile-720x1280-3btn/default_R90_p.png differ
diff --git a/tizen/src/ui/resource/mobile-720x1280-3btn/info.ini b/tizen/src/ui/resource/mobile-720x1280-3btn/info.ini
new file mode 100644 (file)
index 0000000..efd4490
--- /dev/null
@@ -0,0 +1,4 @@
+skin.name=Phone 720x1280
+resolution.width=720
+resolution.height=1280
+manager.priority=3
diff --git a/tizen/src/ui/resource/mobile-720x1280-3btn/layout.qml b/tizen/src/ui/resource/mobile-720x1280-3btn/layout.qml
new file mode 100644 (file)
index 0000000..012075d
--- /dev/null
@@ -0,0 +1,147 @@
+import EmulatorComponent 1.0
+
+EmulatorUI {
+    property string version: "1.0"
+
+    FormList {
+        Form {
+            objectName: "portrait"
+            display: Region { left: 67; top: 116; width: 720; height: 1280 }
+
+            mainImage: "default_0.png"
+            pressedImage: "default_0_p.png"
+
+            KeyList {
+                Key { objectName: "Menu"; keycode: 169
+                    Region { left: 210; top: 1401; width: 84; height: 84 }
+                    tooltip: "Menu"
+                }
+                Key { objectName: "Home"; keycode: 139
+                    Region { left: 390; top: 1401; width: 84; height: 84 }
+                    tooltip: "Home"
+                }
+                Key { objectName: "Back"; keycode: 158
+                    Region { left: 570; top: 1401; width: 84; height: 84 }
+                    tooltip: "Back"
+                }
+                Key { objectName: "Power"; keycode: 116
+                    Region { left: 841; top: 1309; width: 24; height: 96 }
+                    tooltip: "Power"
+                }
+                Key { objectName: "Volume +"; keycode: 115
+                    Region { left: 841; top: 108; width: 24; height: 96 }
+                    tooltip: "Volume +"
+                }
+                Key { objectName: "Volume -"; keycode: 114
+                    Region { left: 841; top: 219; width: 24; height: 96 }
+                    tooltip: "Volume -"
+                }
+            }
+        }
+
+        Form {
+            objectName: "landscape"
+            display: Region { left: 116; top: 78; width: 1280; height: 720 }
+
+            mainImage: "default_L90.png"
+            pressedImage: "default_L90_p.png"
+
+            KeyList {
+                Key { objectName: "Menu"; keycode: 169
+                    Region { left: 1400; top: 570; width: 84; height: 84 }
+                    tooltip: "Menu"
+                }
+                Key { objectName: "Home"; keycode: 139
+                    Region { left: 1400; top: 392; width: 84; height: 84 }
+                    tooltip: "Home"
+                }
+                Key { objectName: "Back"; keycode: 158
+                    Region { left: 1400; top: 210; width: 84; height: 84 }
+                    tooltip: "Back"
+                }
+                Key { objectName: "Power"; keycode: 116
+                    Region { left: 1308; top: 2; width: 96; height: 24 }
+                    tooltip: "Power"
+                }
+                Key { objectName: "Volume +"; keycode: 115
+                    Region { left: 108; top: 2; width: 96; height: 24 }
+                    tooltip: "Volume +"
+                }
+                Key { objectName: "Volume -"; keycode: 114
+                    Region { left: 217; top: 2; width: 96; height: 24 }
+                    tooltip: "Volume -"
+                }
+            }
+        }
+
+        Form {
+            objectName: "reverse portrait"
+            display: Region { left: 78; top: 117; width: 720; height: 1280 }
+
+            mainImage: "default_180.png"
+            pressedImage: "default_180_p.png"
+
+            KeyList {
+                Key { objectName: "Menu"; keycode: 169
+                    Region { left: 570; top: 30; width: 84; height: 84 }
+                    tooltip: "Menu"
+                }
+                Key { objectName: "Home"; keycode: 139
+                    Region { left: 390; top: 30; width: 84; height: 84 }
+                    tooltip: "Home"
+                }
+                Key { objectName: "Back"; keycode: 158
+                    Region { left: 210; top: 30; width: 84; height: 84 }
+                    tooltip: "Back"
+                }
+                Key { objectName: "Power"; keycode: 116
+                    Region { left: 2; top: 110; width: 24; height: 96 }
+                    tooltip: "Power"
+                }
+                Key { objectName: "Volume +"; keycode: 115
+                    Region { left: 2; top: 1310; width: 24; height: 96 }
+                    tooltip: "Volume +"
+                }
+                Key { objectName: "Volume -"; keycode: 114
+                    Region { left: 2; top: 1200; width: 24; height: 96 }
+                    tooltip: "Volume -"
+                }
+            }
+        }
+
+        Form {
+            objectName: "reverse landscape"
+            display: Region { left: 117; top: 67; width: 1280; height: 720 }
+
+            mainImage: "default_R90.png"
+            pressedImage: "default_R90_p.png"
+
+            KeyList {
+                Key { objectName: "Menu"; keycode: 169
+                    Region { left: 28; top: 209; width: 84; height: 84 }
+                    tooltip: "Menu"
+                }
+                Key { objectName: "Home"; keycode: 139
+                    Region { left: 28; top: 391; width: 84; height: 84 }
+                    tooltip: "Home"
+                }
+                Key { objectName: "Back"; keycode: 158
+                    Region { left: 28; top: 568; width: 84; height: 84 }
+                    tooltip: "Back"
+                }
+                Key { objectName: "Power"; keycode: 116
+                    Region { left: 109; top: 841; width: 96; height: 24 }
+                    tooltip: "Power"
+                }
+                Key { objectName: "Volume +"; keycode: 115
+                    Region { left: 1309; top: 841; width: 96; height: 24 }
+                    tooltip: "Volume +"
+                }
+                Key { objectName: "Volume -"; keycode: 114
+                    Region { left: 1199; top: 841; width: 96; height: 24 }
+                    tooltip: "Volume -"
+                }
+            }
+        }
+    }
+}
diff --git a/tizen/src/ui/resource/resource.qrc b/tizen/src/ui/resource/resource.qrc
new file mode 100644 (file)
index 0000000..74222f3
--- /dev/null
@@ -0,0 +1,20 @@
+<RCC>
+    <qresource prefix="/">
+        <file>about.png</file>
+        <file>icons/emulator_icon.ico</file>
+        <file>icons/shell.png</file>
+        <file>icons/about.png</file>
+        <file>icons/advanced.png</file>
+        <file>icons/close.png</file>
+        <file>icons/force_close.png</file>
+        <file>icons/rotate.png</file>
+        <file>icons/scale.png</file>
+        <file>icons/control_panel.png</file>
+        <file>icons/detailed_info.png</file>
+        <file>icons/screen_shot.png</file>
+        <file>icons/host_keyboard.png</file>
+        <file>icons/save_screenshot_dialog.png</file>
+        <file>icons/copy_screenshot_dialog.png</file>
+        <file>icons/refresh_screenshot_dialog.png</file>
+    </qresource>
+</RCC>
diff --git a/tizen/src/ui/resource/wearable-320x320-1btn/default.dbi b/tizen/src/ui/resource/wearable-320x320-1btn/default.dbi
new file mode 100644 (file)
index 0000000..8ef39c0
--- /dev/null
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<EmulatorUI xmlns="http://www.tizen.org/emulator/skin/dbi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <dbi_version>2.2</dbi_version>
+    <rotations>
+        <rotation name="Portrait">
+            <display id="0">
+                <region left="26" top="60" width="320" height="320"/>
+            </display>
+            <imageList>
+                <mainImage>default_0.png</mainImage>
+                <keyPressedImage>default_0_p.png</keyPressedImage>
+            </imageList>
+            <keyMapList>
+                <keyMap>
+                    <region left="372" top="116" width="12" height="80" update="true"/>
+                    <eventInfo>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
+                    </eventInfo>
+                    <tooltip>Power</tooltip>
+                </keyMap>
+            </keyMapList>
+        </rotation>
+        <rotation name="Landscape">
+            <display id="0">
+                <region left="60" top="38" width="320" height="320"/>
+            </display>
+            <imageList>
+                <mainImage>default_L90.png</mainImage>
+                <keyPressedImage>default_L90_p.png</keyPressedImage>
+            </imageList>
+            <keyMapList>
+                <keyMap>
+                    <region left="116" top="0" width="80" height="12" update="true"/>
+                    <eventInfo>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
+                    </eventInfo>
+                    <tooltip>Power</tooltip>
+                </keyMap>
+            </keyMapList>
+        </rotation>
+        <rotation name="Reverse Portrait">
+            <display id="0">
+                <region left="38" top="60" width="320" height="320"/>
+            </display>
+            <imageList>
+                <mainImage>default_180.png</mainImage>
+                <keyPressedImage>default_180_p.png</keyPressedImage>
+            </imageList>
+            <keyMapList>
+                <keyMap>
+                    <region left="0" top="244" width="12" height="80" update="true"/>
+                    <eventInfo>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
+                    </eventInfo>
+                    <tooltip>Power</tooltip>
+                </keyMap>
+            </keyMapList>
+        </rotation>
+        <rotation name="Reverse Landscape">
+            <display id="0">
+                <region left="60" top="26" width="320" height="320"/>
+            </display>
+            <imageList>
+                <mainImage>default_R90.png</mainImage>
+                <keyPressedImage>default_R90_p.png</keyPressedImage>
+            </imageList>
+            <keyMapList>
+                <keyMap>
+                    <region left="244" top="372" width="80" height="12" update="true"/>
+                    <eventInfo>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
+                    </eventInfo>
+                    <tooltip>Power</tooltip>
+                </keyMap>
+            </keyMapList>
+        </rotation>
+    </rotations>
+    <hover>
+        <color B="255" G="255" R="255" />
+    </hover>
+    <popupMenu>
+        <scaleItem visible="false" />
+        <keywindowItem visible="false" />
+        <hostKeyboardItem visible="false" />
+        <ramdumpItem visible="false" />
+    </popupMenu>
+</EmulatorUI>
diff --git a/tizen/src/ui/resource/wearable-320x320-1btn/default_0.png b/tizen/src/ui/resource/wearable-320x320-1btn/default_0.png
new file mode 100755 (executable)
index 0000000..cd23252
Binary files /dev/null and b/tizen/src/ui/resource/wearable-320x320-1btn/default_0.png differ
diff --git a/tizen/src/ui/resource/wearable-320x320-1btn/default_0_p.png b/tizen/src/ui/resource/wearable-320x320-1btn/default_0_p.png
new file mode 100644 (file)
index 0000000..4cfaf78
Binary files /dev/null and b/tizen/src/ui/resource/wearable-320x320-1btn/default_0_p.png differ
diff --git a/tizen/src/ui/resource/wearable-320x320-1btn/default_180.png b/tizen/src/ui/resource/wearable-320x320-1btn/default_180.png
new file mode 100644 (file)
index 0000000..c641763
Binary files /dev/null and b/tizen/src/ui/resource/wearable-320x320-1btn/default_180.png differ
diff --git a/tizen/src/ui/resource/wearable-320x320-1btn/default_180_p.png b/tizen/src/ui/resource/wearable-320x320-1btn/default_180_p.png
new file mode 100644 (file)
index 0000000..871720d
Binary files /dev/null and b/tizen/src/ui/resource/wearable-320x320-1btn/default_180_p.png differ
diff --git a/tizen/src/ui/resource/wearable-320x320-1btn/default_L90.png b/tizen/src/ui/resource/wearable-320x320-1btn/default_L90.png
new file mode 100644 (file)
index 0000000..e7f089b
Binary files /dev/null and b/tizen/src/ui/resource/wearable-320x320-1btn/default_L90.png differ
diff --git a/tizen/src/ui/resource/wearable-320x320-1btn/default_L90_p.png b/tizen/src/ui/resource/wearable-320x320-1btn/default_L90_p.png
new file mode 100644 (file)
index 0000000..4d00686
Binary files /dev/null and b/tizen/src/ui/resource/wearable-320x320-1btn/default_L90_p.png differ
diff --git a/tizen/src/ui/resource/wearable-320x320-1btn/default_R90.png b/tizen/src/ui/resource/wearable-320x320-1btn/default_R90.png
new file mode 100644 (file)
index 0000000..349d8ad
Binary files /dev/null and b/tizen/src/ui/resource/wearable-320x320-1btn/default_R90.png differ
diff --git a/tizen/src/ui/resource/wearable-320x320-1btn/default_R90_p.png b/tizen/src/ui/resource/wearable-320x320-1btn/default_R90_p.png
new file mode 100644 (file)
index 0000000..c5b5e6d
Binary files /dev/null and b/tizen/src/ui/resource/wearable-320x320-1btn/default_R90_p.png differ
diff --git a/tizen/src/ui/resource/wearable-320x320-1btn/info.ini b/tizen/src/ui/resource/wearable-320x320-1btn/info.ini
new file mode 100644 (file)
index 0000000..91e5967
--- /dev/null
@@ -0,0 +1,4 @@
+skin.name=Wearable 320x320
+resolution.width=320
+resolution.height=320
+manager.priority=1
diff --git a/tizen/src/ui/resource/wearable-320x320-1btn/layout.qml b/tizen/src/ui/resource/wearable-320x320-1btn/layout.qml
new file mode 100644 (file)
index 0000000..9fee044
--- /dev/null
@@ -0,0 +1,67 @@
+import EmulatorComponent 1.0
+
+EmulatorUI {
+    property string version: "1.0"
+
+    FormList {
+        Form {
+            objectName: "portrait"
+            display: Region { left: 26; top: 60; width: 320; height: 320 }
+
+            mainImage: "default_0.png"
+            pressedImage: "default_0_p.png"
+
+            KeyList {
+                Key { objectName: "Power"; keycode: 116
+                    Region { left: 372; top: 116; width: 12; height: 80 }
+                    tooltip: "Power"
+                }
+            }
+        }
+
+        Form {
+            objectName: "landscape"
+            display: Region { left: 60; top: 38; width: 320; height: 320 }
+
+            mainImage: "default_L90.png"
+            pressedImage: "default_L90_p.png"
+
+            KeyList {
+                Key { objectName: "Power"; keycode: 116
+                    Region { left: 116; top: 0; width: 80; height: 12 }
+                    tooltip: "Power"
+                }
+            }
+        }
+
+        Form {
+            objectName: "reverse portrait"
+            display: Region { left: 38; top: 60; width: 320; height: 320 }
+
+            mainImage: "default_180.png"
+            pressedImage: "default_180_p.png"
+
+            KeyList {
+                Key { objectName: "Power"; keycode: 116
+                    Region { left: 0; top: 244; width: 12; height: 80 }
+                    tooltip: "Power"
+                }
+            }
+        }
+
+        Form {
+            objectName: "reverse landscape"
+            display: Region { left: 60; top: 26; width: 320; height: 320 }
+
+            mainImage: "default_R90.png"
+            pressedImage: "default_R90_p.png"
+
+            KeyList {
+                Key { objectName: "Power"; keycode: 116
+                    Region { left: 244; top: 372; width: 80; height: 12 }
+                    tooltip: "Power"
+                }
+            }
+        }
+    }
+}
diff --git a/tizen/src/ui/skinbezelitem.cpp b/tizen/src/ui/skinbezelitem.cpp
new file mode 100644 (file)
index 0000000..4d90066
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 <QtWidgets>
+#include <QGraphicsSceneMouseEvent>
+
+#include "skinbezelitem.h"
+
+SkinBezelItem::SkinBezelItem(QImage bezelImg, QGraphicsItem *parent) :
+    QGraphicsPixmapItem(QPixmap::fromImage(bezelImg), parent)
+{
+    keyHandling = false;
+}
+
+void SkinBezelItem::setKeyHandling(bool doing)
+{
+    keyHandling = doing;
+}
+
+bool SkinBezelItem::isKeyHandling()
+{
+    return keyHandling;
+}
+
+SkinBezelItem::~SkinBezelItem()
+{
+    qDebug("destroy bezel item");
+}
diff --git a/tizen/src/ui/skinbezelitem.h b/tizen/src/ui/skinbezelitem.h
new file mode 100644 (file)
index 0000000..e8754f8
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 SKINBEZELITEM_H
+#define SKINBEZELITEM_H
+
+#include <QGraphicsPixmapItem>
+
+class SkinBezelItem : public QGraphicsPixmapItem
+{
+public:
+    SkinBezelItem(QImage bezelImg, QGraphicsItem *parent = 0);
+    ~SkinBezelItem();
+
+    void setKeyHandling(bool doing);
+    bool isKeyHandling();
+
+protected:
+
+private:
+    bool keyHandling;
+};
+
+#endif // SKINBEZELITEM_H
diff --git a/tizen/src/ui/skinkeyitem.cpp b/tizen/src/ui/skinkeyitem.cpp
new file mode 100644 (file)
index 0000000..a658fdc
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "skinkeyitem.h"
+
+SkinKeyItem::SkinKeyItem(QImage pressedImg, HardwareKey *key, SkinBezelItem *parent) :
+    QGraphicsRectItem(key->region, (QGraphicsItem *)parent)
+{
+    this->bezelParent = parent;
+    this->pressedImg = pressedImg;
+    this->key = key;
+    isPressed = false;
+    hoverColor = Qt::white; // TODO:
+    pen.setColor(Qt::transparent);
+
+    longPressTimer = new QTimer();
+    longPressTimer->setInterval(2 * 1000);
+    longPressTimer->setSingleShot(true);
+    connect(longPressTimer, SIGNAL(timeout()), this, SLOT(longPressDetected()));
+
+    setToolTip("<span style=background-color:white><font color=black>"
+        + key->tooltip + "</font></span>");
+
+    setAcceptHoverEvents(true);
+}
+
+void SkinKeyItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+    Q_UNUSED(event)
+
+    isPressed = true;
+    bezelParent->setKeyHandling(true);
+    pen.setColor(Qt::transparent);
+
+    update();
+
+    /* check long press key */
+    if (key->keycode == LONGPRESS_KEYCODE) {
+        longPressTimer->start();
+        return;
+    }
+    qDebug("key pressed : %s", key->name.toLocal8Bit().data());
+
+    do_hw_key_event(KEY_PRESSED, key->keycode);
+}
+
+void SkinKeyItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+    Q_UNUSED(event)
+    int keyCode = 0;
+    isPressed = false;
+    bezelParent->setKeyHandling(false);
+
+    update();
+
+    if (key->keycode == LONGPRESS_KEYCODE) {
+        if (longPressTimer->remainingTime() <= 0) {
+            /* long press key */
+            if (key->name.compare("KEY_RETURN", Qt::CaseInsensitive) == 0) {
+                qDebug("key released : KEY_EXIT");
+                keyCode = 174;
+            } else if (key->name.compare("KEY_YELLOW", Qt::CaseInsensitive) == 0) {
+                qDebug("key released : KEY_MENU");
+                keyCode = 125;
+            } else if (key->name.compare("KEY_CYAN", Qt::CaseInsensitive) == 0) {
+                qDebug("key released : KEY_INFO");
+                keyCode = 188;
+            }
+            do_hw_key_event(KEY_RELEASED, keyCode);
+            return;
+        } else {
+            /* short press key */
+            longPressTimer->stop();
+            if (key->name.compare("KEY_RETURN", Qt::CaseInsensitive) == 0) {
+                keyCode = 1;
+            } else if (key->name.compare("KEY_YELLOW", Qt::CaseInsensitive) == 0) {
+                keyCode = 61;
+            } else if (key->name.compare("KEY_CYAN", Qt::CaseInsensitive) == 0) {
+                keyCode = 62;
+            }
+            qDebug("key pressed : %s", key->name.toLocal8Bit().data());
+            do_hw_key_event(KEY_PRESSED, keyCode);
+        }
+    } else {
+        keyCode = key->keycode;
+    }
+
+    qDebug("key released : %s", key->name.toLocal8Bit().data());
+    do_hw_key_event(KEY_RELEASED, keyCode);
+}
+
+void SkinKeyItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
+{
+    Q_UNUSED(event)
+    //qDebug("key entered");
+
+    pen.setColor(hoverColor);
+
+    update();
+}
+
+void SkinKeyItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
+{
+    Q_UNUSED(event)
+    //qDebug("key leaved");
+
+    pen.setColor(Qt::transparent);
+
+    update();
+}
+
+void SkinKeyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option)
+    Q_UNUSED(widget)
+
+    if (pen.color() != Qt::transparent) {
+        painter->setPen(pen);
+        painter->drawRect(rect());
+    }
+
+    if (isPressed == true) {
+        painter->drawImage(rect().x(), rect().y(), pressedImg);
+    }
+}
+
+void SkinKeyItem::longPressDetected()
+{
+    int keyCode = 0;
+
+    qDebug("long press detected");
+    if (key->name.compare("KEY_RETURN", Qt::CaseInsensitive) == 0) {
+        qDebug("key pressed : KEY_EXIT");
+        keyCode = 174;
+    } else if (key->name.compare("KEY_YELLOW", Qt::CaseInsensitive) == 0) {
+        qDebug("key pressed : KEY_MENU");
+        keyCode = 125;
+    } else if (key->name.compare("KEY_CYAN", Qt::CaseInsensitive) == 0) {
+        qDebug("key pressed : KEY_INFO");
+        keyCode = 188;
+    }
+    do_hw_key_event(KEY_PRESSED, keyCode);
+}
+
+SkinKeyItem::~SkinKeyItem()
+{
+    if (longPressTimer) {
+        delete longPressTimer;
+        longPressTimer = NULL;
+    }
+    //qDebug("destory key item");
+}
diff --git a/tizen/src/ui/skinkeyitem.h b/tizen/src/ui/skinkeyitem.h
new file mode 100644 (file)
index 0000000..ce311b9
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 SKINKEYITEM_H
+#define SKINKEYITEM_H
+
+#include <QGraphicsRectItem>
+#include <QPainter>
+#include <QTimer>
+
+#include "skinbezelitem.h"
+#include "hardwarekey.h"
+
+extern "C" {
+#include "skin/maruskin_operation.h"
+#include "emul_state.h"
+}
+
+#define LONGPRESS_KEYCODE (-999)
+
+class SkinKeyItem : public QObject, public QGraphicsRectItem
+{
+    Q_OBJECT
+
+public:
+    SkinKeyItem(QImage pressedImg, HardwareKey *key, SkinBezelItem *parent = 0);
+    ~SkinKeyItem();
+
+    HardwareKey *key;
+    QImage pressedImg;
+    QTimer *longPressTimer;
+
+signals:
+
+public slots:
+    void longPressDetected();
+
+protected:
+    void mousePressEvent(QGraphicsSceneMouseEvent *event);
+    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+    void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
+    void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
+
+    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+private:
+    SkinBezelItem *bezelParent;
+    bool isPressed;
+    QColor hoverColor;
+    QPen pen;
+    QBrush brush;
+};
+
+#endif // SKINKEYITEM_H
diff --git a/tizen/src/ui/skinview.cpp b/tizen/src/ui/skinview.cpp
new file mode 100644 (file)
index 0000000..c06f756
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 <QtWidgets>
+
+#include "skinview.h"
+#include "mainwindow.h"
+#include "skinkeyitem.h"
+
+SkinView::SkinView(QGraphicsScene *scene, QWidget *parent) :
+    QGraphicsView(scene, parent)
+{
+    setStyleSheet("border-style: none");
+
+    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    setAlignment(Qt::AlignLeft | Qt::AlignTop);
+
+    grabWinPos = QPoint(-1, -1);
+    grabPos = QPoint(-1, -1);
+
+    createItems();
+
+    kbd = new KeyboardHelper();
+}
+
+void SkinView::createItems()
+{
+    MainWindow *win = ((MainWindow *)this->parent());
+    MainForm *form = win->uiInfo->getMainForm();
+
+    /* bezel */
+    SkinBezelItem *bezelItem = new SkinBezelItem(form->skinImg[MainForm::normal]);
+    scene()->addItem(bezelItem);
+
+    /* HW keys */
+    QList<HardwareKey *> keyList = form->keyList;
+
+    HardwareKey *hwKey = NULL;
+    for (int i = 0; i < keyList.count(); i++) {
+        hwKey = keyList.at(i);
+        if (hwKey != NULL) {
+            new SkinKeyItem(form->skinImg[MainForm::pressed].copy(hwKey->region),
+                    hwKey, bezelItem);
+        }
+    }
+}
+
+void SkinView::rotate()
+{
+    scene()->clear();
+    createItems();
+
+    adjustSize();
+}
+
+void SkinView::resizeEvent(QResizeEvent *event)
+{
+    Q_UNUSED(event)
+
+    qDebug("resize skin view");
+
+    MainWindow *win = ((MainWindow *)this->parent());
+
+    /* geometry */
+    const int width = win->uiInfo->getUiSize().width();
+    const int height = win->uiInfo->getUiSize().height();
+    setGeometry(0, 0, width, height);
+
+    /* scaling */
+    const qreal sx = win->getUIState()->getScaleFactor();
+    const qreal sy = win->getUIState()->getScaleFactor();
+    QTransform transform(sx, 0, 0, 0, sy, 0, 0, 0, 1);
+    setTransform(transform);
+
+    //QGraphicsView::resizeEvent(event);
+}
+
+void SkinView::mousePressEvent(QMouseEvent *event)
+{
+    //qDebug("pressed %dx%d", event->x(), event->y());
+
+    if (event->button() == Qt::LeftButton) {
+        //qDebug("grab");
+
+        QWidget *win = ((QWidget *) this->parent());
+        grabWinPos = win->pos();
+        grabPos = event->globalPos();
+    }
+
+    QGraphicsView::mousePressEvent(event);
+}
+
+void SkinView::mouseReleaseEvent(QMouseEvent *event)
+{
+    //qDebug("released %dx%d", event->x(), event->y());
+
+    if (event->button() == Qt::LeftButton) {
+        //qDebug("unloose");
+
+        grabPos = QPoint(-1, -1);
+    }
+
+    QGraphicsView::mouseReleaseEvent(event);
+}
+
+void SkinView::mouseMoveEvent(QMouseEvent *event)
+{
+    QWidget *win = ((QWidget *)this->parent());
+
+    if (grabPos != QPoint(-1, -1)) {
+        win->move(grabWinPos + (event->globalPos() - grabPos));
+    }
+
+    QGraphicsView::mouseMoveEvent(event);
+}
+
+void SkinView::focusOutEvent(QFocusEvent *event)
+{
+    qDebug() << "focus out!";
+    this->kbd->autoKeyRelease();
+}
+
+void SkinView::keyPressEvent(QKeyEvent *event)
+{
+    this->kbd->keyPressed(event);
+}
+
+void SkinView::keyReleaseEvent(QKeyEvent *event)
+{
+    this->kbd->keyReleased(event);
+}
+
+SkinView::~SkinView()
+{
+    qDebug("destroy skin view");
+}
diff --git a/tizen/src/ui/skinview.h b/tizen/src/ui/skinview.h
new file mode 100644 (file)
index 0000000..abbdc42
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 SKINVIEW_H
+#define SKINVIEW_H
+
+#include <QGraphicsView>
+
+#include "keyboardhelper.h"
+
+class SkinView : public QGraphicsView
+{
+public:
+    SkinView(QGraphicsScene *scene, QWidget *parent = 0);
+    ~SkinView();
+
+    void rotate();
+
+protected:
+    void resizeEvent(QResizeEvent *event);
+
+    void mousePressEvent(QMouseEvent *event);
+    void mouseReleaseEvent(QMouseEvent *event);
+    void mouseMoveEvent(QMouseEvent *event);
+    void keyPressEvent(QKeyEvent *event);
+    void keyReleaseEvent(QKeyEvent *event);
+    void focusOutEvent(QFocusEvent *event);
+
+    QPoint grabWinPos;
+    QPoint grabPos;
+    KeyboardHelper *kbd;
+
+private:
+    void createItems();
+};
+
+#endif // SKINVIEW_H
diff --git a/tizen/src/ui/uiinformation.cpp b/tizen/src/ui/uiinformation.cpp
new file mode 100644 (file)
index 0000000..0b7e878
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "uiinformation.h"
+
+UIInformation::UIInformation() :
+    resolution(0, 0), basePort(0)
+{
+    vmDataPath = "./";
+    skinPath = "./";
+}
+
+MainForm *UIInformation::getMainForm()
+{
+    int index = uiState.getMainFormIndex();
+
+    if (index > (mainFormList.count() - 1) || index < 0) {
+        qWarning("invalid form found");
+
+        uiState.mainFormAngle = 0;
+    }
+
+    return mainFormList.at(index);
+}
+
+ControllerForm *UIInformation::getConForm()
+{
+    int index = uiState.conState.getConFormIndex();
+
+    if (index > (conFormList.count() - 1) || index < 0) {
+        qWarning("invalid form found");
+
+        uiState.conState.conFormIndex = 0;
+    }
+
+    return conFormList.at(index);
+}
+
+QSize UIInformation::getMainSize()
+{
+    MainForm *mainForm = getMainForm();
+    if (mainForm == NULL) {
+        qWarning("main form is null");
+        return QSize(0, 0);
+    }
+
+    return mainForm->skinImg[MainForm::normal].size() * uiState.getScaleFactor();
+}
+
+QSize UIInformation::getConSize()
+{
+    ControllerForm *conForm = getConForm();
+    if (conForm == NULL) {
+        qWarning("controller form is null");
+        return QSize(0, 0);
+    }
+
+    return conForm->conImg[ControllerForm::normal].size();
+}
+
+QSize UIInformation::getUiSize()
+{
+    QSize uiSize = getMainSize();
+
+    /* docking controller */
+    if (uiState.conState.dockingCon != NULL) {
+        QSize conSize = getConSize();
+        uiSize.setWidth(uiSize.width() + conSize.width());
+    }
+
+    return uiSize;
+}
+
+QRegion UIInformation::getMainRegion()
+{
+    MainForm *mainForm = getMainForm();
+    if (mainForm == NULL) {
+        qWarning("main form is null");
+        return QRegion(0, 0, 100, 100);
+    }
+
+    QImage *mainImage = &(mainForm->skinImg[MainForm::normal]);
+    QImage regionImage = mainImage->scaled(
+        mainImage->width() * uiState.getScaleFactor(),
+        mainImage->height() * uiState.getScaleFactor()).createAlphaMask();
+
+    return QRegion(QBitmap::fromImage(regionImage));
+}
+
+QRegion UIInformation::getConRegion()
+{
+    ControllerForm *conForm = getConForm();
+    if (conForm == NULL) {
+        qWarning("controller form is null");
+        return QRegion(0, 0, 0, 0);
+    }
+
+    QImage *conImage = &(conForm->conImg[ControllerForm::normal]);
+
+    return QRegion(QBitmap::fromImage(conImage->createAlphaMask()));
+}
+
+QRegion UIInformation::getUiRegion()
+{
+    QRegion uiRegion = getMainRegion();
+
+    /* docking controller */
+    DockingController *con = uiState.conState.dockingCon;
+    if (con != NULL) {
+        QRegion conRegion = getConRegion();
+
+        int vShift = 0;
+        if (getMainSize().height() > getConSize().height()) {
+            if (con->getDockPos() & Qt::AlignCenter) {
+                vShift = (getMainSize().height() / 2)
+                    - (getConSize().height() / 2);
+            } else if (con->getDockPos() & Qt::AlignBottom) {
+                vShift = getMainSize().height() - getConSize().height();
+            }
+        }
+
+        conRegion.translate(getMainSize().width() + 1, vShift);
+        uiRegion = uiRegion.united(conRegion);
+    }
+
+    return uiRegion;
+}
+
+UIInformation::~UIInformation()
+{
+    qDebug("destroy UI info");
+
+    for (int i = 0; i < mainFormList.count(); i++) {
+        delete mainFormList.at(i);
+    }
+    mainFormList.clear();
+
+    for (int i = 0; i < conFormList.count(); i++) {
+        delete conFormList.at(i);
+    }
+    conFormList.clear();
+}
diff --git a/tizen/src/ui/uiinformation.h b/tizen/src/ui/uiinformation.h
new file mode 100644 (file)
index 0000000..14e7fa3
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 UIINFORMATION_H
+#define UIINFORMATION_H
+
+#include <QtWidgets>
+
+#include "mainform.h"
+#include "uistate.h"
+#include "controllerform.h"
+
+class UIInformation
+{
+public:
+    UIInformation();
+    ~UIInformation();
+
+    QString vmName;
+    QSize resolution;
+    int basePort;
+    QString vmDataPath;
+
+    QString skinPath;
+    QString skinName;
+    QList<MainForm *> mainFormList;
+    QList<ControllerForm *> conFormList;
+    QColor hoverColor;
+
+    UIState uiState; /* runtime information */
+
+    MainForm *getMainForm(); /* current */
+    ControllerForm *getConForm();
+    QSize getMainSize();
+    QSize getConSize();
+    QSize getUiSize(); /* size included main, docking con */
+    QRegion getMainRegion();
+    QRegion getConRegion();
+    QRegion getUiRegion(); /* size included main, docking con */
+};
+
+#endif // UIINFORMATION_H
diff --git a/tizen/src/ui/uistate.cpp b/tizen/src/ui/uistate.cpp
new file mode 100644 (file)
index 0000000..938d7c8
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "uistate.h"
+
+UIState::UIState() :
+    mainFormAngle(0), mainFormScale(100)
+{
+    onTop = false;
+    conState.conFormIndex = 0;
+    conState.dockingCon = NULL;
+    conState.floatingCon = NULL;
+    conState.recentlyDockPos = -1;
+    conState.recentlyFloatPos = QPoint(-1, -1);
+}
+
+int UIState::getMainFormIndex(int angle)
+{
+    // TODO: map
+
+    int index = 0;
+
+    switch(angle) {
+    case 90: /* Reverse Landscape */
+        index = 3;
+        break;
+    case 180: /* Reverse Portrait */
+        index = 2;
+        break;
+    case 270: /* Landscape */
+        index = 1;
+        break;
+    case 0:
+    default:
+        index = 0;
+        break;
+    }
+
+    return index;
+}
+
+int UIState::getMainFormIndex()
+{
+    return getMainFormIndex(mainFormAngle);
+}
+
+qreal UIState::getScaleFactor(int scale)
+{
+    return ((qreal)scale) / 100;
+}
+
+qreal UIState::getScaleFactor()
+{
+    return getScaleFactor(this->mainFormScale);
+}
+
+void UIState::setOnTop(bool on)
+{
+    qDebug("set on top : %d", on);
+
+    onTop = on;
+}
+
+bool UIState::isOnTop()
+{
+    return onTop;
+}
diff --git a/tizen/src/ui/uistate.h b/tizen/src/ui/uistate.h
new file mode 100644 (file)
index 0000000..392881b
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 UISTATE_H
+#define UISTATE_H
+
+#include "dockingcontroller.h"
+#include "floatingcontroller.h"
+
+class ControllerState
+{
+public:
+    inline int getConFormIndex() {
+        return conFormIndex;
+    }
+
+    int conFormIndex;
+    DockingController *dockingCon;
+    FloatingController *floatingCon;
+    int recentlyDockPos;
+    QPoint recentlyFloatPos;
+};
+
+class UIState
+{
+public:
+    UIState();
+
+    int getMainFormIndex(int angle);
+    int getMainFormIndex(); /* current */
+    qreal getScaleFactor(int scale);
+    qreal getScaleFactor(); /* current */
+
+    void setOnTop(bool on);
+    bool isOnTop();
+
+    int mainFormAngle;
+    int mainFormScale; /* percentage */
+
+    ControllerState conState;
+
+private:
+    bool onTop;
+};
+
+#endif // UISTATE_H
diff --git a/tizen/src/ui/uiutil.cpp b/tizen/src/ui/uiutil.cpp
new file mode 100644 (file)
index 0000000..ab2959a
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "uiutil.h"
+
+UIUtil::UIUtil()
+{
+    /* do nothing */
+}
+
+QRect UIUtil::getHostScreenBounds()
+{
+    return QApplication::screens().at(
+        QApplication::desktop()->primaryScreen())->virtualGeometry();
+}
diff --git a/tizen/src/ui/uiutil.h b/tizen/src/ui/uiutil.h
new file mode 100644 (file)
index 0000000..b7e20d0
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 UIUTIL_H
+#define UIUTIL_H
+
+#include <QApplication>
+#include <QDesktopWidget>
+#include <QScreen>
+#include <QRect>
+
+class UIUtil
+{
+public:
+    UIUtil();
+
+    static QRect getHostScreenBounds();
+};
+
+#endif // UIUTIL_H
diff --git a/tizen/src/ui/xml/Makefile.objs b/tizen/src/ui/xml/Makefile.objs
new file mode 100644 (file)
index 0000000..3b999b8
--- /dev/null
@@ -0,0 +1,26 @@
+obj-$(CONFIG_QT) += emulatoruitype.o moc_emulatoruitype.o
+obj-$(CONFIG_QT) += formlisttype.o moc_formlisttype.o
+obj-$(CONFIG_QT) += formtype.o moc_formtype.o
+obj-$(CONFIG_QT) += hardwarekeytype.o moc_hardwarekeytype.o
+obj-$(CONFIG_QT) += regiontype.o moc_regiontype.o
+obj-$(CONFIG_QT) += keylisttype.o moc_keylisttype.o
+
+$(obj)/moc_emulatoruitype.o: $(obj)/moc_emulatoruitype.cpp
+$(obj)/moc_emulatoruitype.cpp: $(obj)/emulatoruitype.h
+       moc $< -o $@
+$(obj)/moc_formlisttype.o: $(obj)/moc_formlisttype.cpp
+$(obj)/moc_formlisttype.cpp: $(obj)/formlisttype.h
+       moc $< -o $@
+$(obj)/moc_formtype.o: $(obj)/moc_formtype.cpp
+$(obj)/moc_formtype.cpp: $(obj)/formtype.h
+       moc $< -o $@
+$(obj)/moc_hardwarekeytype.o: $(obj)/moc_hardwarekeytype.cpp
+$(obj)/moc_hardwarekeytype.cpp: $(obj)/hardwarekeytype.h
+       moc $< -o $@
+$(obj)/moc_regiontype.o: $(obj)/moc_regiontype.cpp
+$(obj)/moc_regiontype.cpp: $(obj)/regiontype.h
+       moc $< -o $@
+$(obj)/moc_keylisttype.o: $(obj)/moc_keylisttype.cpp
+$(obj)/moc_keylisttype.cpp: $(obj)/keylisttype.h
+       moc $< -o $@
+
diff --git a/tizen/src/ui/xml/emulatoruitype.cpp b/tizen/src/ui/xml/emulatoruitype.cpp
new file mode 100644 (file)
index 0000000..cb81765
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "emulatoruitype.h"
+
+EmulatorUIType::EmulatorUIType(QObject *parent) :
+    QObject(parent)
+{
+    /* do nothing */
+}
+
+FormListType *EmulatorUIType::formListType()
+{
+    return formList;
+}
+
+void EmulatorUIType::setFormListType(FormListType *formList)
+{
+    this->formList = formList;
+}
diff --git a/tizen/src/ui/xml/emulatoruitype.h b/tizen/src/ui/xml/emulatoruitype.h
new file mode 100644 (file)
index 0000000..e5e4dd0
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 EMULATORUITYPE_H
+#define EMULATORUITYPE_H
+
+#include <QObject>
+
+#include "formlisttype.h"
+
+class EmulatorUIType : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(FormListType *formListType READ formListType WRITE setFormListType)
+    Q_CLASSINFO("DefaultProperty", "formListType")
+
+public:
+    explicit EmulatorUIType(QObject *parent = 0);
+
+    FormListType *formListType();
+
+private:
+    void setFormListType(FormListType *formList);
+
+    FormListType *formList;
+};
+
+#endif // EMULATORUITYPE_H
diff --git a/tizen/src/ui/xml/formlisttype.cpp b/tizen/src/ui/xml/formlisttype.cpp
new file mode 100644 (file)
index 0000000..f2b7d90
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "formlisttype.h"
+
+FormListType::FormListType(QObject *parent) :
+    QObject(parent)
+{
+    /* do nothing */
+}
+
+QQmlListProperty<FormType> FormListType::formList()
+{
+    return QQmlListProperty<FormType>(this, list);
+}
+
+QList<FormType *> *FormListType::getFormList()
+{
+    return &list;
+}
diff --git a/tizen/src/ui/xml/formlisttype.h b/tizen/src/ui/xml/formlisttype.h
new file mode 100644 (file)
index 0000000..d94a47e
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 FORMLISTTYPE_H
+#define FORMLISTTYPE_H
+
+#include <QObject>
+#include <QQmlListProperty>
+
+#include "formtype.h"
+
+class FormListType : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(QQmlListProperty<FormType> formList READ formList)
+    Q_CLASSINFO("DefaultProperty", "formList")
+
+public:
+    explicit FormListType(QObject *parent = 0);
+
+    QList<FormType *> *getFormList();
+
+private:
+    QQmlListProperty<FormType> formList();
+
+    QList<FormType *> list;
+};
+
+#endif // FORMLISTTYPE_H
diff --git a/tizen/src/ui/xml/formtype.cpp b/tizen/src/ui/xml/formtype.cpp
new file mode 100644 (file)
index 0000000..0f73981
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "formtype.h"
+
+FormType::FormType(QObject *parent) :
+    QObject(parent), keyList(NULL)
+{
+    /* do nothing */
+}
+
+RegionType *FormType::displayRegionType()
+{
+    return displayRegion;
+}
+
+void FormType::setDisplayRegionType(RegionType *displayRegion)
+{
+    this->displayRegion = displayRegion;
+}
+
+QString FormType::mainImageName() const
+{
+    return mainImgName;
+}
+
+void FormType::setMainImageName(QString imgFileName)
+{
+    mainImgName = imgFileName;
+}
+
+QString FormType::pressedImageName() const
+{
+    return pressedImgName;
+}
+
+void FormType::setPressedImageName(QString imgFileName)
+{
+    pressedImgName = imgFileName;
+}
+
+KeyListType *FormType::keyListType()
+{
+    return keyList;
+}
+
+void FormType::setKeyListType(KeyListType *keyList)
+{
+    this->keyList = keyList;
+}
+
+QRect FormType::getDisplayRegion()
+{
+    if (displayRegion == NULL) {
+        return QRect(0, 0, 0, 0);
+    }
+
+    return displayRegion->region();
+}
diff --git a/tizen/src/ui/xml/formtype.h b/tizen/src/ui/xml/formtype.h
new file mode 100644 (file)
index 0000000..c9eec66
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 FORMTYPE_H
+#define FORMTYPE_H
+
+#include <QObject>
+
+#include "keylisttype.h"
+#include "regiontype.h"
+
+class FormType : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(RegionType *display READ displayRegionType WRITE setDisplayRegionType)
+    Q_PROPERTY(QString mainImage READ mainImageName WRITE setMainImageName)
+    Q_PROPERTY(QString pressedImage READ pressedImageName WRITE setPressedImageName)
+    Q_PROPERTY(KeyListType *keyListType READ keyListType WRITE setKeyListType)
+    Q_CLASSINFO("DefaultProperty", "keyListType")
+
+public:
+    explicit FormType(QObject *parent = 0);
+
+    QString mainImageName() const;
+    QString pressedImageName() const;
+    KeyListType *keyListType();
+
+    QRect getDisplayRegion();
+
+private:
+    RegionType *displayRegionType();
+    void setDisplayRegionType(RegionType *displayRegion);
+    void setMainImageName(QString imgFileName);
+    void setPressedImageName(QString imgFileName);
+    void setKeyListType(KeyListType *keyList);
+
+    RegionType *displayRegion;
+    QString mainImgName;
+    QString pressedImgName;
+    KeyListType *keyList;
+};
+
+#endif // FORMTYPE_H
diff --git a/tizen/src/ui/xml/hardwarekeytype.cpp b/tizen/src/ui/xml/hardwarekeytype.cpp
new file mode 100644 (file)
index 0000000..4def9c8
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "hardwarekeytype.h"
+
+HardwareKeyType::HardwareKeyType(QObject *parent) :
+    QObject(parent)
+{
+    /* do nothing */
+}
+
+int HardwareKeyType::keycode() const
+{
+    return code;
+}
+
+void HardwareKeyType::setKeycode(int keycode)
+{
+    code = keycode;
+}
+
+QString HardwareKeyType::tooltip() const
+{
+    return tip;
+}
+
+void HardwareKeyType::setTooltip(const QString &tooltip)
+{
+    tip = tooltip;
+}
+
+RegionType *HardwareKeyType::keyRegionType()
+{
+    return keyRegion;
+}
+
+void HardwareKeyType::setKeyRegionType(RegionType *keyRegion)
+{
+    this->keyRegion = keyRegion;
+}
+
+QRect HardwareKeyType::region()
+{
+    if (keyRegion == NULL) {
+        return QRect(0, 0, 0, 0);
+    }
+
+    return keyRegion->region();
+}
diff --git a/tizen/src/ui/xml/hardwarekeytype.h b/tizen/src/ui/xml/hardwarekeytype.h
new file mode 100644 (file)
index 0000000..f4ef8da
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 HARDWAREKEYTYPE_H
+#define HARDWAREKEYTYPE_H
+
+#include <QObject>
+
+#include "regiontype.h"
+
+class HardwareKeyType : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(int keycode READ keycode WRITE setKeycode)
+    Q_PROPERTY(QString tooltip READ tooltip WRITE setTooltip)
+    Q_PROPERTY(RegionType *keyRegionType READ keyRegionType WRITE setKeyRegionType)
+    Q_CLASSINFO("DefaultProperty", "keyRegionType")
+
+public:
+    explicit HardwareKeyType(QObject *parent = 0);
+
+    int keycode() const;
+    QString tooltip() const;
+
+    QRect region();
+
+private:
+    void setKeycode(int keycode);
+    void setTooltip(const QString &tooltip);
+    RegionType *keyRegionType();
+    void setKeyRegionType(RegionType *regionType);
+
+    int code;
+    QString tip;
+    RegionType *keyRegion;
+};
+
+#endif // HARDWAREKEYTYPE_H
diff --git a/tizen/src/ui/xml/keylisttype.cpp b/tizen/src/ui/xml/keylisttype.cpp
new file mode 100644 (file)
index 0000000..6280cd1
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "keylisttype.h"
+
+KeyListType::KeyListType(QObject *parent) :
+    QObject(parent)
+{
+    /* do nothing */
+}
+
+QQmlListProperty<HardwareKeyType> KeyListType::keyListType()
+{
+    return QQmlListProperty<HardwareKeyType>(this, list);
+}
+
+QList<HardwareKeyType *> *KeyListType::getKeyList()
+{
+    return &list;
+}
+
diff --git a/tizen/src/ui/xml/keylisttype.h b/tizen/src/ui/xml/keylisttype.h
new file mode 100644 (file)
index 0000000..5427f50
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 KEYLISTTYPE_H
+#define KEYLISTTYPE_H
+
+#include <QObject>
+#include <QQmlListProperty>
+
+#include "hardwarekeytype.h"
+
+class KeyListType : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(QQmlListProperty<HardwareKeyType> keyListType READ keyListType)
+    Q_CLASSINFO("DefaultProperty", "keyListType")
+
+public:
+    explicit KeyListType(QObject *parent = 0);
+
+    QList<HardwareKeyType *> *getKeyList();
+
+private:
+    QQmlListProperty<HardwareKeyType> keyListType();
+
+    QList<HardwareKeyType *> list;
+};
+
+#endif // KEYLISTTYPE_H
diff --git a/tizen/src/ui/xml/regiontype.cpp b/tizen/src/ui/xml/regiontype.cpp
new file mode 100644 (file)
index 0000000..ac370dc
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 "regiontype.h"
+
+RegionType::RegionType(QObject *parent) :
+    QObject(parent), x(0), y(0), w(0), h(0)
+{
+    /* do nothing */
+}
+
+int RegionType::left()
+{
+    return x;
+}
+
+void RegionType::setLeft(int left)
+{
+    x = left;
+}
+
+int RegionType::top()
+{
+    return y;
+}
+
+void RegionType::setTop(int top)
+{
+    y = top;
+}
+
+int RegionType::width()
+{
+    return w;
+}
+
+void RegionType::setWidth(int width)
+{
+    w = width;
+}
+
+int RegionType::height()
+{
+    return h;
+}
+
+void RegionType::setHeight(int height)
+{
+    h = height;
+}
+
+QRect RegionType::region() const
+{
+    return QRect(x, y, w, h);
+}
diff --git a/tizen/src/ui/xml/regiontype.h b/tizen/src/ui/xml/regiontype.h
new file mode 100644 (file)
index 0000000..e0885ab
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@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 REGIONTYPE_H
+#define REGIONTYPE_H
+
+#include <QObject>
+#include <QRect>
+
+class RegionType : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(int left READ left WRITE setLeft)
+    Q_PROPERTY(int top READ top WRITE setTop)
+    Q_PROPERTY(int width READ width WRITE setWidth)
+    Q_PROPERTY(int height READ height WRITE setHeight)
+
+public:
+    explicit RegionType(QObject *parent = 0);
+
+    int left();
+    int top();
+    int width();
+    int height();
+
+    QRect region() const;
+
+private:
+    void setLeft(int left);
+    void setTop(int top);
+    void setWidth(int width);
+    void setHeight(int height);
+
+    int x;
+    int y;
+    int w;
+    int h;
+};
+
+#endif // REGIONTYPE_H
index e9b3de0..286a422 100644 (file)
@@ -1,3 +1,11 @@
+ifdef CONFIG_WIN32
+QEMU_CFLAGS += -I$(SRC_PATH)/hw/vigs/vigs_inc
+endif
+
+ifdef CONFIG_DARWIN
+QEMU_CFLAGS += -I$(SRC_PATH)/hw/vigs/vigs_inc
+endif
+
 # osutil
 LIBS += $(CURL_LIBS)
 obj-y += osutil.o
index 379bab3..13c7573 100644 (file)
@@ -75,7 +75,6 @@ struct gl_context *check_gl_context_create(struct gl_context *share_ctx,
         kCGLPFAAlphaSize, 8,
         kCGLPFADepthSize, 24,
         kCGLPFAStencilSize, 8,
-        kCGLPFANoRecovery,
         kCGLPFAPBuffer,
         0
     };
@@ -88,7 +87,6 @@ struct gl_context *check_gl_context_create(struct gl_context *share_ctx,
         kCGLPFAAlphaSize, 8,
         kCGLPFADepthSize, 24,
         kCGLPFAStencilSize, 8,
-        kCGLPFANoRecovery,
         kCGLPFAOpenGLProfile, kCGLOGLPVersion_3_2_Core,
         0
     };
diff --git a/vl.c b/vl.c
index 1844efd..6cfce07 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -2198,13 +2198,26 @@ static DisplayType select_display(const char *p)
         exit(1);
 #endif
 #ifdef CONFIG_MARU
-# ifdef CONFIG_SDL
     } else if (strstart(p, "maru_sdl", &opts)) {
+# ifdef CONFIG_SDL
         display = DT_MARU_SDL;
+# else
+        fprintf(stderr, "maru_sdl support is disabled\n");
+        exit(1);
 # endif
-# ifdef CONFIG_USE_SHM
     } else if (strstart(p, "maru_shm", &opts)) {
+# ifdef CONFIG_USE_SHM
         display = DT_MARU_SHM;
+# else
+        fprintf(stderr, "maru_shm is disabled\n");
+        exit(1);
+# endif
+    } else if (strstart(p, "maru_qt", &opts)) {
+# ifdef CONFIG_QT
+        display = DT_MARU_QT;
+# else
+        fprintf(stderr, "maru_qt is disabled\n");
+        exit(1);
 # endif
 #endif /* CONFIG_MARU */
     } else if (strstart(p, "none", &opts)) {
@@ -3278,6 +3291,10 @@ int main(int argc, char **argv, char **envp)
                             "'%s' option", slots_str ? "maxmem" : "slots");
                     exit(EXIT_FAILURE);
                 }
+
+#ifdef CONFIG_MARU
+                set_emul_ram_size(optarg);
+#endif
                 break;
             }
 #ifdef CONFIG_TPM
@@ -3471,6 +3488,10 @@ int main(int argc, char **argv, char **envp)
                              qemu_opt_get(opts, "mount_tag"));
                 qemu_opt_set(device, "mount_tag",
                              qemu_opt_get(opts, "mount_tag"));
+
+#ifdef CONFIG_MARU
+                set_emul_file_sharing_path(qemu_opt_get(opts, "path"));
+#endif
                 break;
             }
             case QEMU_OPTION_virtfs_synth: {
@@ -3596,6 +3617,9 @@ int main(int argc, char **argv, char **envp)
            case QEMU_OPTION_enable_yagl:
 #if defined(CONFIG_YAGL)
                 enable_yagl = 1;
+#ifdef CONFIG_MARU
+                set_emul_gpu_accel(true);
+#endif
 #else
                 fprintf(stderr, "YaGL openGLES passthrough support is disabled,"
                     " ignoring -enable-yagl\n");
@@ -3974,6 +3998,10 @@ int main(int argc, char **argv, char **envp)
         exit(1);
     }
 
+#ifdef CONFIG_MARU
+    maru_display_early_init(display_type);
+#endif
+
     current_machine = MACHINE(object_new(object_class_get_name(
                           OBJECT_CLASS(machine_class))));
     object_property_add_child(object_get_root(), "machine",
@@ -4166,6 +4194,8 @@ int main(int argc, char **argv, char **envp)
         display_type = DT_MARU_SDL;
 #elif defined(CONFIG_USE_SHM)
         display_type = DT_MARU_SHM;
+#elif defined(CONFIG_QT)
+        display_type = DT_MARU_QT;
 #endif
 #elif defined(CONFIG_GTK)
         display_type = DT_GTK;
@@ -4520,6 +4550,11 @@ int main(int argc, char **argv, char **envp)
         start_skin();
         break;
 #endif
+#if defined(CONFIG_QT)
+    case DT_MARU_QT:
+        maru_display_init(ds, display_type, full_screen);
+        break;
+#endif
 #endif
     default:
         break;