update source for tizen_2.1
authorSooyoung Ha <yoosah.ha@samsung.com>
Wed, 3 Apr 2013 02:24:32 +0000 (11:24 +0900)
committerSooyoung Ha <yoosah.ha@samsung.com>
Wed, 3 Apr 2013 02:24:32 +0000 (11:24 +0900)
116 files changed:
Makefile.target
exec.c
hw/virtio-pci.c
hw/virtio.h [changed mode: 0644->0755]
package/changelog
package/emulator-qemu-common.remove.ubuntu-32
package/emulator-qemu-common.remove.ubuntu-64
package/emulator-qemu-x86.install.ubuntu-32 [moved from package/emulator-qemu-common.install.ubuntu-32 with 81% similarity]
package/emulator-qemu-x86.install.ubuntu-64 [moved from package/emulator-qemu-common.install.ubuntu-64 with 81% similarity]
package/pkginfo.manifest
tizen/distrib/initscript/tizen_kvm [new file with mode: 0755]
tizen/src/Makefile
tizen/src/Makefile.tizen
tizen/src/SDL_gfx/AUTHORS [new file with mode: 0644]
tizen/src/SDL_gfx/COPYING [new file with mode: 0644]
tizen/src/SDL_gfx/LICENSE [new file with mode: 0644]
tizen/src/SDL_gfx/README [new file with mode: 0644]
tizen/src/SDL_gfx/SDL_rotozoom.c [new file with mode: 0644]
tizen/src/SDL_gfx/SDL_rotozoom.h [new file with mode: 0644]
tizen/src/VERSION
tizen/src/check_gl.c [new file with mode: 0644]
tizen/src/debug_ch.c
tizen/src/debug_ch.h
tizen/src/emul_state.c
tizen/src/emul_state.h
tizen/src/emul_state_darwin.m [moved from tizen/src/option.h with 64% similarity]
tizen/src/emulator.c
tizen/src/emulator.h
tizen/src/hw/gl_func_perso.h
tizen/src/hw/gloffscreen.h
tizen/src/hw/gloffscreen_agl.c [new file with mode: 0644]
tizen/src/hw/gloffscreen_test.c
tizen/src/hw/gloffscreen_test.h [new file with mode: 0644]
tizen/src/hw/gloffscreen_wgl.c
tizen/src/hw/gloffscreen_xcomposite.c
tizen/src/hw/maru_brightness.c
tizen/src/hw/maru_brightness.h
tizen/src/hw/maru_camera_common.h
tizen/src/hw/maru_camera_common_pci.c
tizen/src/hw/maru_camera_darwin.h
tizen/src/hw/maru_camera_darwin_converter.c
tizen/src/hw/maru_camera_darwin_pci.m
tizen/src/hw/maru_camera_linux_pci.c
tizen/src/hw/maru_camera_win32_interface.h
tizen/src/hw/maru_camera_win32_pci.c
tizen/src/hw/maru_device_ids.h
tizen/src/hw/maru_overlay.c
tizen/src/hw/maru_overlay.h
tizen/src/hw/maru_vga.c
tizen/src/hw/maru_virtio_hwkey.c [new file with mode: 0644]
tizen/src/hw/maru_virtio_hwkey.h [new file with mode: 0644]
tizen/src/hw/maru_virtio_keyboard.c
tizen/src/hw/maru_virtio_keyboard.h
tizen/src/hw/maru_virtio_touchscreen.c
tizen/src/hw/maru_virtio_touchscreen.h
tizen/src/hw/opengl_exec.c
tizen/src/hw/opengl_func.h
tizen/src/maru_common.h
tizen/src/maru_display.h
tizen/src/maru_sdl.c
tizen/src/mloop_event.c
tizen/src/mloop_event.h
tizen/src/ns_event.h
tizen/src/ns_event.m
tizen/src/option.c [deleted file]
tizen/src/osutil-darwin.c [new file with mode: 0644]
tizen/src/osutil-linux.c [new file with mode: 0644]
tizen/src/osutil-win32.c [new file with mode: 0644]
tizen/src/osutil.c [new file with mode: 0644]
tizen/src/osutil.h [new file with mode: 0644]
tizen/src/sdb.c
tizen/src/sdb.h
tizen/src/skin/client/build.xml
tizen/src/skin/client/native_src/share.c
tizen/src/skin/client/resource/images/key-window/scroll_back.png [new file with mode: 0644]
tizen/src/skin/client/resource/images/key-window/scroll_button_down_hover.png [new file with mode: 0644]
tizen/src/skin/client/resource/images/key-window/scroll_button_down_nml.png [new file with mode: 0644]
tizen/src/skin/client/resource/images/key-window/scroll_button_down_pushed.png [new file with mode: 0644]
tizen/src/skin/client/resource/images/key-window/scroll_button_up_hover.png [new file with mode: 0644]
tizen/src/skin/client/resource/images/key-window/scroll_button_up_nml.png [new file with mode: 0644]
tizen/src/skin/client/resource/images/key-window/scroll_button_up_pushed.png [new file with mode: 0644]
tizen/src/skin/client/resource/images/key-window/scroll_thumb.png [new file with mode: 0644]
tizen/src/skin/client/skins/emul-320x480/default.dbi
tizen/src/skin/client/skins/emul-480x800/default.dbi
tizen/src/skin/client/skins/emul-600x1024/default.dbi
tizen/src/skin/client/skins/emul-720x1280/default.dbi
tizen/src/skin/client/skins/emul-general/default.dbi
tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorFingers.java
tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSdlSkin.java
tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorShmSkin.java
tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSkin.java
tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSkinMain.java
tizen/src/skin/client/src/org/tizen/emulator/skin/comm/ICommunicator.java
tizen/src/skin/client/src/org/tizen/emulator/skin/comm/sock/SocketCommunicator.java
tizen/src/skin/client/src/org/tizen/emulator/skin/comm/sock/data/DisplayStateData.java [new file with mode: 0644]
tizen/src/skin/client/src/org/tizen/emulator/skin/config/EmulatorConfig.java
tizen/src/skin/client/src/org/tizen/emulator/skin/custom/ColorTag.java [new file with mode: 0644]
tizen/src/skin/client/src/org/tizen/emulator/skin/custom/CustomButton.java [new file with mode: 0644]
tizen/src/skin/client/src/org/tizen/emulator/skin/custom/CustomProgressBar.java [new file with mode: 0644]
tizen/src/skin/client/src/org/tizen/emulator/skin/custom/CustomScrollBar.java [new file with mode: 0644]
tizen/src/skin/client/src/org/tizen/emulator/skin/custom/CustomScrolledComposite.java [new file with mode: 0644]
tizen/src/skin/client/src/org/tizen/emulator/skin/custom/CustomScrolledCompositeLayout.java [new file with mode: 0644]
tizen/src/skin/client/src/org/tizen/emulator/skin/custom/KeyWindow.java [new file with mode: 0644]
tizen/src/skin/client/src/org/tizen/emulator/skin/custom/SkinWindow.java [new file with mode: 0644]
tizen/src/skin/client/src/org/tizen/emulator/skin/dialog/AboutDialog.java
tizen/src/skin/client/src/org/tizen/emulator/skin/image/ImageRegistry.java
tizen/src/skin/client/src/org/tizen/emulator/skin/layout/GeneralPurposeSkinComposer.java
tizen/src/skin/client/src/org/tizen/emulator/skin/layout/PhoneShapeSkinComposer.java
tizen/src/skin/client/src/org/tizen/emulator/skin/util/SkinUtil.java
tizen/src/skin/maruskin_client.c
tizen/src/skin/maruskin_client.h
tizen/src/skin/maruskin_keymap.h
tizen/src/skin/maruskin_operation.c
tizen/src/skin/maruskin_server.c
tizen/src/skin/maruskin_server.h
vl.c [changed mode: 0644->0755]

index 60d860e..4371991 100755 (executable)
@@ -62,7 +62,7 @@ else
 stap:
 endif
 
-all: $(PROGS) stap
+all: $(PROGS) stap check-gl
 
 # Dummy command so that make thinks it has done something
        @true
@@ -322,6 +322,30 @@ $(QEMU_PROG): $(all-obj-y)
        $(call LINK,$^)
 endif
 
+CHECK_GL_OBJS = check_gl.o gloffscreen_test.o gloffscreen_common.o 
+CHECK_GL_LDFLAGS =
+CHECK_GL_TARGET =
+ifdef CONFIG_LINUX
+CHECK_GL_OBJS += gloffscreen_xcomposite.o
+CHECK_GL_LDFLAGS += -lGL -lXcomposite -lXext -lglib-2.0
+CHECK_GL_TARGET = check-gl
+endif
+ifdef CONFIG_WIN32
+CHECK_GL_OBJS += gloffscreen_wgl.o
+CHECK_GL_LDFLAGS += -fstack-protector `pkg-config --libs glib-2.0` -lopengl32 -lglu32 -lgdi32
+CHECK_GL_TARGET = check-gl.exe
+endif
+ifdef CONFIG_DARWIN
+CHECK_GL_OBJS += gloffscreen_agl.o
+CHECK_GL_LDFLAGS += -mmacosx-version-min=10.4 `pkg-config --cflags --libs glib-2.0` -framework GLUT -framework OpenGL -framework AGL
+CHECK_GL_TARGET = check-gl
+endif
+
+check-gl: check_gl.o
+       gcc -o $(CHECK_GL_TARGET) $(CHECK_GL_OBJS) $(CHECK_GL_LDFLAGS)
+check_gl.o: check_gl.c
+       gcc -c ../tizen/src/check_gl.c
+
 gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh
        $(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES),"  GEN   $(TARGET_DIR)$@")
 
diff --git a/exec.c b/exec.c
index a64e70b..8e6bf12 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -1386,10 +1386,10 @@ void tb_link_page(TranslationBlock *tb,
 /* check whether the given addr is in TCG generated code buffer or not */
 bool is_tcg_gen_code(uintptr_t tc_ptr)
 {
-    /* This can be called during code generation, code_gen_buffer_max_size
+    /* This can be called during code generation, code_gen_buffer_size
        is used instead of code_gen_ptr for upper boundary checking */
     return (tc_ptr >= (uintptr_t)code_gen_buffer &&
-            tc_ptr < (uintptr_t)(code_gen_buffer + code_gen_buffer_max_size));
+            tc_ptr < (uintptr_t)(code_gen_buffer + code_gen_buffer_size));
 }
 #endif
 
index 8ff80d9..eb6e236 100644 (file)
@@ -970,6 +970,29 @@ static void virtio_esm_exit_pci(PCIDevice *pci_dev)
     virtio_esm_exit(proxy->vdev);
     virtio_exit_pci(pci_dev);
 }
+
+static int virtio_hwkey_init_pci(PCIDevice *pci_dev)
+{
+    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+    VirtIODevice *vdev;
+
+    vdev = maru_virtio_hwkey_init(&pci_dev->qdev);
+    if (!vdev) {
+        return -1;
+    }
+    virtio_init_pci(proxy, vdev);
+    return 0;
+}
+
+static void virtio_hwkey_exit_pci(PCIDevice *pci_dev)
+{
+    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+
+    virtio_pci_stop_ioeventfd(proxy);
+    maru_virtio_hwkey_exit(proxy->vdev);
+    virtio_exit_pci(pci_dev);
+}
+
 #endif
 
 static Property virtio_blk_properties[] = {
@@ -1245,6 +1268,28 @@ static TypeInfo virtio_esm_info = {
     .instance_size = sizeof(VirtIOPCIProxy),
     .class_init    = virtio_esm_class_init,
 };
+
+static void virtio_hwkey_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_hwkey_init_pci;
+    k->exit = virtio_hwkey_exit_pci;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    k->device_id = PCI_DEVICE_ID_VIRTIO_HWKEY;
+    k->revision = VIRTIO_PCI_ABI_VERSION;
+    k->class_id = PCI_CLASS_OTHERS;
+    dc->reset = virtio_pci_reset;
+}
+
+static TypeInfo virtio_hwkey_info = {
+    .name          = "virtio-hwkey-pci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(VirtIOPCIProxy),
+    .class_init    = virtio_hwkey_class_init,
+};
+
 #endif /* CONFIG_MARU */
 
 static void virtio_pci_register_types(void)
@@ -1261,6 +1306,7 @@ static void virtio_pci_register_types(void)
     type_register_static(&maru_virtio_touchscreen_info);
     type_register_static(&virtio_keyboard_info);
     type_register_static(&virtio_esm_info);
+    type_register_static(&virtio_hwkey_info);
 #endif
 }
 
old mode 100644 (file)
new mode 100755 (executable)
index 1a33b4c..0b03561
@@ -221,6 +221,7 @@ void virtio_scsi_exit(VirtIODevice *vdev);
 #include "tizen/src/hw/maru_virtio_touchscreen.h"
 #include "tizen/src/hw/maru_virtio_keyboard.h"
 #include "tizen/src/hw/maru_virtio_esm.h"
+#include "tizen/src/hw/maru_virtio_hwkey.h"
 #endif
 
 
index abcff52..d809731 100644 (file)
@@ -1,3 +1,198 @@
-* 2.0.0
-- Tizen 2.0 final release
-== SungMin Ha <sungmin82.ha@samsung.com> 2013-02-13
+* 1.5.22
+- no need to get the shmkey from another shm
+== GiWoong Kim <giwoong.kim@samsung.com> 2013-04-02
+* 1.5.21
+- Fixed a bug that a camera frame is not sent to FW.
+== Jinhyung Jo <jinhyung.jo@samsung.com> 2013-03-29
+* 1.5.20
+- modified skin's dbi file for key code of phone shape
+== Sungmin Ha <sungmin82.ha@samsung.com> 2013-03-29
+* 1.5.19
+- modified elem index and mutex lock in virtio-kbd
+== Sungmin Ha <sungmin82.ha@samsung.com> 2013-03-29
+* 1.5.18
+- Skip the display updates until the LCD is turned off
+== GiWoong Kim <giwoong.kim@samsung.com> 2013-03-28
+* 1.5.17
+- modified Makefile to library load on mac from check-gl
+== Sungmin Ha <sungmin82.ha@samsung.com> 2013-03-26
+* 1.5.16
+- Fix dibs install error by mis-typing.
+== Sangjin Kim <sangjin3.kim@samsung.com> 2013-03-25
+* 1.5.15
+- Fix dibs build error.
+== Sangjin Kim <sangjin3.kim@samsung.com> 2013-03-21
+* 1.5.14
+- Generate check-gl binary to use at an emulator-manager.
+== Sangjin Kim <sangjin3.kim@samsung.com> 2013-03-21
+* 1.5.13
+- Enable pbuffer surface.
+== Sangjin Kim <sangjin3.kim@samsung.com> 2013-03-20
+* 1.5.6
+- modified virtio hwkey device and improved hwkey mapping 
+== Sungmin Ha <sungmin82.ha@samsung.com> 2013-03-20
+* 1.5.5
+- moved kvm script files from qemu-common to qemu-x86 package. 
+== Kitae Kim <kt920.kim@samsung.com> 2013-03-15
+* 1.5.4
+- added routine in case that there is no gksudo.
+== Kitae Kim <kt920.kim@samsung.com> 2013-03-08
+* 1.5.03
+- modified path separator
+== GiWoong Kim <giwoong.kim@samsung.com> 2013-02-25
+* 1.5.02
+- Sync-up with tizen 2.0 latest gl source code.
+== Sangjin Kim <sangjin3.kim@samsung.com> 2013-02-21
+* 1.5.01
+- added virtio hwkey device
+== GiWoong Kim <giwoong.kim@samsung.com> 2013-02-21
+* 1.4.90
+- version up
+== SungMin Ha <sungmin82.ha@samsung.com> 2013-02-15
+* 1.4.89
+- added bottom half instead of mloop
+== GiWoong Kim <giwoong.kim@samsung.com> 2013-02-15
+* 1.4.80
+- version up for making new package
+== Munkyu Im <munkyu.im@samsung.com> 2013-02-04
+* 1.4.79
+- added pthread_mutex_destroy
+== GiWoong Kim <giwoong.kim@samsung.com> 2013-01-29
+* 1.4.76
+- prepare 10 colors for Pair Tag
+== GiWoong Kim <giwoong.kim@samsung.com> 2013-01-25
+* 1.4.67
+- Changed host keyboard status routine on OS X.
+== Kitae Kim <kt920.kim@samsung.com> 2013-01-24
+* 1.4.66
+- modified screenshot operation when vga is not ready
+== Sungmin Ha <sungmin82.ha@samsung.com> 2013-01-23
+* 1.4.65
+- version up for making new package
+== Munkyu Im <munkyu.im@samsung.com> 2013-01-22
+* 1.4.64
+- Fix emulator crash problem when using EffectsApp.
+== Sangjin Kim <sangjin3.kim@samsung.com> 2013-01-17
+* 1.4.62
+- removed ifndef for screenshot
+== Sungmin Ha <sungmin82.ha@samsung.com> 2013-01-17
+* 1.4.61
+- Fixed a problem about displayed useless line on screenshot
+== Sungmin Ha <sungmin82.ha@samsung.com> 2013-01-16
+* 1.4.60
+- removed setFocus on mac
+== GiWoong Kim <giwoong.kim@samsung.com> 2013-01-16
+* 1.4.58
+- modify init process
+== Munkyu Im <munkyu.im@samsung.com> 2013-01-16
+* 1.4.57
+- modified include path
+== GiWoong Kim <giwoong.kim@samsung.com> 2013-01-15
+* 1.4.55
+- move SDL_gfx files
+== GiWoong Kim <giwoong.kim@samsung.com> 2013-01-15
+* 1.4.51
+- control the focus in general skin
+== GiWoong Kim <giwoong.kim@samsung.com> 2013-01-14
+* 1.4.49
+- switch the z-order between main window and key window
+== GiWoong Kim <giwoong.kim@samsung.com> 2013-01-11
+* 1.4.43
+- change temp file path
+== Munkyu Im <munkyu.im@samsung.com> 2013-01-09
+* 1.4.42
+- fix dynamic loading library path
+== Munkyu Im <munkyu.im@samsung.com> 2013-01-04
+* 1.4.41
+- fix multi touch on Mac
+== Munkyu Im <munkyu.im@samsung.com> 2013-01-03
+* 1.4.40
+- version up
+== Munkyu Im <munkyu.im@samsung.com> 2013-01-03
+* 1.4.39
+- version up
+== Sooyoung Ha <yoosah.ha@samsung.com> 2013-01-03
+* 1.4.38
+- Fixed a memory leak while decoding video.
+== Kitae Kim <kt920.kim@samsung.com> 2012-12-28
+* 1.4.35
+- fix gl capability check fail on windows intel graphics machine.
+== Sangjin Kim <sangjin3.kim@samsung.com> 2012-12-28
+* 1.4.34
+- fix getting proxy
+== Munkyu Im <munkyu.im@samsung.com> 2012-12-27
+* 1.4.33
+- Fixed codec module and added function declarations for virtio-keyboard.
+== Kitae Kim <kt920.kim@samsung.com> 2012-12-18
+* 1.4.32
+- Copy sdbscript file to bin folder on mac.
+== GiWoong Kim <giwoong.kim@samsung.com> 2012-12-18
+* 1.4.25
+- Fixed a capture failure on Linux system.
+== Jinhyung Jo <jinhyung.jo@samsung.com> 2012-12-17
+* 1.4.24
+- Reverted dibs build script.
+- The previous build script was wrong.
+== Kitae Kim <kt920.kim@samsung.com> 2012-12-17
+* 1.4.23
+- Fixed an unexpected termination on Windows while previewing camera.
+== Jinhyung Jo <jinhyung.jo@samsung.com> 2012-12-17
+* 1.4.22
+- Added multi-touch control scenario
+== GiWoong Kim <giwoong.kim@samsung.com> 2012-12-10
+* 1.4.17
+- Added double quotation mark for path.
+== GiWoong Kim <giwoong.kim@samsung.com> 2012-12-06
+* 1.4.15
+- rearrange finger image when rotate
+== Munkyu In <munkyu.im@samsung.com> 2012-11-29
+* 1.4.14
+- added try-catch to AboutDialog
+== GiWoong Kim <giwoong.kim@samsung.com> 2012-11-29
+* 1.4.13
+- Text dimming issue fixed at windows with nvidia card.
+== Sangjin Kim <sangjin3.kim@samsung.com> 2012-11-28
+* 1.4.12
+- Convert a HW key container in general skin
+== GiWoong Kim <giwoong.kim@samsung.com> 2012-11-26
+* 1.4.9
+- Fix EGL_BAD_ALLOC error when using pixmap surface repeatedly.
+== Sangjin Kim <sangjin3.kim@samsung.com> 2012-11-22
+* 1.4.8
+- Added force close menu
+- Advanced>Force Close
+== GiWoong Kim <giwoong.kim@samsung.com> 2012-11-12
+* 1.4.7
+- Fixed a bug of brightness level
+== Jinhyung Jo <jinhyung.jo@samsung.com> 2012-11-15
+* 1.4.6
+- refactoring of skin code
+- Fixed N_SE-12805 issue
+== GiWoong Kim <giwoong.kim@samsung.com> 2012-11-14
+* 1.4.5
+- refactoring of skin code
+- Added EmulatorSkinState file & define ISkinComposer interface
+== GiWoong Kim <giwoong.kim@samsung.com> 2012-11-12
+* 1.4.4
+- Apply qemu_ld/st optimization according to QEMU 1.2
+== Yeongkyoon Lee <yeongkyoon.lee@samsung.com> 2012-11-09
+* 1.4.2
+- Added libattr1-dev, libcap library
+- Added libattr1-dev, libcap library
+== GiWoong Kim <giwoong.kim@samsung.com> 2012-11-08
+* 1.4.1
+- Disable folding button in general skin
+- Disable folding button in general skin
+== GiWoong Kim <giwoong.kim@samsung.com> 2012-11-06
+* 1.4.0
+- vga: Support HVGA, WXGA, HD1080, WQXGA resolution.
+- Support HVGA, WXGA, HD1080, WQXGA resolution.
+== Signed-off-by: Sangjin Kim <sangjin3.kim@samsung.com> 2012-11-02
+* 1.3.68
+- Don't lose the release event of HW key
+- Event if user releases the mouse cursor at outside of HW key area, it does not lose the event.
+== GiWoong Kim <giwoong.kim@samsung.com> 2012-10-29
+* 1.3.66
+- Change SDK version.
+- Change version from 2.0a3 to 2.0a4-RC1
+== Kitae Kim <kt920.kim@samsung.com> 2012-10-23
index f1f106e..26af735 100755 (executable)
@@ -13,6 +13,14 @@ echo "rm -f /etc/init.d/tizen-kvm" >> $TMP_FILE
 echo "rm -f /lib/udev/rules.d/45-tizen-kvm.rules" >> $TMP_FILE
 
 chmod +x $TMP_FILE
-gksudo ./$TMP_FILE
+
+GKSUDO=`which gksudo`
+if [ "$GKSUDO" = "" ]
+then
+       echo "there is no gksudo."
+       sudo ./$TMP_FILE
+else
+       gksudo ./$TMP_FILE
+fi
 
 rm $TMP_FILE
index f1f106e..26af735 100755 (executable)
@@ -13,6 +13,14 @@ echo "rm -f /etc/init.d/tizen-kvm" >> $TMP_FILE
 echo "rm -f /lib/udev/rules.d/45-tizen-kvm.rules" >> $TMP_FILE
 
 chmod +x $TMP_FILE
-gksudo ./$TMP_FILE
+
+GKSUDO=`which gksudo`
+if [ "$GKSUDO" = "" ]
+then
+       echo "there is no gksudo."
+       sudo ./$TMP_FILE
+else
+       gksudo ./$TMP_FILE
+fi
 
 rm $TMP_FILE
similarity index 81%
rename from package/emulator-qemu-common.install.ubuntu-32
rename to package/emulator-qemu-x86.install.ubuntu-32
index ba1c51f..e2b4592 100755 (executable)
@@ -14,6 +14,14 @@ echo "/etc/init.d/tizen-kvm start" >> $TMP_FILE
 echo "update-rc.d tizen-kvm defaults" >> $TMP_FILE
 
 chmod +x $TMP_FILE
-gksudo ./$TMP_FILE
+
+GKSUDO=`which gksudo`
+if [ "$GKSUDO" = "" ]
+then
+       echo "there is no gksudo."
+       sudo ./$TMP_FILE
+else
+       gksudo ./$TMP_FILE
+fi
 
 rm $TMP_FILE
similarity index 81%
rename from package/emulator-qemu-common.install.ubuntu-64
rename to package/emulator-qemu-x86.install.ubuntu-64
index ba1c51f..e2b4592 100755 (executable)
@@ -14,6 +14,14 @@ echo "/etc/init.d/tizen-kvm start" >> $TMP_FILE
 echo "update-rc.d tizen-kvm defaults" >> $TMP_FILE
 
 chmod +x $TMP_FILE
-gksudo ./$TMP_FILE
+
+GKSUDO=`which gksudo`
+if [ "$GKSUDO" = "" ]
+then
+       echo "there is no gksudo."
+       sudo ./$TMP_FILE
+else
+       gksudo ./$TMP_FILE
+fi
 
 rm $TMP_FILE
index ec022f6..b0d85f6 100644 (file)
@@ -1,4 +1,4 @@
-Version: 2.0.0
+Version: 1.5.22
 Maintainer: Yeong-Kyoon Lee<yeongkyoon.lee@samsung.com>
 Source: emulator
 
diff --git a/tizen/distrib/initscript/tizen_kvm b/tizen/distrib/initscript/tizen_kvm
new file mode 100755 (executable)
index 0000000..263a687
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/sh
+do_start () {
+       if grep -qs "^flags.* vmx" /proc/cpuinfo; then
+               modprobe -b kvm_intel "$KVM_NESTED"
+       elif grep -qs "^flags.* svm" /proc/cpuinfo; then
+               modprobe -b kvm_amd
+       fi
+}
+
+case "$1" in
+  start)
+       do_start
+       ;;
+  restart|reload|force-reload)
+       # No-op
+       ;;
+  stop)
+       # No-op
+       ;;
+  *)
+       echo "Usage: $0 start|stop" >&2
+       exit 3
+       ;;
+esac
index 734c1ef..7eda9e8 100755 (executable)
@@ -37,6 +37,7 @@ endif
 ifdef CONFIG_DARWIN
        $(CC) -mmacosx-version-min=10.4 -o check-hax check_hax.c        
 endif
+
 skin_client:
        ant -buildfile skin/client/build.xml make-jar
 
@@ -118,13 +119,16 @@ endif
        
        cp skin/client/emulator-skin.jar $(EMUL_DIR)/bin
 ifdef CONFIG_WIN32
+       cp ../../i386-softmmu/check-gl.exe $(EMUL_DIR)/bin
        cp check-hax.exe $(EMUL_DIR)/bin
 endif
 ifdef CONFIG_DARWIN
+       cp ../../i386-softmmu/check-gl $(EMUL_DIR)/bin
        cp check-hax $(EMUL_DIR)/bin
        cp sdbscript $(EMUL_DIR)/bin
 endif
 ifdef CONFIG_LINUX
+       cp ../../i386-softmmu/check-gl $(EMUL_DIR)/bin
        cp -pPr ../distrib/initscript/tizen-kvm $(EMUL_DIR)/etc
        cp -pPr ../distrib/initscript/45-tizen-kvm.rules $(EMUL_DIR)/etc
 endif
@@ -143,12 +147,15 @@ else
 endif
 
 ifdef CONFIG_DARWIN
-       install_name_tool -change /opt/local/lib/libgthread-2.0.*.dylib @loader_path/libgthread-2.0.0.dylib $(EMUL_DIR)/bin/qemu-img 
+       install_name_tool -change /opt/local/lib/libgthread-2.0.*.dylib @loader_path/libgthread-2.0.0.dylib $(EMUL_DIR)/bin/qemu-img
        install_name_tool -change /opt/local/lib/libglib-2.0.*.dylib @loader_path/libglib-2.0.0.dylib $(EMUL_DIR)/bin/qemu-img
        install_name_tool -change /opt/local/lib/libintl.8.dylib @loader_path/libintl.8.dylib $(EMUL_DIR)/bin/qemu-img
        install_name_tool -change /opt/local/lib/gcc47/libgcc_s.1.dylib @loader_path/libgcc_s.1.dylib $(EMUL_DIR)/bin/qemu-img
        install_name_tool -change /opt/local/lib/libz.1.dylib @loader_path/libz.1.dylib $(EMUL_DIR)/bin/qemu-img
        install_name_tool -change /opt/local/lib/libcurl.4.dylib @loader_path/libcurl.4.dylib $(EMUL_DIR)/bin/qemu-img
+       install_name_tool -change /opt/local/lib/libglib-2.0.*.dylib @loader_path/libglib-2.0.0.dylib $(EMUL_DIR)/bin/check-gl
+       install_name_tool -change /opt/local/lib/libintl.8.dylib @loader_path/libintl.8.dylib $(EMUL_DIR)/bin/check-gl
+       install_name_tool -change /opt/local/lib/gcc47/libgcc_s.1.dylib @loader_path/libgcc_s.1.dylib $(EMUL_DIR)/bin/check-gl
 
        @for target in $(TARGET_DIRS); do \
        case "$$target" in \
@@ -178,6 +185,7 @@ install_dibs: all_dibs
        mkdir -p $(DIBS_COMMON_DIR)/etc
        mkdir -p $(DIBS_X86_DIR)/bin
        mkdir -p $(DIBS_X86_DIR)/data
+       mkdir -p $(DIBS_X86_DIR)/etc
        mkdir -p $(DIBS_ARM_DIR)/bin
 ifndef CONFIG_DARWIN
        @for target in $(TARGET_DIRS); do \
@@ -227,17 +235,20 @@ endif
 
        cp skin/client/emulator-skin.jar $(DIBS_COMMON_DIR)/bin
 ifdef CONFIG_WIN32
+       cp ../../i386-softmmu/check-gl.exe $(DIBS_COMMON_DIR)/bin
        cp check-hax.exe $(DIBS_COMMON_DIR)/bin
 endif
 
 ifdef CONFIG_DARWIN
+       cp ../../i386-softmmu/check-gl $(DIBS_COMMON_DIR)/bin
        cp check-hax $(DIBS_COMMON_DIR)/bin
        cp sdbscript $(DIBS_COMMON_DIR)/bin
 endif
 ifdef CONFIG_LINUX
-       echo "Copying tizen-kvm to $(DIBS_COMMON_DIR)/etc"
-       cp -pPr ../distrib/initscript/tizen-kvm $(DIBS_COMMON_DIR)/etc
-       cp -pPr ../distrib/initscript/45-tizen-kvm.rules $(DIBS_COMMON_DIR)/etc
+       cp ../../i386-softmmu/check-gl $(DIBS_COMMON_DIR)/bin
+       echo "Copying tizen-kvm to $(DIBS_X86_DIR)/etc"
+       cp -pPr ../distrib/initscript/tizen-kvm $(DIBS_X86_DIR)/etc
+       cp -pPr ../distrib/initscript/45-tizen-kvm.rules $(DIBS_X86_DIR)/etc
 endif
 
 ifndef CONFIG_DARWIN
@@ -258,6 +269,9 @@ ifdef CONFIG_DARWIN
        install_name_tool -change /opt/local/lib/gcc47/libgcc_s.1.dylib @loader_path/libgcc_s.1.dylib $(DIBS_COMMON_DIR)/bin/qemu-img
        install_name_tool -change /opt/local/lib/libz.1.dylib @loader_path/libz.1.dylib $(DIBS_COMMON_DIR)/bin/qemu-img
        install_name_tool -change /opt/local/lib/libcurl.4.dylib @loader_path/libcurl.4.dylib $(DIBS_COMMON_DIR)/bin/qemu-img
+       install_name_tool -change /opt/local/lib/libglib-2.0.*.dylib @loader_path/libglib-2.0.0.dylib $(DIBS_COMMON_DIR)/bin/check-gl
+       install_name_tool -change /opt/local/lib/libintl.8.dylib @loader_path/libintl.8.dylib $(DIBS_COMMON_DIR)/bin/check-gl
+       install_name_tool -change /opt/local/lib/gcc47/libgcc_s.1.dylib @loader_path/libgcc_s.1.dylib $(DIBS_COMMON_DIR)/bin/check-gl
 
        @for target in $(TARGET_DIRS); do \
        case "$$target" in \
index 8f3ed26..e374992 100755 (executable)
@@ -87,7 +87,19 @@ endif #CONFIG_OPENGLES
 #endif #!CONFIG_DARWIN
 
 # maru loader
-obj-y += emulator.o emul_state.o option.o maru_err_table.o
+obj-y += emulator.o emul_state.o maru_err_table.o
+
+# osutil
+obj-y += osutil.o
+ifdef CONFIG_LINUX
+obj-y += osutil-linux.o
+endif
+ifdef CONFIG_WIN32
+obj-y += osutil-win32.o
+endif
+ifdef CONFIG_DARWIN
+obj-y += osutil-darwin.o
+endif
 
 # maru display
 obj-y += maru_display.o maru_shm.o
@@ -117,6 +129,7 @@ obj-y += maru_usb_touchscreen.o maru_virtio_touchscreen.o
 obj-y += maru_virtio_keyboard.o
 obj-y += maru_codec.o
 obj-y += maru_virtio_esm.o
+obj-y += maru_virtio_hwkey.o
 
 obj-$(CONFIG_PCI) += maru_camera_common_pci.o
 obj-$(CONFIG_LINUX) += maru_camera_linux_pci.o
diff --git a/tizen/src/SDL_gfx/AUTHORS b/tizen/src/SDL_gfx/AUTHORS
new file mode 100644 (file)
index 0000000..9ea070b
--- /dev/null
@@ -0,0 +1 @@
+Andreas Schiffler <aschiffler@ferzkopp.net>
diff --git a/tizen/src/SDL_gfx/COPYING b/tizen/src/SDL_gfx/COPYING
new file mode 100644 (file)
index 0000000..04bd5d6
--- /dev/null
@@ -0,0 +1 @@
+(C) A. Schiffler, ZLIB - see file LICENSE
diff --git a/tizen/src/SDL_gfx/LICENSE b/tizen/src/SDL_gfx/LICENSE
new file mode 100644 (file)
index 0000000..f1eb9d8
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+
+Copyright (C) 2001-2011  Andreas Schiffler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+   1. The origin of this software must not be misrepresented; you must not
+   claim that you wrote the original software. If you use this software
+   in a product, an acknowledgment in the product documentation would be
+   appreciated but is not required.
+
+   2. Altered source versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+   3. This notice may not be removed or altered from any source
+   distribution.
+
+Andreas Schiffler -- aschiffler at ferzkopp dot net
+
+*/
\ No newline at end of file
diff --git a/tizen/src/SDL_gfx/README b/tizen/src/SDL_gfx/README
new file mode 100644 (file)
index 0000000..cc8409d
--- /dev/null
@@ -0,0 +1,500 @@
+/*!\r
+\r
+\r
+\mainpage SDL_gfx - SDL-1.2 graphics drawing primitives, rotozoom and other supporting functions\r
+\r
+\r
+\section contact_sec Contact and License\r
+\r
+Email aschiffler at ferzkopp dot net to contact the author or better check\r
+author's homepage at http://www.ferzkopp.net for the most up-to-date\r
+contact information.\r
+\r
+This library is licenced under the zlib License, see the file LICENSE for details. \r
+\r
+\r
+\section intro_sec Introduction\r
+\r
+The SDL_gfx library evolved out of the SDL_gfxPrimitives code which\r
+provided basic drawing routines such as lines, circles or polygons for \r
+SDL Surfaces and adding a couple other useful functions for zooming \r
+images for example and doing basic image processing on byte arrays.\r
+\r
+Note that SDL_gfx is compatible with SDL version 1.2 (not SDL2).\r
+\r
+The current components of the SDL_gfx library are:\r
+- Graphic Primitives (SDL_gfxPrimitives.h, SDL_gfxPrimitives.c)\r
+- Rotozoomer (SDL_rotozoom.h, SDL_rotozoom.c)\r
+- Framerate control (SDL_framerate.h, SDL_framerate.c)\r
+- MMX image filters (SDL_imageFilter.h, SDL_imageFilter.c)\r
+- Custom Blit functions (SDL_gfxBlitFunc.h, SDL_gfxBlitFunc.c)\r
+- Build-in 8x8 Font (SDL_gfxPrimitives_font.h)\r
+\r
+\r
+\r
+\subsection notes_gfx Notes on Graphics Primitives\r
+\r
+Care has been taken so that all routines are fully alpha-aware and can \r
+blend any primitive onto the target surface if ALPHA<255. Surface depths \r
+supported are 1,2,3 and 4 bytes per pixel. Surface locking is implemented\r
+in each routine and the library should work well with hardware \r
+accelerated surfaces. \r
+\r
+\htmlonly\r
+<a href="../Screenshots/SDL_gfxPrimitives.jpg" target="_blank" title="SDL_gfxPrimitives Screenshot"><img src="../Screenshots/SDL_gfxPrimitives-thumb.jpg" border="0" hspace="5"></a><br />\r
+\endhtmlonly\r
+\r
+Currently, The following Anti-Aliased drawing primitives are available:\r
+- AA-line\r
+- AA-polygon\r
+- AA-circle\r
+- AA-ellipse\r
+\r
+Note: All ___Color routines expect the color to be in the format 0xRRGGBBAA.\r
+\r
+\subsection notes_roto Notes on Rotozoomer\r
+\r
+The rotozoom code is not ASM-speed quality, but it should be fast enough \r
+even for some realtime effects if the CPU is good or bitmaps small.\r
+With interpolation the routines are typically used for pre-rendering stuff \r
+in higher quality (i.e. smoothing) - that's also the reason why the API differs \r
+from SDL_BlitRect() - as they create a new target surface each time rotozoom \r
+is called. The final rendering speed is dependent on the target surface\r
+size as it is beeing xy-scanned when rendering the new surface.\r
+\r
+\htmlonly\r
+<a href="../Screenshots/SDL_rotozoom.jpg" target="_blank" title="SDL_rotozoom Screenshot"><img src="../Screenshots/SDL_rotozoom-thumb.jpg" border="0" hspace="5"></a><br />\r
+\endhtmlonly\r
+\r
+Note also that the smoothing toggle is dependent on the input surface bit \r
+depth. 8bit surfaces will \b never be smoothed - only 32bit surfaces will.\r
+\r
+Note that surfaces of other bit depth then 8 and 32 will be converted \r
+on the fly to a 32bit surface using a blit into a temporary surface. This \r
+impacts performance somewhat.\r
+\r
+Smoothing (interpolation) flags work only on 32bit surfaces:\r
+\verbatim\r
+ #define SMOOTHING_OFF         0\r
+ #define SMOOTHING_ON          1\r
+\endverbatim\r
\r
+\subsection notes_rate Notes on Framerate Manager\r
+\r
+The framerate functions are used to insert delays into the graphics loop\r
+to maintain a constant framerate.\r
+\r
+The implementation is more sophisticated that the usual\r
+\verbatim\r
+       SDL_Delay(1000/FPS); \r
+\endverbatim\r
+call since these functions keep track of the desired game time per frame \r
+for a linearly interpolated sequence of future timing points of each frame. \r
+This is done to avoid rounding errors from the inherent instability in the \r
+delay generation and application.\r
+\r
+\htmlonly\r
+<a href="../framerate.png" target="_blank" title="Framerate Diagram"><img src="../framerate-thumb.png" border="0"></a><br />\r
+\endhtmlonly\r
+\r
+i.e. the 100th frame of a game running at 50Hz will be accurately\r
+2.00sec after the 1st frame (if the machine can keep up with the drawing).\r
+\r
+The functions return 0 or 'value' for sucess and -1 for error. All functions\r
+use a pointer to a framerate-manager variable to operate.\r
+\r
+\r
+\subsection notes_filter Notes on ImageFilters\r
+\r
+The imagefilter functions are a collection of MMX optimized routines that\r
+operate on continuous buffers of bytes - typically greyscale images from \r
+framegrabbers and such - performing functions such as image addition and \r
+binarization. All functions (almost ... not the the convolution routines) \r
+have a C implementation that is automatically used on systems without MMX \r
+capabilities.\r
+\r
+The compiler flag -DUSE_MMX toggles the conditional compile of MMX assembly.\r
+An assembler must be installed (i.e. "nasm").\r
+\r
+\r
+\subsection notes_blitters Notes on Custom Blitters\r
+\r
+The custom blitter functions provide (limited) support for surface\r
+compositing - that is surfaces can be blitted together, and then\r
+still blitted to the screen with transparency intact.\r
+\r
+\subsection platforms Supported Platforms\r
+\r
+\subsubsection platformlinux Unix/Linux\r
+\r
+The library compiles and is tested for a Linux target (gcc compiler) via the\r
+the usual configure;make;make install sequence.\r
+\r
+\subsubsection platformwindows Windows\r
\r
+A Win32 target is available (VisualC6/7/8/9, mingw32, xmingw32 cross-compiler).\r
+The SDL_gfx.sln will open VS2010 (the old VS2008 .sln is also still included) \r
+including express versions. \r
+\r
+See "Other Builds" for additional makefiles (may be out of date).\r
+\r
+When using the cross-compiler (available on the author's homepage, very\r
+out of date), the build process generates .DLLs. You can use the command \r
+line 'LIB.EXE' tool to generate VC6 compatible .LIB files for linking \r
+purposes. \r
+\r
+\subsubsection platformosx Mac OSX \r
+\r
+The usual autotools build chain should be used. MacPorts or fink may \r
+be required (that's what the author uses).\r
+\r
+Xcode is supported via templates. See "Other Builds" folder Xcode3+.zip -\r
+this template only supports SDL_gfx and not the tests. For this template, the\r
+Deployment Target (the lowest version to run on) is set to 10.5 and expects\r
+the SDL.framework preinstalled in some default location\r
+(either /Library/Frameworks, or ~/Library/Frameworks). \r
+\r
+Older targets are also reported to work (10.3+ native and Project Builder). \r
+\r
+\subsubsection platformqnx QNX\r
+\r
+QNX was reported to build (see .diff in "Other Builds").\r
+\r
+\subsubsection platformzune Zune\r
+\r
+ZuneHD (WinCE 6 ARM) is reported to build (see OpenZDK in "Other Builds").\r
+Note that between rendering on the Zune's ARM CPU and constantly uploading\r
+textures to the GPU, SDL_gfx is going to be slow. Also, the libc math \r
+functions all use software FP emulation even when VFP floating point\r
+support is turned on in the compiler, so there's extra overhead due to that\r
+as well.\r
+\r
+\subsubsection platformothers Others\r
+\r
+Other platforms might work but have not been tested by the author.\r
+Please check the file "INSTALL" as well as the folder "Other Builds".\r
+\r
+See also section "Installation" below for more build instructions.\r
+\r
+\section install_sec Installation\r
+\r
+\subsection unix Unix/Linux\r
+\r
+To compile the library your need the SDL 1.2 installed from source or \r
+installed with the 'devel' RPM package. For example on Mandriva, run:\r
+\verbatim\r
+       urpmi  libSDL1.2-devel\r
+\endverbatim\r
+\r
+Then run\r
+\verbatim\r
+       ./autogen.sh    # (optional, recommended)\r
+       ./configure\r
+       make\r
+       make install\r
+       ldconfig\r
+\endverbatim\r
+\r
+to compile and install the library. The default location for the \r
+installation is /usr/local/lib and /usr/local/include. The libary \r
+path might need to be added to the file:\r
+       /etc/ld.so.conf\r
+\r
+Run the shell script 'nodebug.sh' before make, to patch the makefile \r
+for optimized compilation:\r
+\verbatim\r
+       ./autogen.sh    # (optional, recommended)\r
+       ./configure\r
+       ./nodebug.sh\r
+       make\r
+       make install\r
+       ldconfig\r
+\endverbatim\r
+\r
+Check the folder "Other Builds" for alternative makefiles.\r
+\r
+\subsection prep Build Prep\r
+\r
+Run autogen.sh or manually:\r
+\verbatim\r
+       aclocal --force\r
+       libtoolize --force --copy\r
+       autoreconf -fvi\r
+\endverbatim\r
+\r
+\subsection nommx No-MMX\r
+\r
+To build without MMX code enabled (i.e. PPC or for AMD64 architecture\r
+which is missing pusha/popa):\r
+\verbatim\r
+       ./configure --disable-mmx\r
+       make\r
+       make install\r
+\endverbatim\r
+i.e. to build on MacOSX 10.3+ use:\r
+\verbatim\r
+       ./configure --disable-mmx && make\r
+\endverbatim\r
+\r
+\subsection vs9 Windows (VC9, VS2010)\r
+\r
+Open SDL_gfx.sln solution file and review README.\r
+\r
+\subsection vs8 Windows (VC8, VS2008)\r
+\r
+Open SDL_gfx_VS2008.sln solution file and review README.\r
+\r
+\r
+\subsection vc6 Windows (VC6/7)\r
+\r
+See folder Other Builds.\r
+\r
+To create a Windows DLL using VisualC6:\r
+\verbatim\r
+       unzip -a VisualC6.zip\r
+       vcvars32.bat\r
+       copy VisualC/makefile\r
+       nmake\r
+\endverbatim\r
+or\r
+\verbatim\r
+       unzip -a VisualC7.zip\r
+\endverbatim\r
+and open the project file.\r
+\r
+\r
+\subsection wince WindowsCE\r
+\r
+See folder Other Builds.\r
+\r
+May need workaround for missing lrint.\r
+\r
+\r
+\subsection cross Cross-Compilation\r
+\r
+To build using mingw32 on Win32, check the makefile contained in mingw.zip\r
+\r
+To create a Windows DLL using the xmingw32 cross-compiler:\r
+\verbatim\r
+       cross-configure\r
+       cross-make\r
+       cross-make install\r
+\endverbatim\r
+\r
+Make sure the -DBUILD_DLL is used (and only then) when creating the DLLs.\r
+Make sure -DWIN32 is used when compiling the sources (creating or using\r
+the DLLs.\r
+\r
+Specify the path to your cross-compiled 'sdl-config', and invoke\r
+'./configure' with the '--host' and '--build' arguments. For example,\r
+to cross-compile a .DLL from GNU/Linux:\r
+\verbatim\r
+       SDL_CONFIG=/usr/local/cross-tools/i386-mingw32msvc/bin/sdl-config \\r
+               ./configure --host=i586-mingw32msvc --build=i686-pc-linux-gnu\r
+       make\r
+       make install\r
+\endverbatim\r
+\r
+\subsection qnx QNX\r
+\r
+To build on QNX6, patch first using:\r
+\verbatim\r
+       patch -p0 <QNX.diff\r
+\endverbatim\r
+\r
+\subsection osx OSX\r
+\r
+Use standard unix build sequence.\r
+\r
+To build on MacOS X with Project Builder, follow these steps:\r
+- Update your developer tools to the lastest version.\r
+- Install the SDL Developers framework for Mac OS X.\r
+- Download the latest SDL_gfx source distribution and extract the\r
+       archive in a convenient location.\r
+- Extract the included OSX-PB.tgz archive into the\r
+       top directory of the SDL_gfx distribution (from step 3). This will create a\r
+       PB that contains the project files.\r
+- The project has targets for the SDL_gfx framework and the four test\r
+       programs. All can be built using the 'deployment' or 'development' build\r
+       styles. \r
+\r
+A newer version for MaxOS X is included in the OSX-PB-XCode.zip archive. The \r
+updated version uses relative pathnames where appropriate, and pointers to \r
+the standard  installation location of SDL. However, it may require XCode in \r
+order to be used.\r
+\r
+\section interfaces_sec Language Interfaces\r
+\r
+SDL_gfx has been integrated with the following language interfaces:\r
+- Pascal: http://www.freepascal-meets-sdl.net\r
+- Perl: http://sdl.perl.org\r
+- Python: http://www.pygame.org\r
+- C#: http://cs-sdl.sourceforge.net\r
+- Lua: http://www.egsl.retrogamecoding.org/\r
+- Oberon: http://sourceforge.net/projects/sdl-for-oberon/\r
+\r
+\section test_sec Test Programs\r
+\r
+Change to the ./Test directory and run\r
+\verbatim\r
+       ./autogen.sh\r
+       ./configure\r
+       make\r
+\endverbatim\r
+to create several test programs for the libraries functions. This requires\r
+the library to be previously compiled and installed.\r
+\r
+\r
+See the source code .c files for some sample code and implementation hints.\r
+\r
+\r
+\section contrib_sec Contributors\r
+\r
+- Fix for filledbox by Ingo van Lil, inguin at gmx.de - thanks Ingo.\r
+\r
+- Non-alpha line drawing code adapted from routine \r
+  by Pete Shinners, pete at shinners.org - thanks Pete.\r
+\r
+- More fixes by Karl Bartel, karlb at gmx.net - thanks Karl.\r
+\r
+- Much testing and suggestions for fixes from Danny van Bruggen,\r
+  danny at froukepc.dhs.org - thanks Danny.\r
+\r
+- Original AA-circle/-ellipse code idea from Stephane Magnenat, \r
+  nct at wg0.ysagoon.com - thanks Stephane.\r
+\r
+- Faster blending routines contributed by Anders Lindstroem,\r
+  cal at swipnet.se - thanks Anders.\r
+\r
+- New AA-circle/-ellipse code based on ideas from Anders Lindstroem - \r
+  thanks Anders.\r
+\r
+- VisualC makefile contributed by Danny van Bruggen, \r
+  danny at froukepc.dhs.org - thanks Danny.\r
+\r
+- VisualC7 project file contributed by James Turk, \r
+  jturk at conceptofzero.com - thanks James.\r
+\r
+- Project Builder package contributed by Thomas Tongue, \r
+  TTongue at imagiware.com - Thanks Thomas.\r
+\r
+- Fix for filledPolygon contributed by Kentaro Fukuchi \r
+  fukuchi at is.titech.ac.jp - Thanks Kentaro.\r
+\r
+- QNX6 patch contributed by Mike Gorchak,\r
+  mike at malva.ua - Thanks Mike.\r
+\r
+- Pie idea contributed by Eike Lange,\r
+  eike.lange at uni-essen.de - Thanks Eike.\r
+\r
+- Dynamic font setup by Todor Prokopov,\r
+  koprok at dir.bg - Thanks Todor.\r
+\r
+- Horizontal/Vertical flipping code by Victor (Haypo) \r
+  Stinner, victor.stinner at haypocalc.com - Thanks Victor.\r
+\r
+- OSX build fixes by Michael Wybrow, \r
+  mjwybrow at cs.mu.oz.au - Thanks Michael.\r
+\r
+- gcc3.4 build fixes by Dries Verachtert, \r
+  dries at ulyssis.org - Thanks Dries.\r
+\r
+- Updated OSX build by Brian Rice,\r
+  water451 at gmail.com - Thanks Brian.\r
+\r
+- aaellipse issues pointed out by Marco Wertz,\r
+  marco.wertz at gmx.de - Thanks Marco.\r
+\r
+- texturedPolygon idea and code by Kees Jongenburger,\r
+  kees.jongenburger at gmail.com - Thanks Kees.\r
\r
+- Several bugfixes contributed by Sigborn Skjaeret, \r
+  cisc at broadpark.no - Thanks CISC.\r
+\r
+- Syntax error for C++ found by Olivier Boudeville,\r
+  olivier.boudeville at online.fr - Thanks Olivier.\r
+\r
+- hline/vline clipping fixes found by Daniel Roggen,\r
+  droggen at gmail.com and Mikael Thieme, \r
+  mikael.thieme at his.se - Thanks Daniel+Mikael.\r
+\r
+- rotozoom fix for big-endian machines (i.e. PPC)\r
+  by Julian Mayer, julianmayer at mac.com - Thanks\r
+  Julian.\r
+\r
+- Cross-compilation notes contributed by Sylvain\r
+  Beucler, beuc at beuc.net - Thanks Sylvain.\r
+\r
+- Fix duplicate pixel renders in circleColor contributed\r
+  by David Raber, lotharstar at gmail.com - Thanks David.\r
+\r
+- New arcColor (and arcRGBA) routine contributed\r
+  by David Raber, lotharstar at gmail.com - Thanks David.\r
+\r
+- Idea for polygonColorMT and texturePolygonMT routines for\r
+  multithreaded operation contributed by "unknown" -\r
+  Thank you.\r
+\r
+- Multiple patches applied and repackaged version 2.0.18\r
+  by Paul, sweetlilmre at gmail.com - Thanks Paul and\r
+  other contributors of patches.\r
+\r
+- Change to avoid gcc4 compiler warnings contributed by Thien-Thi\r
+  nguyen, ttn at gnuvola.org - thanks Thi. \r
+\r
+- hline 1bpp off-by-one patch contributed by Manuel Lausch\r
+  mail at manuellausch.de - Thanks Manuel.\r
+\r
+- pkg-config support contributed by Luca Bigliardi, shammash\r
+  at artha.org - thanks Luca.\r
+\r
+- Updated mingw Makefile contributed by Jan Leike, jan dot leike \r
+  at gmx dot net - thanks Jan.\r
+\r
+- Rotozoom debugging help by Jeff Wilges, heff at ifup dot us -\r
+  thanks Jeff.\r
+\r
+- Build updates provided by Barry deFreese, bdefreese at debian \r
+  dot org - thanks Barry.\r
+\r
+- Fix for 1-pixel postponement with 8bit scaling by Sylvain Beucler, \r
+  beuc at beuc dot net - thanks Sylvain.\r
+\r
+- Updates to headers and configure to allow for cross-compiling \r
+  to DLL (not just static .a) and fixes for compiling on Windows \r
+  using autotools by Sylvain Beucler, beuc at beuc dot net - thanks Sylvain.\r
+\r
+- Added Visual CE Project to Builds. Contributed by vrichomme at smartmobili\r
+  dot com - thanks.\r
+\r
+- Added Symbian and Windows 64bit fix with lrint function by Rene \r
+  Dudfield, renesd at gmail dot com - thanks Rene.\r
+\r
+- Fixes for Rotate90 0-degree case by Chris Allport, chris dot allport\r
+  at gmail dot com - thanks Chris.\r
+\r
+- Fixed for Win32 build support defines by tigerfishdaisy (SF) - thanks\r
+  Tiger Tiger.\r
+\r
+- Patch for OpenSDK contributed by itsnotabigtruck at ovi dot com - thanks\r
+  IsNotABigTruck.\r
+\r
+- OSX Xcode 3+ template ZIP contributed by marabus at meta dot ua - thanks\r
+  Vasyl.\r
+\r
+- Memory leak/error check patch for zoomSurface contributed by \r
+  RodolfoRG - thanks Rodolfo.\r
+\r
+- Zoom scaling factor rounding bugfix patch contributed by WanderWander\r
+  Lairson Costa - thanks Wander.\r
+\r
+- Suggestions for speed improvements contributed by inkyankes - thanks.\r
+\r
+- Pixel blend routine patches contributed by mitja at lxnav dot com -\r
+  thanks Mitja.\r
+\r
+\section changelog_sec Change Log\r
+\r
+\verbinclude ChangeLog\r
+\r
+*/
\ No newline at end of file
diff --git a/tizen/src/SDL_gfx/SDL_rotozoom.c b/tizen/src/SDL_gfx/SDL_rotozoom.c
new file mode 100644 (file)
index 0000000..3831236
--- /dev/null
@@ -0,0 +1,1717 @@
+/*  
+
+SDL_rotozoom.c: rotozoomer, zoomer and shrinker for 32bit or 8bit surfaces
+
+Copyright (C) 2001-2012  Andreas Schiffler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+claim that you wrote the original software. If you use this software
+in a product, an acknowledgment in the product documentation would be
+appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and must not be
+misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+
+Andreas Schiffler -- aschiffler at ferzkopp dot net
+
+*/
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "SDL_rotozoom.h"
+
+/* ---- Internally used structures */
+
+/*!
+\brief A 32 bit RGBA pixel.
+*/
+typedef struct tColorRGBA {
+       Uint8 r;
+       Uint8 g;
+       Uint8 b;
+       Uint8 a;
+} tColorRGBA;
+
+/*!
+\brief A 8bit Y/palette pixel.
+*/
+typedef struct tColorY {
+       Uint8 y;
+} tColorY;
+
+/*! 
+\brief Returns maximum of two numbers a and b.
+*/
+#define MAX(a,b)    (((a) > (b)) ? (a) : (b))
+
+/*! 
+\brief Number of guard rows added to destination surfaces.
+
+This is a simple but effective workaround for observed issues.
+These rows allocate extra memory and are then hidden from the surface.
+Rows are added to the end of destination surfaces when they are allocated. 
+This catches any potential overflows which seem to happen with 
+just the right src image dimensions and scale/rotation and can lead
+to a situation where the program can segfault.
+*/
+#define GUARD_ROWS (2)
+
+/*!
+\brief Lower limit of absolute zoom factor or rotation degrees.
+*/
+#define VALUE_LIMIT    0.001
+
+/*!
+\brief Returns colorkey info for a surface
+*/
+static Uint32 _colorkey(SDL_Surface *src)
+{
+       Uint32 key = 0; 
+#if (SDL_MINOR_VERSION == 3)
+       SDL_GetColorKey(src, &key);
+#else
+       if (src) 
+       {
+               key = src->format->colorkey;
+       }
+#endif
+       return key;
+}
+
+
+/*! 
+\brief Internal 32 bit integer-factor averaging Shrinker.
+
+Shrinks 32 bit RGBA/ABGR 'src' surface to 'dst' surface.
+Averages color and alpha values values of src pixels to calculate dst pixels.
+Assumes src and dst surfaces are of 32 bit depth.
+Assumes dst surface was allocated with the correct dimensions.
+
+\param src The surface to shrink (input).
+\param dst The shrunken surface (output).
+\param factorx The horizontal shrinking ratio.
+\param factory The vertical shrinking ratio.
+
+\return 0 for success or -1 for error.
+*/
+static int _shrinkSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory)
+{
+       int x, y, dx, dy, sgap, dgap, ra, ga, ba, aa;
+       int n_average;
+       tColorRGBA *sp, *osp, *oosp;
+       tColorRGBA *dp;
+
+       /*
+       * Averaging integer shrink
+       */
+
+       /* Precalculate division factor */
+       n_average = factorx*factory;
+
+       /*
+       * Scan destination
+       */
+       sp = (tColorRGBA *) src->pixels;
+       sgap = src->pitch - src->w * 4;
+
+       dp = (tColorRGBA *) dst->pixels;
+       dgap = dst->pitch - dst->w * 4;
+
+       for (y = 0; y < dst->h; y++) {
+
+               osp=sp;
+               for (x = 0; x < dst->w; x++) {
+
+                       /* Trace out source box and accumulate */
+                       oosp=sp;
+                       ra=ga=ba=aa=0;
+                       for (dy=0; dy < factory; dy++) {
+                               for (dx=0; dx < factorx; dx++) {
+                                       ra += sp->r;
+                                       ga += sp->g;
+                                       ba += sp->b;
+                                       aa += sp->a;
+
+                                       sp++;
+                               } 
+                               /* src dx loop */
+                               sp = (tColorRGBA *)((Uint8*)sp + (src->pitch - 4*factorx)); // next y
+                       }
+                       /* src dy loop */
+
+                       /* next box-x */
+                       sp = (tColorRGBA *)((Uint8*)oosp + 4*factorx);
+
+                       /* Store result in destination */
+                       dp->r = ra/n_average;
+                       dp->g = ga/n_average;
+                       dp->b = ba/n_average;
+                       dp->a = aa/n_average;
+
+                       /*
+                       * Advance destination pointer 
+                       */
+                       dp++;
+               } 
+               /* dst x loop */
+
+               /* next box-y */
+               sp = (tColorRGBA *)((Uint8*)osp + src->pitch*factory);
+
+               /*
+               * Advance destination pointers 
+               */
+               dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
+       } 
+       /* dst y loop */
+
+       return (0);
+}
+
+/*! 
+\brief Internal 8 bit integer-factor averaging shrinker.
+
+Shrinks 8bit Y 'src' surface to 'dst' surface.
+Averages color (brightness) values values of src pixels to calculate dst pixels.
+Assumes src and dst surfaces are of 8 bit depth.
+Assumes dst surface was allocated with the correct dimensions.
+
+\param src The surface to shrink (input).
+\param dst The shrunken surface (output).
+\param factorx The horizontal shrinking ratio.
+\param factory The vertical shrinking ratio.
+
+\return 0 for success or -1 for error.
+*/
+static int _shrinkSurfaceY(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory)
+{
+       int x, y, dx, dy, sgap, dgap, a;
+       int n_average;
+       Uint8 *sp, *osp, *oosp;
+       Uint8 *dp;
+
+       /*
+       * Averaging integer shrink
+       */
+
+       /* Precalculate division factor */
+       n_average = factorx*factory;
+
+       /*
+       * Scan destination
+       */
+       sp = (Uint8 *) src->pixels;
+       sgap = src->pitch - src->w;
+
+       dp = (Uint8 *) dst->pixels;
+       dgap = dst->pitch - dst->w;
+
+       for (y = 0; y < dst->h; y++) {    
+
+               osp=sp;
+               for (x = 0; x < dst->w; x++) {
+
+                       /* Trace out source box and accumulate */
+                       oosp=sp;
+                       a=0;
+                       for (dy=0; dy < factory; dy++) {
+                               for (dx=0; dx < factorx; dx++) {
+                                       a += (*sp);
+                                       /* next x */           
+                                       sp++;
+                               } 
+                               /* end src dx loop */         
+                               /* next y */
+                               sp = (Uint8 *)((Uint8*)sp + (src->pitch - factorx)); 
+                       } 
+                       /* end src dy loop */
+
+                       /* next box-x */
+                       sp = (Uint8 *)((Uint8*)oosp + factorx);
+
+                       /* Store result in destination */
+                       *dp = a/n_average;
+
+                       /*
+                       * Advance destination pointer 
+                       */
+                       dp++;
+               } 
+               /* end dst x loop */
+
+               /* next box-y */
+               sp = (Uint8 *)((Uint8*)osp + src->pitch*factory);
+
+               /*
+               * Advance destination pointers 
+               */
+               dp = (Uint8 *)((Uint8 *)dp + dgap);
+       } 
+       /* end dst y loop */
+
+       return (0);
+}
+
+/*! 
+\brief Internal 32 bit Zoomer with optional anti-aliasing by bilinear interpolation.
+
+Zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface.
+Assumes src and dst surfaces are of 32 bit depth.
+Assumes dst surface was allocated with the correct dimensions.
+
+\param src The surface to zoom (input).
+\param dst The zoomed surface (output).
+\param flipx Flag indicating if the image should be horizontally flipped.
+\param flipy Flag indicating if the image should be vertically flipped.
+\param smooth Antialiasing flag; set to SMOOTHING_ON to enable.
+
+\return 0 for success or -1 for error.
+*/
+static int _zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy, int smooth)
+{
+       int x, y, sx, sy, ssx, ssy, *sax, *say, *csax, *csay, *salast, csx, csy, ex, ey, cx, cy, sstep, sstepx, sstepy;
+       tColorRGBA *c00, *c01, *c10, *c11;
+       tColorRGBA *sp, *csp, *dp;
+       int spixelgap, spixelw, spixelh, dgap, t1, t2;
+
+       /*
+       * Allocate memory for row/column increments 
+       */
+       if ((sax = (int *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) {
+               return (-1);
+       }
+       if ((say = (int *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) {
+               free(sax);
+               return (-1);
+       }
+
+       /*
+       * Precalculate row increments 
+       */
+       spixelw = (src->w - 1);
+       spixelh = (src->h - 1);
+       if (smooth) {
+               sx = (int) (65536.0 * (float) spixelw / (float) (dst->w - 1));
+               sy = (int) (65536.0 * (float) spixelh / (float) (dst->h - 1));
+       } else {
+               sx = (int) (65536.0 * (float) (src->w) / (float) (dst->w));
+               sy = (int) (65536.0 * (float) (src->h) / (float) (dst->h));
+       }
+
+       /* Maximum scaled source size */
+       ssx = (src->w << 16) - 1;
+       ssy = (src->h << 16) - 1;
+
+       /* Precalculate horizontal row increments */
+       csx = 0;
+       csax = sax;
+       for (x = 0; x <= dst->w; x++) {
+               *csax = csx;
+               csax++;
+               csx += sx;
+
+               /* Guard from overflows */
+               if (csx > ssx) { 
+                       csx = ssx; 
+               }
+       }
+
+       /* Precalculate vertical row increments */
+       csy = 0;
+       csay = say;
+       for (y = 0; y <= dst->h; y++) {
+               *csay = csy;
+               csay++;
+               csy += sy;
+
+               /* Guard from overflows */
+               if (csy > ssy) {
+                       csy = ssy;
+               }
+       }
+
+       sp = (tColorRGBA *) src->pixels;
+       dp = (tColorRGBA *) dst->pixels;
+       dgap = dst->pitch - dst->w * 4;
+       spixelgap = src->pitch/4;
+
+       if (flipx) sp += spixelw;
+       if (flipy) sp += (spixelgap * spixelh);
+
+       /*
+       * Switch between interpolating and non-interpolating code 
+       */
+       if (smooth) {
+
+               /*
+               * Interpolating Zoom 
+               */
+               csay = say;
+               for (y = 0; y < dst->h; y++) {
+                       csp = sp;
+                       csax = sax;
+                       for (x = 0; x < dst->w; x++) {
+                               /*
+                               * Setup color source pointers 
+                               */
+                               ex = (*csax & 0xffff);
+                               ey = (*csay & 0xffff);
+                               cx = (*csax >> 16);
+                               cy = (*csay >> 16);
+                               sstepx = cx < spixelw;
+                               sstepy = cy < spixelh;
+                               c00 = sp;
+                               c01 = sp;
+                               c10 = sp;
+                               if (sstepy) {
+                                       if (flipy) {
+                                               c10 -= spixelgap;
+                                       } else {
+                                               c10 += spixelgap;
+                                       }
+                               }
+                               c11 = c10;
+                               if (sstepx) {
+                                       if (flipx) {
+                                               c01--;
+                                               c11--;
+                                       } else {
+                                               c01++;
+                                               c11++;
+                                       }
+                               }
+
+                               /*
+                               * Draw and interpolate colors 
+                               */
+                               t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff;
+                               t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff;
+                               dp->r = (((t2 - t1) * ey) >> 16) + t1;
+                               t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff;
+                               t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff;
+                               dp->g = (((t2 - t1) * ey) >> 16) + t1;
+                               t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff;
+                               t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff;
+                               dp->b = (((t2 - t1) * ey) >> 16) + t1;
+                               t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff;
+                               t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff;
+                               dp->a = (((t2 - t1) * ey) >> 16) + t1;                          
+                               /*
+                               * Advance source pointer x
+                               */
+                               salast = csax;
+                               csax++;                         
+                               sstep = (*csax >> 16) - (*salast >> 16);
+                               if (flipx) {
+                                       sp -= sstep;
+                               } else {
+                                       sp += sstep;
+                               }
+
+                               /*
+                               * Advance destination pointer x
+                               */
+                               dp++;
+                       }
+                       /*
+                       * Advance source pointer y
+                       */
+                       salast = csay;
+                       csay++;
+                       sstep = (*csay >> 16) - (*salast >> 16);
+                       sstep *= spixelgap;
+                       if (flipy) { 
+                               sp = csp - sstep;
+                       } else {
+                               sp = csp + sstep;
+                       }
+
+                       /*
+                       * Advance destination pointer y
+                       */
+                       dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
+               }
+       } else {
+               /*
+               * Non-Interpolating Zoom 
+               */              
+               csay = say;
+               for (y = 0; y < dst->h; y++) {
+                       csp = sp;
+                       csax = sax;
+                       for (x = 0; x < dst->w; x++) {
+                               /*
+                               * Draw 
+                               */
+                               *dp = *sp;
+
+                               /*
+                               * Advance source pointer x
+                               */
+                               salast = csax;
+                               csax++;                         
+                               sstep = (*csax >> 16) - (*salast >> 16);
+                               if (flipx) sstep = -sstep;
+                               sp += sstep;
+
+                               /*
+                               * Advance destination pointer x
+                               */
+                               dp++;
+                       }
+                       /*
+                       * Advance source pointer y
+                       */
+                       salast = csay;
+                       csay++;
+                       sstep = (*csay >> 16) - (*salast >> 16);
+                       sstep *= spixelgap;
+                       if (flipy) sstep = -sstep;                      
+                       sp = csp + sstep;
+
+                       /*
+                       * Advance destination pointer y
+                       */
+                       dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
+               }
+       }
+
+       /*
+       * Remove temp arrays 
+       */
+       free(sax);
+       free(say);
+
+       return (0);
+}
+
+/*! 
+
+\brief Internal 8 bit Zoomer without smoothing.
+
+Zooms 8bit palette/Y 'src' surface to 'dst' surface.
+Assumes src and dst surfaces are of 8 bit depth.
+Assumes dst surface was allocated with the correct dimensions.
+
+\param src The surface to zoom (input).
+\param dst The zoomed surface (output).
+\param flipx Flag indicating if the image should be horizontally flipped.
+\param flipy Flag indicating if the image should be vertically flipped.
+
+\return 0 for success or -1 for error.
+*/
+static int _zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy)
+{
+       int x, y;
+       Uint32 *sax, *say, *csax, *csay;
+       int csx, csy;
+       Uint8 *sp, *dp, *csp;
+       int dgap;
+
+       /*
+       * Allocate memory for row increments 
+       */
+       if ((sax = (Uint32 *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) {
+               return (-1);
+       }
+       if ((say = (Uint32 *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) {
+               free(sax);
+               return (-1);
+       }
+
+       /*
+       * Pointer setup 
+       */
+       sp = csp = (Uint8 *) src->pixels;
+       dp = (Uint8 *) dst->pixels;
+       dgap = dst->pitch - dst->w;
+
+       if (flipx) csp += (src->w-1);
+       if (flipy) csp  = ( (Uint8*)csp + src->pitch*(src->h-1) );
+
+       /*
+       * Precalculate row increments 
+       */
+       csx = 0;
+       csax = sax;
+       for (x = 0; x < dst->w; x++) {
+               csx += src->w;
+               *csax = 0;
+               while (csx >= dst->w) {
+                       csx -= dst->w;
+                       (*csax)++;
+               }
+               (*csax) = (*csax) * (flipx ? -1 : 1);
+               csax++;
+       }
+       csy = 0;
+       csay = say;
+       for (y = 0; y < dst->h; y++) {
+               csy += src->h;
+               *csay = 0;
+               while (csy >= dst->h) {
+                       csy -= dst->h;
+                       (*csay)++;
+               }
+               (*csay) = (*csay) * (flipy ? -1 : 1);
+               csay++;
+       }
+
+       /*
+       * Draw 
+       */
+       csay = say;
+       for (y = 0; y < dst->h; y++) {
+               csax = sax;
+               sp = csp;
+               for (x = 0; x < dst->w; x++) {
+                       /*
+                       * Draw 
+                       */
+                       *dp = *sp;
+                       /*
+                       * Advance source pointers 
+                       */
+                       sp += (*csax);
+                       csax++;
+                       /*
+                       * Advance destination pointer 
+                       */
+                       dp++;
+               }
+               /*
+               * Advance source pointer (for row) 
+               */
+               csp += ((*csay) * src->pitch);
+               csay++;
+
+               /*
+               * Advance destination pointers 
+               */
+               dp += dgap;
+       }
+
+       /*
+       * Remove temp arrays 
+       */
+       free(sax);
+       free(say);
+
+       return (0);
+}
+
+/*! 
+\brief Internal 32 bit rotozoomer with optional anti-aliasing.
+
+Rotates and zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control 
+parameters by scanning the destination surface and applying optionally anti-aliasing
+by bilinear interpolation.
+Assumes src and dst surfaces are of 32 bit depth.
+Assumes dst surface was allocated with the correct dimensions.
+
+\param src Source surface.
+\param dst Destination surface.
+\param cx Horizontal center coordinate.
+\param cy Vertical center coordinate.
+\param isin Integer version of sine of angle.
+\param icos Integer version of cosine of angle.
+\param flipx Flag indicating horizontal mirroring should be applied.
+\param flipy Flag indicating vertical mirroring should be applied.
+\param smooth Flag indicating anti-aliasing should be used.
+*/
+static void _transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth)
+{
+       int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh;
+       tColorRGBA c00, c01, c10, c11, cswap;
+       tColorRGBA *pc, *sp;
+       int gap;
+
+       /*
+       * Variable setup 
+       */
+       xd = ((src->w - dst->w) << 15);
+       yd = ((src->h - dst->h) << 15);
+       ax = (cx << 16) - (icos * cx);
+       ay = (cy << 16) - (isin * cx);
+       sw = src->w - 1;
+       sh = src->h - 1;
+       pc = (tColorRGBA*) dst->pixels;
+       gap = dst->pitch - dst->w * 4;
+
+       /*
+       * Switch between interpolating and non-interpolating code 
+       */
+       if (smooth) {
+               for (y = 0; y < dst->h; y++) {
+                       dy = cy - y;
+                       sdx = (ax + (isin * dy)) + xd;
+                       sdy = (ay - (icos * dy)) + yd;
+                       for (x = 0; x < dst->w; x++) {
+                               dx = (sdx >> 16);
+                               dy = (sdy >> 16);
+                               if (flipx) dx = sw - dx;
+                               if (flipy) dy = sh - dy;
+                               if ((dx > -1) && (dy > -1) && (dx < (src->w-1)) && (dy < (src->h-1))) {
+                                       sp = (tColorRGBA *)src->pixels;;
+                                       sp += ((src->pitch/4) * dy);
+                                       sp += dx;
+                                       c00 = *sp;
+                                       sp += 1;
+                                       c01 = *sp;
+                                       sp += (src->pitch/4);
+                                       c11 = *sp;
+                                       sp -= 1;
+                                       c10 = *sp;
+                                       if (flipx) {
+                                               cswap = c00; c00=c01; c01=cswap;
+                                               cswap = c10; c10=c11; c11=cswap;
+                                       }
+                                       if (flipy) {
+                                               cswap = c00; c00=c10; c10=cswap;
+                                               cswap = c01; c01=c11; c11=cswap;
+                                       }
+                                       /*
+                                       * Interpolate colors 
+                                       */
+                                       ex = (sdx & 0xffff);
+                                       ey = (sdy & 0xffff);
+                                       t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff;
+                                       t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff;
+                                       pc->r = (((t2 - t1) * ey) >> 16) + t1;
+                                       t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff;
+                                       t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff;
+                                       pc->g = (((t2 - t1) * ey) >> 16) + t1;
+                                       t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff;
+                                       t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff;
+                                       pc->b = (((t2 - t1) * ey) >> 16) + t1;
+                                       t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff;
+                                       t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff;
+                                       pc->a = (((t2 - t1) * ey) >> 16) + t1;
+                               }
+                               sdx += icos;
+                               sdy += isin;
+                               pc++;
+                       }
+                       pc = (tColorRGBA *) ((Uint8 *) pc + gap);
+               }
+       } else {
+               for (y = 0; y < dst->h; y++) {
+                       dy = cy - y;
+                       sdx = (ax + (isin * dy)) + xd;
+                       sdy = (ay - (icos * dy)) + yd;
+                       for (x = 0; x < dst->w; x++) {
+                               dx = (short) (sdx >> 16);
+                               dy = (short) (sdy >> 16);
+                               if (flipx) dx = (src->w-1)-dx;
+                               if (flipy) dy = (src->h-1)-dy;
+                               if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) {
+                                       sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
+                                       sp += dx;
+                                       *pc = *sp;
+                               }
+                               sdx += icos;
+                               sdy += isin;
+                               pc++;
+                       }
+                       pc = (tColorRGBA *) ((Uint8 *) pc + gap);
+               }
+       }
+}
+
+/*!
+
+\brief Rotates and zooms 8 bit palette/Y 'src' surface to 'dst' surface without smoothing.
+
+Rotates and zooms 8 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control 
+parameters by scanning the destination surface.
+Assumes src and dst surfaces are of 8 bit depth.
+Assumes dst surface was allocated with the correct dimensions.
+
+\param src Source surface.
+\param dst Destination surface.
+\param cx Horizontal center coordinate.
+\param cy Vertical center coordinate.
+\param isin Integer version of sine of angle.
+\param icos Integer version of cosine of angle.
+\param flipx Flag indicating horizontal mirroring should be applied.
+\param flipy Flag indicating vertical mirroring should be applied.
+*/
+static void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy)
+{
+       int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay, sw, sh;
+       tColorY *pc, *sp;
+       int gap;
+
+       /*
+       * Variable setup 
+       */
+       xd = ((src->w - dst->w) << 15);
+       yd = ((src->h - dst->h) << 15);
+       ax = (cx << 16) - (icos * cx);
+       ay = (cy << 16) - (isin * cx);
+       sw = src->w - 1;
+       sh = src->h - 1;
+       pc = (tColorY*) dst->pixels;
+       gap = dst->pitch - dst->w;
+       /*
+       * Clear surface to colorkey 
+       */      
+       memset(pc, (int)(_colorkey(src) & 0xff), dst->pitch * dst->h);
+       /*
+       * Iterate through destination surface 
+       */
+       for (y = 0; y < dst->h; y++) {
+               dy = cy - y;
+               sdx = (ax + (isin * dy)) + xd;
+               sdy = (ay - (icos * dy)) + yd;
+               for (x = 0; x < dst->w; x++) {
+                       dx = (short) (sdx >> 16);
+                       dy = (short) (sdy >> 16);
+                       if (flipx) dx = (src->w-1)-dx;
+                       if (flipy) dy = (src->h-1)-dy;
+                       if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) {
+                               sp = (tColorY *) (src->pixels);
+                               sp += (src->pitch * dy + dx);
+                               *pc = *sp;
+                       }
+                       sdx += icos;
+                       sdy += isin;
+                       pc++;
+               }
+               pc += gap;
+       }
+}
+
+/*!
+\brief Rotates a 32 bit surface in increments of 90 degrees.
+
+Specialized 90 degree rotator which rotates a 'src' surface in 90 degree 
+increments clockwise returning a new surface. Faster than rotozoomer since
+not scanning or interpolation takes place. Input surface must be 32 bit.
+(code contributed by J. Schiller, improved by C. Allport and A. Schiffler)
+
+\param src Source surface to rotate.
+\param numClockwiseTurns Number of clockwise 90 degree turns to apply to the source.
+
+\returns The new, rotated surface; or NULL for surfaces with incorrect input format.
+*/
+SDL_Surface* rotateSurface90Degrees(SDL_Surface* src, int numClockwiseTurns) 
+{
+       int row, col, newWidth, newHeight;
+       int bpp, src_ipr, dst_ipr;
+       SDL_Surface* dst;
+       Uint32* srcBuf;
+       Uint32* dstBuf;
+
+       /* Has to be a valid surface pointer and only 32-bit surfaces (for now) */
+       if (!src || src->format->BitsPerPixel != 32) { return NULL; }
+
+       /* normalize numClockwiseTurns */
+       while(numClockwiseTurns < 0) { numClockwiseTurns += 4; }
+       numClockwiseTurns = (numClockwiseTurns % 4);
+
+       /* if it's even, our new width will be the same as the source surface */
+       newWidth = (numClockwiseTurns % 2) ? (src->h) : (src->w);
+       newHeight = (numClockwiseTurns % 2) ? (src->w) : (src->h);
+       dst = SDL_CreateRGBSurface( src->flags, newWidth, newHeight, src->format->BitsPerPixel,
+               src->format->Rmask,
+               src->format->Gmask, 
+               src->format->Bmask, 
+               src->format->Amask);
+       if(!dst) {
+               return NULL;
+       }
+
+       if (SDL_MUSTLOCK(dst)) {
+               SDL_LockSurface(dst);
+       }
+       if (SDL_MUSTLOCK(dst)) {
+               SDL_LockSurface(dst);
+       }
+
+       /* Calculate int-per-row */
+       bpp = src->format->BitsPerPixel / 8;
+       src_ipr = src->pitch / bpp;
+       dst_ipr = dst->pitch / bpp;
+
+       switch(numClockwiseTurns) {
+       case 0: /* Make a copy of the surface */
+               {
+                       /* Unfortunately SDL_BlitSurface cannot be used to make a copy of the surface
+                       since it does not preserve alpha. */
+
+                       if (src->pitch == dst->pitch) {
+                               /* If the pitch is the same for both surfaces, the memory can be copied all at once. */
+                               memcpy(dst->pixels, src->pixels, (src->h * src->pitch));
+                       }
+                       else
+                       {
+                               /* If the pitch differs, copy each row separately */
+                               srcBuf = (Uint32*)(src->pixels); 
+                               dstBuf = (Uint32*)(dst->pixels);
+                               for (row = 0; row < src->h; row++) {
+                                       memcpy(dstBuf, srcBuf, dst->w * bpp);
+                                       srcBuf += src_ipr;
+                                       dstBuf += dst_ipr;
+                               } /* end for(col) */
+                       } /* end for(row) */
+               }
+               break;
+
+               /* rotate clockwise */
+       case 1: /* rotated 90 degrees clockwise */
+               {
+                       for (row = 0; row < src->h; ++row) {
+                               srcBuf = (Uint32*)(src->pixels) + (row * src_ipr);
+                               dstBuf = (Uint32*)(dst->pixels) + (dst->w - row - 1);
+                               for (col = 0; col < src->w; ++col) {
+                                       *dstBuf = *srcBuf;
+                                       ++srcBuf;
+                                       dstBuf += dst_ipr;
+                               } 
+                               /* end for(col) */
+                       } 
+                       /* end for(row) */
+               }
+               break;
+
+       case 2: /* rotated 180 degrees clockwise */
+               {
+                       for (row = 0; row < src->h; ++row) {
+                               srcBuf = (Uint32*)(src->pixels) + (row * src_ipr);
+                               dstBuf = (Uint32*)(dst->pixels) + ((dst->h - row - 1) * dst_ipr) + (dst->w - 1);
+                               for (col = 0; col < src->w; ++col) {
+                                       *dstBuf = *srcBuf;
+                                       ++srcBuf;
+                                       --dstBuf;
+                               } 
+                       } 
+               }
+               break;
+
+       case 3:
+               {
+                       for (row = 0; row < src->h; ++row) {
+                               srcBuf = (Uint32*)(src->pixels) + (row * src_ipr);
+                               dstBuf = (Uint32*)(dst->pixels) + row + ((dst->h - 1) * dst_ipr);
+                               for (col = 0; col < src->w; ++col) {
+                                       *dstBuf = *srcBuf;
+                                       ++srcBuf;
+                                       dstBuf -= dst_ipr;
+                               } 
+                       } 
+               }
+               break;
+       } 
+       /* end switch */
+
+       if (SDL_MUSTLOCK(src)) {
+               SDL_UnlockSurface(src);
+       }
+       if (SDL_MUSTLOCK(dst)) {
+               SDL_UnlockSurface(dst);
+       }
+
+       return dst;
+}
+
+
+/*!
+\brief Internal target surface sizing function for rotozooms with trig result return. 
+
+\param width The source surface width.
+\param height The source surface height.
+\param angle The angle to rotate in degrees.
+\param zoomx The horizontal scaling factor.
+\param zoomy The vertical scaling factor.
+\param dstwidth The calculated width of the destination surface.
+\param dstheight The calculated height of the destination surface.
+\param canglezoom The sine of the angle adjusted by the zoom factor.
+\param sanglezoom The cosine of the angle adjusted by the zoom factor.
+
+*/
+static void _rotozoomSurfaceSizeTrig(int width, int height, double angle, double zoomx, double zoomy, 
+       int *dstwidth, int *dstheight, 
+       double *canglezoom, double *sanglezoom)
+{
+       double x, y, cx, cy, sx, sy;
+       double radangle;
+       int dstwidthhalf, dstheighthalf;
+
+       /*
+       * Determine destination width and height by rotating a centered source box 
+       */
+       radangle = angle * (M_PI / 180.0);
+       *sanglezoom = sin(radangle);
+       *canglezoom = cos(radangle);
+       *sanglezoom *= zoomx;
+       *canglezoom *= zoomx;
+       x = (double)(width / 2);
+       y = (double)(height / 2);
+       cx = *canglezoom * x;
+       cy = *canglezoom * y;
+       sx = *sanglezoom * x;
+       sy = *sanglezoom * y;
+
+       dstwidthhalf = MAX((int)
+               ceil(MAX(MAX(MAX(fabs(cx + sy), fabs(cx - sy)), fabs(-cx + sy)), fabs(-cx - sy))), 1);
+       dstheighthalf = MAX((int)
+               ceil(MAX(MAX(MAX(fabs(sx + cy), fabs(sx - cy)), fabs(-sx + cy)), fabs(-sx - cy))), 1);
+       *dstwidth = 2 * dstwidthhalf;
+       *dstheight = 2 * dstheighthalf;
+}
+
+/*! 
+\brief Returns the size of the resulting target surface for a rotozoomSurfaceXY() call. 
+
+\param width The source surface width.
+\param height The source surface height.
+\param angle The angle to rotate in degrees.
+\param zoomx The horizontal scaling factor.
+\param zoomy The vertical scaling factor.
+\param dstwidth The calculated width of the rotozoomed destination surface.
+\param dstheight The calculated height of the rotozoomed destination surface.
+*/
+void rotozoomSurfaceSizeXY(int width, int height, double angle, double zoomx, double zoomy, int *dstwidth, int *dstheight)
+{
+       double dummy_sanglezoom, dummy_canglezoom;
+
+       _rotozoomSurfaceSizeTrig(width, height, angle, zoomx, zoomy, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom);
+}
+
+/*! 
+\brief Returns the size of the resulting target surface for a rotozoomSurface() call. 
+
+\param width The source surface width.
+\param height The source surface height.
+\param angle The angle to rotate in degrees.
+\param zoom The scaling factor.
+\param dstwidth The calculated width of the rotozoomed destination surface.
+\param dstheight The calculated height of the rotozoomed destination surface.
+*/
+void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight)
+{
+       double dummy_sanglezoom, dummy_canglezoom;
+
+       _rotozoomSurfaceSizeTrig(width, height, angle, zoom, zoom, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom);
+}
+
+/*!
+\brief Rotates and zooms a surface and optional anti-aliasing. 
+
+Rotates and zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface.
+'angle' is the rotation in degrees and 'zoom' a scaling factor. If 'smooth' is set
+then the destination 32bit surface is anti-aliased. If the surface is not 8bit
+or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
+
+\param src The surface to rotozoom.
+\param angle The angle to rotate in degrees.
+\param zoom The scaling factor.
+\param smooth Antialiasing flag; set to SMOOTHING_ON to enable.
+
+\return The new rotozoomed surface.
+*/
+SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth)
+{
+       return rotozoomSurfaceXY(src, angle, zoom, zoom, smooth);
+}
+
+/*!
+\brief Rotates and zooms a surface with different horizontal and vertival scaling factors and optional anti-aliasing. 
+
+Rotates and zooms a 32bit or 8bit 'src' surface to newly created 'dst' surface.
+'angle' is the rotation in degrees, 'zoomx and 'zoomy' scaling factors. If 'smooth' is set
+then the destination 32bit surface is anti-aliased. If the surface is not 8bit
+or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
+
+\param src The surface to rotozoom.
+\param angle The angle to rotate in degrees.
+\param zoomx The horizontal scaling factor.
+\param zoomy The vertical scaling factor.
+\param smooth Antialiasing flag; set to SMOOTHING_ON to enable.
+
+\return The new rotozoomed surface.
+*/
+SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth)
+{
+       SDL_Surface *rz_src;
+       SDL_Surface *rz_dst;
+       double zoominv;
+       double sanglezoom, canglezoom, sanglezoominv, canglezoominv;
+       int dstwidthhalf, dstwidth, dstheighthalf, dstheight;
+       int is32bit;
+       int i, src_converted;
+       int flipx,flipy;
+       Uint8 r,g,b;
+       Uint32 colorkey = 0;
+       int colorKeyAvailable = 0;
+
+       /*
+       * Sanity check 
+       */
+       if (src == NULL)
+               return (NULL);
+
+       if (src->flags & SDL_SRCCOLORKEY)
+       {
+               colorkey = _colorkey(src);
+               SDL_GetRGB(colorkey, src->format, &r, &g, &b);
+               colorKeyAvailable = 1;
+       }
+       /*
+       * Determine if source surface is 32bit or 8bit 
+       */
+       is32bit = (src->format->BitsPerPixel == 32);
+       if ((is32bit) || (src->format->BitsPerPixel == 8)) {
+               /*
+               * Use source surface 'as is' 
+               */
+               rz_src = src;
+               src_converted = 0;
+       } else {
+               /*
+               * New source surface is 32bit with a defined RGBA ordering 
+               */
+               rz_src =
+                       SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, 
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+                       0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
+#else
+                       0xff000000,  0x00ff0000, 0x0000ff00, 0x000000ff
+#endif
+                       );
+               if(colorKeyAvailable)
+                       SDL_SetColorKey(src, 0, 0);
+
+               SDL_BlitSurface(src, NULL, rz_src, NULL);
+
+               if(colorKeyAvailable)
+                       SDL_SetColorKey(src, SDL_SRCCOLORKEY, colorkey);
+               src_converted = 1;
+               is32bit = 1;
+       }
+
+       /*
+       * Sanity check zoom factor 
+       */
+       flipx = (zoomx<0.0);
+       if (flipx) zoomx=-zoomx;
+       flipy = (zoomy<0.0);
+       if (flipy) zoomy=-zoomy;
+       if (zoomx < VALUE_LIMIT) zoomx = VALUE_LIMIT;
+       if (zoomy < VALUE_LIMIT) zoomy = VALUE_LIMIT;
+       zoominv = 65536.0 / (zoomx * zoomx);
+
+       /*
+       * Check if we have a rotozoom or just a zoom 
+       */
+       if (fabs(angle) > VALUE_LIMIT) {
+
+               /*
+               * Angle!=0: full rotozoom 
+               */
+               /*
+               * ----------------------- 
+               */
+
+               /* Determine target size */
+               _rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, zoomx, zoomy, &dstwidth, &dstheight, &canglezoom, &sanglezoom);
+
+               /*
+               * Calculate target factors from sin/cos and zoom 
+               */
+               sanglezoominv = sanglezoom;
+               canglezoominv = canglezoom;
+               sanglezoominv *= zoominv;
+               canglezoominv *= zoominv;
+
+               /* Calculate half size */
+               dstwidthhalf = dstwidth / 2;
+               dstheighthalf = dstheight / 2;
+
+               /*
+               * Alloc space to completely contain the rotated surface 
+               */
+               rz_dst = NULL;
+               if (is32bit) {
+                       /*
+                       * Target surface is 32bit with source RGBA/ABGR ordering 
+                       */
+                       rz_dst =
+                               SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32,
+                               rz_src->format->Rmask, rz_src->format->Gmask,
+                               rz_src->format->Bmask, rz_src->format->Amask);
+               } else {
+                       /*
+                       * Target surface is 8bit 
+                       */
+                       rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0);
+               }
+
+               /* Check target */
+               if (rz_dst == NULL)
+                       return NULL;
+
+               /* Adjust for guard rows */
+               rz_dst->h = dstheight;
+
+               if (colorKeyAvailable == 1){
+                       colorkey = SDL_MapRGB(rz_dst->format, r, g, b);
+
+                       SDL_FillRect(rz_dst, NULL, colorkey );
+               }
+
+               /*
+               * Lock source surface 
+               */
+               if (SDL_MUSTLOCK(rz_src)) {
+                       SDL_LockSurface(rz_src);
+               }
+
+               /*
+               * Check which kind of surface we have 
+               */
+               if (is32bit) {
+                       /*
+                       * Call the 32bit transformation routine to do the rotation (using alpha) 
+                       */
+                       _transformSurfaceRGBA(rz_src, rz_dst, dstwidthhalf, dstheighthalf,
+                               (int) (sanglezoominv), (int) (canglezoominv), 
+                               flipx, flipy,
+                               smooth);
+                       /*
+                       * Turn on source-alpha support 
+                       */
+                       SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
+                       SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src));
+               } else {
+                       /*
+                       * Copy palette and colorkey info 
+                       */
+                       for (i = 0; i < rz_src->format->palette->ncolors; i++) {
+                               rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
+                       }
+                       rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
+                       /*
+                       * Call the 8bit transformation routine to do the rotation 
+                       */
+                       transformSurfaceY(rz_src, rz_dst, dstwidthhalf, dstheighthalf,
+                               (int) (sanglezoominv), (int) (canglezoominv),
+                               flipx, flipy);
+                       SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src));
+               }
+               /*
+               * Unlock source surface 
+               */
+               if (SDL_MUSTLOCK(rz_src)) {
+                       SDL_UnlockSurface(rz_src);
+               }
+
+       } else {
+
+               /*
+               * Angle=0: Just a zoom 
+               */
+               /*
+               * -------------------- 
+               */
+
+               /*
+               * Calculate target size
+               */
+               zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight);
+
+               /*
+               * Alloc space to completely contain the zoomed surface 
+               */
+               rz_dst = NULL;
+               if (is32bit) {
+                       /*
+                       * Target surface is 32bit with source RGBA/ABGR ordering 
+                       */
+                       rz_dst =
+                               SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32,
+                               rz_src->format->Rmask, rz_src->format->Gmask,
+                               rz_src->format->Bmask, rz_src->format->Amask);
+               } else {
+                       /*
+                       * Target surface is 8bit 
+                       */
+                       rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0);
+               }
+
+               /* Check target */
+               if (rz_dst == NULL)
+                       return NULL;
+
+               /* Adjust for guard rows */
+               rz_dst->h = dstheight;
+
+               if (colorKeyAvailable == 1){
+                       colorkey = SDL_MapRGB(rz_dst->format, r, g, b);
+
+                       SDL_FillRect(rz_dst, NULL, colorkey );
+               }
+
+               /*
+               * Lock source surface 
+               */
+               if (SDL_MUSTLOCK(rz_src)) {
+                       SDL_LockSurface(rz_src);
+               }
+
+               /*
+               * Check which kind of surface we have 
+               */
+               if (is32bit) {
+                       /*
+                       * Call the 32bit transformation routine to do the zooming (using alpha) 
+                       */
+                       _zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth);
+
+                       /*
+                       * Turn on source-alpha support 
+                       */
+                       SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
+                       SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src));
+               } else {
+                       /*
+                       * Copy palette and colorkey info 
+                       */
+                       for (i = 0; i < rz_src->format->palette->ncolors; i++) {
+                               rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
+                       }
+                       rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
+
+                       /*
+                       * Call the 8bit transformation routine to do the zooming 
+                       */
+                       _zoomSurfaceY(rz_src, rz_dst, flipx, flipy);
+                       SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src));
+               }
+
+               /*
+               * Unlock source surface 
+               */
+               if (SDL_MUSTLOCK(rz_src)) {
+                       SDL_UnlockSurface(rz_src);
+               }
+       }
+
+       /*
+       * Cleanup temp surface 
+       */
+       if (src_converted) {
+               SDL_FreeSurface(rz_src);
+       }
+
+       /*
+       * Return destination surface 
+       */
+       return (rz_dst);
+}
+
+/*!
+\brief Calculates the size of the target surface for a zoomSurface() call.
+
+The minimum size of the target surface is 1. The input factors can be positive or negative.
+
+\param width The width of the source surface to zoom.
+\param height The height of the source surface to zoom.
+\param zoomx The horizontal zoom factor.
+\param zoomy The vertical zoom factor.
+\param dstwidth Pointer to an integer to store the calculated width of the zoomed target surface.
+\param dstheight Pointer to an integer to store the calculated height of the zoomed target surface.
+*/
+void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight)
+{
+       /*
+       * Make zoom factors positive 
+       */
+       int flipx, flipy;
+       flipx = (zoomx<0.0);
+       if (flipx) zoomx = -zoomx;
+       flipy = (zoomy<0.0);
+       if (flipy) zoomy = -zoomy;
+
+       /*
+       * Sanity check zoom factors 
+       */
+       if (zoomx < VALUE_LIMIT) {
+               zoomx = VALUE_LIMIT;
+       }
+       if (zoomy < VALUE_LIMIT) {
+               zoomy = VALUE_LIMIT;
+       }
+
+       /*
+       * Calculate target size 
+       */
+       *dstwidth = (int) floor(((double) width * zoomx) + 0.5);
+       *dstheight = (int) floor(((double) height * zoomy) + 0.5);
+       if (*dstwidth < 1) {
+               *dstwidth = 1;
+       }
+       if (*dstheight < 1) {
+               *dstheight = 1;
+       }
+}
+
+/*! 
+\brief Zoom a surface by independent horizontal and vertical factors with optional smoothing.
+
+Zooms a 32bit or 8bit 'src' surface to newly created 'dst' surface.
+'zoomx' and 'zoomy' are scaling factors for width and height. If 'smooth' is on
+then the destination 32bit surface is anti-aliased. If the surface is not 8bit
+or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
+If zoom factors are negative, the image is flipped on the axes.
+
+\param src The surface to zoom.
+\param zoomx The horizontal zoom factor.
+\param zoomy The vertical zoom factor.
+\param smooth Antialiasing flag; set to SMOOTHING_ON to enable.
+
+\return The new, zoomed surface.
+*/
+SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth)
+{
+       SDL_Surface *rz_src;
+       SDL_Surface *rz_dst;
+       int dstwidth, dstheight;
+       int is32bit;
+       int i, src_converted;
+       int flipx, flipy;
+
+       /*
+       * Sanity check 
+       */
+       if (src == NULL)
+               return (NULL);
+
+       /*
+       * Determine if source surface is 32bit or 8bit 
+       */
+       is32bit = (src->format->BitsPerPixel == 32);
+       if ((is32bit) || (src->format->BitsPerPixel == 8)) {
+               /*
+               * Use source surface 'as is' 
+               */
+               rz_src = src;
+               src_converted = 0;
+       } else {
+               /*
+               * New source surface is 32bit with a defined RGBA ordering 
+               */
+               rz_src =
+                       SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, 
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+                       0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
+#else
+                       0xff000000,  0x00ff0000, 0x0000ff00, 0x000000ff
+#endif
+                       );
+               if (rz_src == NULL) {
+                       return NULL;
+               }
+               SDL_BlitSurface(src, NULL, rz_src, NULL);
+               src_converted = 1;
+               is32bit = 1;
+       }
+
+       flipx = (zoomx<0.0);
+       if (flipx) zoomx = -zoomx;
+       flipy = (zoomy<0.0);
+       if (flipy) zoomy = -zoomy;
+
+       /* Get size if target */
+       zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight);
+
+       /*
+       * Alloc space to completely contain the zoomed surface 
+       */
+       rz_dst = NULL;
+       if (is32bit) {
+               /*
+               * Target surface is 32bit with source RGBA/ABGR ordering 
+               */
+               rz_dst =
+                       SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32,
+                       rz_src->format->Rmask, rz_src->format->Gmask,
+                       rz_src->format->Bmask, rz_src->format->Amask);
+       } else {
+               /*
+               * Target surface is 8bit 
+               */
+               rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0);
+       }
+
+       /* Check target */
+       if (rz_dst == NULL) {
+               /*
+               * Cleanup temp surface 
+               */
+               if (src_converted) {
+                       SDL_FreeSurface(rz_src);
+               }               
+               return NULL;
+       }
+
+       /* Adjust for guard rows */
+       rz_dst->h = dstheight;
+
+       /*
+       * Lock source surface 
+       */
+       if (SDL_MUSTLOCK(rz_src)) {
+               SDL_LockSurface(rz_src);
+       }
+
+       /*
+       * Check which kind of surface we have 
+       */
+       if (is32bit) {
+               /*
+               * Call the 32bit transformation routine to do the zooming (using alpha) 
+               */
+               _zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth);
+               /*
+               * Turn on source-alpha support 
+               */
+               SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
+       } else {
+               /*
+               * Copy palette and colorkey info 
+               */
+               for (i = 0; i < rz_src->format->palette->ncolors; i++) {
+                       rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
+               }
+               rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
+               /*
+               * Call the 8bit transformation routine to do the zooming 
+               */
+               _zoomSurfaceY(rz_src, rz_dst, flipx, flipy);
+               SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src));
+       }
+       /*
+       * Unlock source surface 
+       */
+       if (SDL_MUSTLOCK(rz_src)) {
+               SDL_UnlockSurface(rz_src);
+       }
+
+       /*
+       * Cleanup temp surface 
+       */
+       if (src_converted) {
+               SDL_FreeSurface(rz_src);
+       }
+
+       /*
+       * Return destination surface 
+       */
+       return (rz_dst);
+}
+
+/*! 
+\brief Shrink a surface by an integer ratio using averaging.
+
+Shrinks a 32bit or 8bit 'src' surface to a newly created 'dst' surface.
+'factorx' and 'factory' are the shrinking ratios (i.e. 2=1/2 the size,
+3=1/3 the size, etc.) The destination surface is antialiased by averaging
+the source box RGBA or Y information. If the surface is not 8bit
+or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
+The input surface is not modified. The output surface is newly allocated.
+
+\param src The surface to shrink.
+\param factorx The horizontal shrinking ratio.
+\param factory The vertical shrinking ratio.
+
+\return The new, shrunken surface.
+*/
+/*@null@*/ 
+SDL_Surface *shrinkSurface(SDL_Surface *src, int factorx, int factory)
+{
+       int result;
+       SDL_Surface *rz_src;
+       SDL_Surface *rz_dst = NULL;
+       int dstwidth, dstheight;
+       int is32bit;
+       int i, src_converted;
+       int haveError = 0;
+
+       /*
+       * Sanity check 
+       */
+       if (src == NULL) {
+               return (NULL);
+       }
+
+       /*
+       * Determine if source surface is 32bit or 8bit 
+       */
+       is32bit = (src->format->BitsPerPixel == 32);
+       if ((is32bit) || (src->format->BitsPerPixel == 8)) {
+               /*
+               * Use source surface 'as is' 
+               */
+               rz_src = src;
+               src_converted = 0;
+       } else {
+               /*
+               * New source surface is 32bit with a defined RGBA ordering 
+               */
+               rz_src = SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, 
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+                       0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
+#else
+                       0xff000000,  0x00ff0000, 0x0000ff00, 0x000000ff
+#endif
+                       );
+               if (rz_src==NULL) {
+                       haveError = 1;
+                       goto exitShrinkSurface;
+               }
+
+               SDL_BlitSurface(src, NULL, rz_src, NULL);
+               src_converted = 1;
+               is32bit = 1;
+       }
+
+       /*
+       * Lock the surface 
+       */
+       if (SDL_MUSTLOCK(rz_src)) {
+               if (SDL_LockSurface(rz_src) < 0) {
+                       haveError = 1;
+                       goto exitShrinkSurface;
+               }
+       }
+
+       /* Get size for target */
+       dstwidth=rz_src->w/factorx;
+       while (dstwidth*factorx>rz_src->w) { dstwidth--; }
+       dstheight=rz_src->h/factory;
+       while (dstheight*factory>rz_src->h) { dstheight--; }
+
+       /*
+       * Alloc space to completely contain the shrunken surface
+       * (with added guard rows)
+       */
+       if (is32bit==1) {
+               /*
+               * Target surface is 32bit with source RGBA/ABGR ordering 
+               */
+               rz_dst =
+                       SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32,
+                       rz_src->format->Rmask, rz_src->format->Gmask,
+                       rz_src->format->Bmask, rz_src->format->Amask);
+       } else {
+               /*
+               * Target surface is 8bit 
+               */
+               rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0);
+       }
+
+       /* Check target */
+       if (rz_dst == NULL) {
+               haveError = 1;
+               goto exitShrinkSurface;
+       }
+
+       /* Adjust for guard rows */
+       rz_dst->h = dstheight;
+
+       /*
+       * Check which kind of surface we have 
+       */
+       if (is32bit==1) {
+               /*
+               * Call the 32bit transformation routine to do the shrinking (using alpha) 
+               */
+               result = _shrinkSurfaceRGBA(rz_src, rz_dst, factorx, factory);          
+               if ((result!=0) || (rz_dst==NULL)) {
+                       haveError = 1;
+                       goto exitShrinkSurface;
+               }
+
+               /*
+               * Turn on source-alpha support 
+               */
+               result = SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
+               if (result!=0) {
+                       haveError = 1;
+                       goto exitShrinkSurface;
+               }
+       } else {
+               /*
+               * Copy palette and colorkey info 
+               */
+               for (i = 0; i < rz_src->format->palette->ncolors; i++) {
+                       rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
+               }
+               rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
+               /*
+               * Call the 8bit transformation routine to do the shrinking 
+               */
+               result = _shrinkSurfaceY(rz_src, rz_dst, factorx, factory);
+               if (result!=0) {
+                       haveError = 1;
+                       goto exitShrinkSurface;
+               }
+
+               /*
+               * Set colorkey on target
+               */
+               result = SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src));
+               if (result!=0) {
+                       haveError = 1;
+                       goto exitShrinkSurface;
+               }               
+       }
+
+exitShrinkSurface:
+       if (rz_src!=NULL) {
+               /*
+               * Unlock source surface 
+               */
+               if (SDL_MUSTLOCK(rz_src)) {
+                       SDL_UnlockSurface(rz_src);
+               }
+
+               /*
+               * Cleanup temp surface 
+               */
+               if (src_converted==1) {
+                       SDL_FreeSurface(rz_src);
+               }
+       }
+
+       /* Check error state; maybe need to cleanup destination */
+       if (haveError==1) {
+               if (rz_dst!=NULL) {
+                       SDL_FreeSurface(rz_dst);
+               }
+               rz_dst=NULL;
+       } 
+
+       /*
+       * Return destination surface 
+       */
+       return (rz_dst);
+}
diff --git a/tizen/src/SDL_gfx/SDL_rotozoom.h b/tizen/src/SDL_gfx/SDL_rotozoom.h
new file mode 100644 (file)
index 0000000..80b31f1
--- /dev/null
@@ -0,0 +1,123 @@
+/*  
+
+SDL_rotozoom.c: rotozoomer, zoomer and shrinker for 32bit or 8bit surfaces
+
+Copyright (C) 2001-2012  Andreas Schiffler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+claim that you wrote the original software. If you use this software
+in a product, an acknowledgment in the product documentation would be
+appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and must not be
+misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+
+Andreas Schiffler -- aschiffler at ferzkopp dot net
+
+*/
+
+#ifndef _SDL_rotozoom_h
+#define _SDL_rotozoom_h
+
+#include <math.h>
+
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef M_PI
+#define M_PI   3.141592654
+#endif
+
+#include "SDL.h"
+
+       /* ---- Defines */
+
+       /*!
+       \brief Disable anti-aliasing (no smoothing).
+       */
+#define SMOOTHING_OFF          0
+
+       /*!
+       \brief Enable anti-aliasing (smoothing).
+       */
+#define SMOOTHING_ON           1
+
+       /* ---- Function Prototypes */
+
+#ifdef _MSC_VER
+#  if defined(DLL_EXPORT) && !defined(LIBSDL_GFX_DLL_IMPORT)
+#    define SDL_ROTOZOOM_SCOPE __declspec(dllexport)
+#  else
+#    ifdef LIBSDL_GFX_DLL_IMPORT
+#      define SDL_ROTOZOOM_SCOPE __declspec(dllimport)
+#    endif
+#  endif
+#endif
+#ifndef SDL_ROTOZOOM_SCOPE
+#  define SDL_ROTOZOOM_SCOPE extern
+#endif
+
+       /* 
+
+       Rotozoom functions
+
+       */
+
+       SDL_ROTOZOOM_SCOPE SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth);
+
+       SDL_ROTOZOOM_SCOPE SDL_Surface *rotozoomSurfaceXY
+               (SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth);
+
+
+       SDL_ROTOZOOM_SCOPE void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth,
+               int *dstheight);
+
+       SDL_ROTOZOOM_SCOPE void rotozoomSurfaceSizeXY
+               (int width, int height, double angle, double zoomx, double zoomy, 
+               int *dstwidth, int *dstheight);
+
+       /* 
+
+       Zooming functions
+
+       */
+
+       SDL_ROTOZOOM_SCOPE SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth);
+
+       SDL_ROTOZOOM_SCOPE void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight);
+
+       /* 
+
+       Shrinking functions
+
+       */     
+
+       SDL_ROTOZOOM_SCOPE SDL_Surface *shrinkSurface(SDL_Surface * src, int factorx, int factory);
+
+       /* 
+
+       Specialized rotation functions
+
+       */
+
+       SDL_ROTOZOOM_SCOPE SDL_Surface* rotateSurface90Degrees(SDL_Surface* src, int numClockwiseTurns);
+
+       /* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif                         /* _SDL_rotozoom_h */
index 227cea2..47f7d32 100644 (file)
@@ -1 +1 @@
-2.0.0
+Maru
diff --git a/tizen/src/check_gl.c b/tizen/src/check_gl.c
new file mode 100644 (file)
index 0000000..1d83edb
--- /dev/null
@@ -0,0 +1,7 @@
+#include "hw/gloffscreen_test.h"
+#include "debug_ch.h"
+
+int main (int argc, char** argv)
+{
+       return gl_acceleration_capability_check();
+}
index 955af7f..f11664f 100644 (file)
 #include "emulator.h"
 #include "debug_ch.h"
 
-// DEBUGCH file is located in binary directory.
-char bin_dir[1024] = {0,};
-
-static char logpath[512] = {0,};
 static char debugchfile[512] = {0, };
 #ifdef _WIN32
 static HANDLE handle;
 #endif
 
-void set_log_path(char *path)
-{
-    strcpy(logpath, path);
-}
-
-char *get_log_path(void)
-{
-    return logpath;
-}
-
 static inline int interlocked_xchg_add( int *dest, int incr )
 {
        int ret_val;
@@ -289,10 +275,10 @@ static void debug_init(void)
        strcat(debugchfile, "/DEBUGCH");
 #endif
 
-    if (0 == strlen(bin_dir)) {
+    if (0 == strlen(bin_path)) {
         strcpy(debugchfile, "DEBUGCH");
     } else {
-        strcat(debugchfile, bin_dir);
+        strcat(debugchfile, bin_path);
         strcat(debugchfile, "DEBUGCH");
     }
 
@@ -326,9 +312,9 @@ static void debug_init(void)
        }
        
        open_flags = O_BINARY | O_RDWR | O_CREAT | O_TRUNC;
-       fd = qemu_open(logpath, open_flags, 0666);
+       fd = qemu_open(log_path, open_flags, 0666);
     if(fd < 0) {
-        fprintf(stderr, "Can't open logfile: %s\n", logpath);
+        fprintf(stderr, "Can't open logfile: %s\n", log_path);
        exit(1);
     }
     close(fd);
@@ -375,7 +361,7 @@ static int dbg_vprintf( const char *format, va_list args )
        sprintf(txt, "%s", tmp);
 
        // unlock
-       if ((fp = fopen(logpath, "a+")) == NULL) {
+       if ((fp = fopen(log_path, "a+")) == NULL) {
                fprintf(stdout, "Emulator can't open.\n"
                                "Please check if "
                                "this binary file is running on the right path.\n");
@@ -455,9 +441,9 @@ int dbg_log( enum _debug_class cls, struct _debug_channel *channel,
        va_end(valist);
    
     open_flags = O_RDWR | O_APPEND | O_BINARY ;
-       fd = qemu_open(logpath, open_flags, 0666);
+       fd = qemu_open(log_path, open_flags, 0666);
        if(fd < 0) {
-        fprintf(stderr, "Can't open logfile: %s\n", logpath);
+        fprintf(stderr, "Can't open logfile: %s\n", log_path);
        exit(1);
     }
     ret_write = qemu_write_full(fd, buf, ret);
index 1788592..e1c193b 100644 (file)
@@ -57,9 +57,6 @@ struct _debug_channel
        char multiname[15];
 };
 
-void set_log_path(char *path);
-char *get_log_path(void);
-
 #ifndef NO_DEBUG
 #define MSGSIZE_MAX 2048
 #define __GET_DEBUGGING_FIXME(dbch) ((dbch)->flags & (1 << __DBCL_FIXME))
@@ -97,8 +94,6 @@ char *get_log_path(void);
 (void)0 : (void)dbg_printf
 */
 
-extern char bin_dir[1024];
-
 extern unsigned char _dbg_get_channel_flags( struct _debug_channel *channel );
 extern int _dbg_set_channel_flags( struct _debug_channel *channel,
                unsigned char set, unsigned char clear );
index b6d78ed..ea71444 100644 (file)
@@ -57,17 +57,6 @@ int get_emul_skin_enable(void)
     return _emul_info.skin_enable;
 }
 
-/* current emulator condition */
-int get_emulator_condition(void)
-{
-    return _emul_state.emulator_condition;
-}
-
-void set_emulator_condition(int state)
-{
-    _emul_state.emulator_condition = state;
-}
-
 /* lcd screen size */
 void set_emul_lcd_size(int width, int height)
 {
@@ -120,6 +109,28 @@ int get_emul_max_touch_point(void)
     return _emul_info.max_touch_point;
 }
 
+/* base port for emualtor vm */
+void set_emul_vm_base_port(int port)
+{
+    _emul_info.vm_base_port = port;
+}
+
+int get_emul_vm_base_port(void)
+{
+    return _emul_info.vm_base_port;
+}
+
+/* current emulator condition */
+int get_emulator_condition(void)
+{
+    return _emul_state.emulator_condition;
+}
+
+void set_emulator_condition(int state)
+{
+    _emul_state.emulator_condition = state;
+}
+
 /* emulator window scale */
 void set_emul_win_scale(double scale_factor)
 {
@@ -191,7 +202,7 @@ int get_host_lock_key_state(int key)
     return -1;
 }
 
-/* manage CapsLock key state for usb keyboard input */
+/* manage CapsLock key state for host keyboard input */
 void set_emul_caps_lock_state(int state)
 {
     _emul_state.qemu_caps_lock = state;
@@ -199,10 +210,10 @@ void set_emul_caps_lock_state(int state)
 
 int get_emul_caps_lock_state(void)
 {
-    return  _emul_state.qemu_caps_lock;
+    return _emul_state.qemu_caps_lock;
 }
 
-/* manage NumLock key state for usb keyboard input */
+/* manage NumLock key state for host keyboard input */
 void set_emul_num_lock_state(int state)
 {
     _emul_state.qemu_num_lock = state;
@@ -210,5 +221,6 @@ void set_emul_num_lock_state(int state)
 
 int get_emul_num_lock_state(void)
 {
-    return  _emul_state.qemu_num_lock;
+    return _emul_state.qemu_num_lock;
 }
+
index 66655cc..efb1232 100644 (file)
@@ -39,8 +39,8 @@
 
 /* keep it consistent with emulator-skin definition */
 enum {
-    HARD_KEY_HOME = 101,
-    HARD_KEY_POWER = 103,
+    HARD_KEY_HOME = 139,
+    HARD_KEY_POWER = 116,
     HARD_KEY_VOL_UP = 115,
     HARD_KEY_VOL_DOWN = 114,
 };
@@ -80,7 +80,8 @@ typedef  struct EmulatorConfigInfo {
     int lcd_size_h;
     int sdl_bpp;
     int max_touch_point;
-    //TODO:
+    int vm_base_port;
+    /* add here */
 } EmulatorConfigInfo;
 
 typedef struct EmulatorConfigState {
@@ -90,7 +91,7 @@ typedef struct EmulatorConfigState {
     MultiTouchState qemu_mts;
     int qemu_caps_lock;
     int qemu_num_lock;
-    //TODO:
+    /* add here */
 } EmulatorConfigState;
 
 
@@ -100,6 +101,8 @@ void set_emul_lcd_size(int width, int height);
 void set_emul_win_scale(double scale);
 void set_emul_sdl_bpp(int bpp);
 void set_emul_max_touch_point(int cnt);
+void set_emul_vm_base_port(int port);
+
 void set_emulator_condition(int state);
 void set_emul_rotation(short rotation_type);
 void set_emul_caps_lock_state(int state);
@@ -112,6 +115,8 @@ int get_emul_lcd_height(void);
 double get_emul_win_scale(void);
 int get_emul_sdl_bpp(void);
 int get_emul_max_touch_point(void);
+int get_emul_vm_base_port(void);
+
 int get_emulator_condition(void);
 short get_emul_rotation(void);
 MultiTouchState *get_emul_multi_touch_state(void);
similarity index 64%
rename from tizen/src/option.h
rename to tizen/src/emul_state_darwin.m
index 44b26a7..b4fab47 100644 (file)
@@ -1,14 +1,14 @@
-/* 
+/*
  * Emulator
  *
- * Copyright (C) 2011, 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
- * Contact: 
+ * Contact:
+ * Kitae Kim <kt920.kim@samsung.com>
  * SeokYeon Hwang <syeon.hwang@samsung.com>
  * MunKyu Im <munkyu.im@samsung.com>
  * GiWoong Kim <giwoong.kim@samsung.com>
  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- * HyunJun Son
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  *
  */
 
-#ifndef __OPTION_H__
-#define __OPTION_H__
+#import <Cocoa/Cocoa.h>
+#import <AppKit/NSEvent.h>
 
-#include <glib.h>
+#include "emul_state.h"
 
-#include <sys/types.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-int gethostDNS(char *dns1, char *dns2);
-int gethostproxy(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy);
-#endif
+/* retrieves the status of the host lock key */
+int get_host_lock_key_state_darwin(int key)
+{
+    /* support only capslock */
+    if (key == HOST_CAPSLOCK_KEY) {
+        return ((NSAlphaShiftKeyMask & [NSEvent modifierFlags]) ? 1 : 0);
+    } else if (key == HOST_NUMLOCK_KEY) {
+        return 0;
+    }
 
+    return -1;
+}
index c7f119e..c7abf6d 100644 (file)
 
 
 #include "maru_common.h"
-#include <stdlib.h>
-#ifdef CONFIG_SDL
-#include <SDL.h>
-#endif
 #include "emulator.h"
+#include "osutil.h"
 #include "guest_debug.h"
 #include "sdb.h"
 #include "string.h"
 #include "skin/maruskin_server.h"
 #include "skin/maruskin_client.h"
 #include "guest_server.h"
-#include "debug_ch.h"
-#include "option.h"
 #include "emul_state.h"
 #include "qemu_socket.h"
 #include "build_info.h"
 #include "maru_err_table.h"
-#include <glib.h>
-#include <glib/gstdio.h>
-
-#if defined(CONFIG_WIN32)
-#include <windows.h>
-#elif defined(CONFIG_LINUX)
-#include <linux/version.h>
-#include <sys/utsname.h>
-#include <sys/sysinfo.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#endif
+#include "maru_display.h"
+#include "qemu-config.h"
+#include "mloop_event.h"
+#include "hw/maru_camera_common.h"
+#include "hw/gloffscreen_test.h"
+#include "debug_ch.h"
 
-#if defined(CONFIG_DARWIN)
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include "tizen/src/ns_event.h"
+#include <stdlib.h>
+#ifdef CONFIG_SDL
+#include <SDL.h>
 #endif
 
-#include "mloop_event.h"
+#ifdef CONFIG_DARWIN
+#include "ns_event.h"
+#endif
 
 MULTI_DEBUG_CHANNEL(qemu, main);
 
@@ -85,12 +72,23 @@ MULTI_DEBUG_CHANNEL(qemu, main);
 #define LOGFILE             "emulator.log"
 #define LCD_WIDTH_PREFIX "width="
 #define LCD_HEIGHT_PREFIX "height="
+
 #define MIDBUF  128
 
+gchar bin_path[PATH_MAX] = { 0, };
+gchar log_path[PATH_MAX] = { 0, };
+
 int tizen_base_port;
-char tizen_target_path[MAXLEN];
-char tizen_target_img_path[MAXLEN];
-char logpath[MAXLEN];
+char tizen_target_path[PATH_MAX];
+char tizen_target_img_path[PATH_MAX];
+
+int enable_gl = 0;
+int enable_yagl = 0;
+
+int is_webcam_enabled;
+
+#define LEN_MARU_KERNEL_CMDLINE 512
+gchar maru_kernel_cmdline[LEN_MARU_KERNEL_CMDLINE];
 
 static int _skin_argc;
 static char **_skin_argv;
@@ -101,11 +99,9 @@ static char **_qemu_argv;
 int thread_running = 1; /* Check if we need exit main */
 #endif
 
-void maru_display_fini(void);
-
-char *get_logpath(void)
+const gchar *get_log_path(void)
 {
-    return logpath;
+    return log_path;
 }
 
 void exit_emulator(void)
@@ -117,157 +113,6 @@ void exit_emulator(void)
     maru_display_fini();
 }
 
-void check_shdmem(void)
-{
-#if defined(CONFIG_LINUX)
-    int shm_id;
-    void *shm_addr;
-    u_int port;
-    int val;
-    struct shmid_ds shm_info;
-
-    for (port = 26100; port < 26200; port += 10) {
-        shm_id = shmget((key_t)port, 0, 0);
-        if (shm_id != -1) {
-            shm_addr = shmat(shm_id, (void *)0, 0);
-            if ((void *)-1 == shm_addr) {
-                ERR("error occured at shmat()\n");
-                break;
-            }
-
-            val = shmctl(shm_id, IPC_STAT, &shm_info);
-            if (val != -1) {
-                INFO("count of process that use shared memory : %d\n",
-                    shm_info.shm_nattch);
-                if ((shm_info.shm_nattch > 0) &&
-                    strcmp(tizen_target_img_path, (char *)shm_addr) == 0) {
-                    if (check_port_bind_listen(port + 1) > 0) {
-                        shmdt(shm_addr);
-                        continue;
-                    }
-                    shmdt(shm_addr);
-                    maru_register_exit_msg(MARU_EXIT_UNKNOWN,
-                                        "Can not execute this VM.\n"
-                                        "The same name is running now.");
-                    exit(0);
-                } else {
-                    shmdt(shm_addr);
-                }
-            }
-        }
-    }
-
-#elif defined(CONFIG_WIN32)
-    u_int port;
-    char *base_port = NULL;
-    char *pBuf;
-    HANDLE hMapFile;
-    for (port = 26100; port < 26200; port += 10) {
-        base_port = g_strdup_printf("%d", port);
-        hMapFile = OpenFileMapping(FILE_MAP_READ, TRUE, base_port);
-        if (hMapFile == NULL) {
-            INFO("port %s is not used.\n", base_port);
-            continue;
-        } else {
-             pBuf = (char *)MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 50);
-            if (pBuf == NULL) {
-                ERR("Could not map view of file (%d).\n", GetLastError());
-                CloseHandle(hMapFile);
-            }
-
-            if (strcmp(pBuf, tizen_target_img_path) == 0) {
-                maru_register_exit_msg(MARU_EXIT_UNKNOWN,
-                    "Can not execute this VM.\n"
-                    "The same name is running now.");
-                UnmapViewOfFile(pBuf);
-                CloseHandle(hMapFile);
-                free(base_port);
-                exit(0);
-            } else {
-                UnmapViewOfFile(pBuf);
-            }
-        }
-
-        CloseHandle(hMapFile);
-        free(base_port);
-    }
-#elif defined(CONFIG_DARWIN)
-    /* TODO: */
-#endif
-}
-
-void make_shdmem(void)
-{
-#if defined(CONFIG_LINUX)
-    int shmid;
-    char *shared_memory;
-
-    shmid = shmget((key_t)tizen_base_port, MAXLEN, 0666|IPC_CREAT);
-    if (shmid == -1) {
-        ERR("shmget failed\n");
-        return;
-    }
-
-    shared_memory = shmat(shmid, (char *)0x00, 0);
-    if (shared_memory == (void *)-1) {
-        ERR("shmat failed\n");
-        return;
-    }
-    sprintf(shared_memory, "%s", tizen_target_img_path);
-    INFO("shared memory key: %d value: %s\n",
-        tizen_base_port, (char *)shared_memory);
-#elif defined(CONFIG_WIN32)
-    HANDLE hMapFile;
-    char *pBuf;
-    char *port_in_use;
-    char *shared_memory;
-
-    shared_memory = g_strdup_printf("%s", tizen_target_img_path);
-    port_in_use =  g_strdup_printf("%d", tizen_base_port);
-    hMapFile = CreateFileMapping(
-                 INVALID_HANDLE_VALUE, /* use paging file */
-                 NULL,                 /* default security */
-                 PAGE_READWRITE,       /* read/write access */
-                 0,                /* maximum object size (high-order DWORD) */
-                 50,               /* maximum object size (low-order DWORD) */
-                 port_in_use);         /* name of mapping object */
-    if (hMapFile == NULL) {
-        ERR("Could not create file mapping object (%d).\n", GetLastError());
-        return;
-    }
-    pBuf = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 50);
-
-    if (pBuf == NULL) {
-        ERR("Could not map view of file (%d).\n", GetLastError());
-        CloseHandle(hMapFile);
-        return;
-    }
-
-    CopyMemory((PVOID)pBuf, shared_memory, strlen(shared_memory));
-    free(port_in_use);
-    free(shared_memory);
-#elif defined(CONFIG_DARWIN)
-    /* TODO: */
-    int shmid;
-    char *shared_memory;
-
-    shmid = shmget((key_t)SHMKEY, MAXLEN, 0666|IPC_CREAT);
-    if (shmid == -1) {
-        ERR("shmget failed\n");
-        return;
-    }
-    shared_memory = shmat(shmid, (char *)0x00, 0);
-    if (shared_memory == (void *)-1) {
-        ERR("shmat failed\n");
-        return;
-    }
-    sprintf(shared_memory, "%d", get_sdb_base_port() + 2);
-    INFO("shared memory key: %d, value: %s\n", SHMKEY, (char *)shared_memory);
-    shmdt(shared_memory);
-#endif
-    return;
-}
-
 static void construct_main_window(int skin_argc, char *skin_argv[],
                                 int qemu_argc, char *qemu_argv[])
 {
@@ -319,77 +164,39 @@ static void parse_options(int argc, char *argv[], int *skin_argc,
     }
 }
 
-static char *set_bin_dir(char *exec_argv)
+static void get_host_proxy(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
 {
-#ifndef CONFIG_DARWIN
-    char link_path[1024] = { 0, };
-#endif
-    char *file_name = NULL;
-
-#if defined(CONFIG_WIN32)
-    if (!GetModuleFileName(NULL, link_path, 1024)) {
-        return NULL;
-    }
-
-    file_name = strrchr(link_path, '\\');
-    strncpy(bin_dir, link_path, strlen(link_path) - strlen(file_name));
-
-    strcat(bin_dir, "\\");
-
-#elif defined(CONFIG_LINUX)
-    ssize_t len = readlink("/proc/self/exe", link_path, sizeof(link_path) - 1);
-
-    if (len < 0 || len > sizeof(link_path)) {
-        perror("get_bin_dir error : ");
-        return NULL;
-    }
-
-    link_path[len] = '\0';
-
-    file_name = strrchr(link_path, '/');
-    strncpy(bin_dir, link_path, strlen(link_path) - strlen(file_name));
-
-    strcat(bin_dir, "/");
-
-#else
-    if (!exec_argv) {
-        return NULL;
-    }
-
-    char *data = strdup(exec_argv);
-    if (!data) {
-        fprintf(stderr, "Fail to strdup for paring a binary directory.\n");
-        return NULL;
-    }
-
-    file_name = strrchr(data, '/');
-    if (!file_name) {
-        free(data);
-        return NULL;
-    }
+    get_host_proxy_os(http_proxy, https_proxy, ftp_proxy, socks_proxy);
+}
 
-    strncpy(bin_dir, data, strlen(data) - strlen(file_name));
+static void set_bin_path(gchar * exec_argv)
+{
+    set_bin_path_os(exec_argv);
+}
 
-    strcat(bin_dir, "/");
-    free(data);
-#endif
+gchar * get_bin_path(void)
+{
+    return bin_path;
+}
 
-    return bin_dir;
+static void check_vm_lock(void)
+{
+    check_vm_lock_os();
 }
 
-char *get_bin_path(void)
+static void make_vm_lock(void)
 {
-    return bin_dir;
+    make_vm_lock_os();
 }
 
-void set_image_and_log_path(char *qemu_argv)
+static void set_image_and_log_path(char *qemu_argv)
 {
     int i, j = 0;
     int name_len = 0;
     int prefix_len = 0;
     int suffix_len = 0;
     int max = 0;
-    char *path = malloc(MAXLEN);
+    char *path = malloc(PATH_MAX);
     name_len = strlen(qemu_argv);
     prefix_len = strlen(IMAGE_PATH_PREFIX);
     suffix_len = strlen(IMAGE_PATH_SUFFIX);
@@ -403,33 +210,34 @@ void set_image_and_log_path(char *qemu_argv)
     } else {
         strcpy(tizen_target_path, g_path_get_dirname(path));
     }
+
     strcpy(tizen_target_img_path, path);
     free(path);
-    strcpy(logpath, tizen_target_path);
-    strcat(logpath, LOGS_SUFFIX);
+
+    strcpy(log_path, tizen_target_path);
+    strcat(log_path, LOGS_SUFFIX);
 #ifdef CONFIG_WIN32
-    if (access(g_win32_locale_filename_from_utf8(logpath), R_OK) != 0) {
-        g_mkdir(g_win32_locale_filename_from_utf8(logpath), 0755);
+    if (access(g_win32_locale_filename_from_utf8(log_path), R_OK) != 0) {
+        g_mkdir(g_win32_locale_filename_from_utf8(log_path), 0755);
     }
 #else
-    if (access(logpath, R_OK) != 0) {
-        g_mkdir(logpath, 0755);
+    if (access(log_path, R_OK) != 0) {
+        g_mkdir(log_path, 0755);
     }
 #endif
-    strcat(logpath, LOGFILE);
-    set_log_path(logpath);
+    strcat(log_path, LOGFILE);
 }
 
-void redir_output(void)
+static void redir_output(void)
 {
     FILE *fp;
 
-    fp = freopen(logpath, "a+", stdout);
+    fp = freopen(log_path, "a+", stdout);
     if (fp == NULL) {
         fprintf(stderr, "log file open error\n");
     }
 
-    fp = freopen(logpath, "a+", stderr);
+    fp = freopen(log_path, "a+", stderr);
     if (fp == NULL) {
         fprintf(stderr, "log file open error\n");
     }
@@ -437,7 +245,7 @@ void redir_output(void)
     setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
 }
 
-void extract_qemu_info(int qemu_argc, char **qemu_argv)
+static void extract_qemu_info(int qemu_argc, char **qemu_argv)
 {
     int i = 0;
 
@@ -450,7 +258,7 @@ void extract_qemu_info(int qemu_argc, char **qemu_argv)
 
 }
 
-void extract_skin_info(int skin_argc, char **skin_argv)
+static void extract_skin_info(int skin_argc, char **skin_argv)
 {
     int i = 0;
     int w = 0, h = 0;
@@ -476,7 +284,7 @@ void extract_skin_info(int skin_argc, char **skin_argv)
 }
 
 
-static void system_info(void)
+static void print_system_info(void)
 {
 #define DIV 1024
 
@@ -484,7 +292,7 @@ static void system_info(void)
     struct tm *tm_time;
     struct timeval tval;
 
-    INFO("* SDK Version : %s\n", build_version);
+    INFO("* Board name : %s\n", build_version);
     INFO("* Package %s\n", pkginfo_version);
     INFO("* Package %s\n", pkginfo_maintainer);
     INFO("* Git Head : %s\n", pkginfo_githead);
@@ -505,132 +313,168 @@ static void system_info(void)
         SDL_Linked_Version()->minor,
         SDL_Linked_Version()->patch);
 #endif
+    print_system_info_os();
+}
 
-#if defined(CONFIG_WIN32)
-    INFO("* Windows\n");
-
-    /* Retrieves information about the current os */
-    OSVERSIONINFO osvi;
-    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
-    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+typedef struct {
+    const char *device_name;
+    int found;
+} device_opt_finding_t;
 
-    if (GetVersionEx(&osvi)) {
-        INFO("* MajorVersion : %d, MinorVersion : %d, BuildNumber : %d, \
-            PlatformId : %d, CSDVersion : %s\n", osvi.dwMajorVersion,
-            osvi.dwMinorVersion, osvi.dwBuildNumber,
-            osvi.dwPlatformId, osvi.szCSDVersion);
+static int find_device_opt (QemuOpts *opts, void *opaque)
+{
+    device_opt_finding_t *devp = (device_opt_finding_t *) opaque;
+    if (devp->found == 1) {
+        return 0;
     }
 
-    /* Retrieves information about the current system */
-    SYSTEM_INFO sysi;
-    ZeroMemory(&sysi, sizeof(SYSTEM_INFO));
-
-    GetSystemInfo(&sysi);
-    INFO("* Processor type : %d, Number of processors : %d\n",
-            sysi.dwProcessorType, sysi.dwNumberOfProcessors);
-
-    MEMORYSTATUSEX memInfo;
-    memInfo.dwLength = sizeof(MEMORYSTATUSEX);
-    GlobalMemoryStatusEx(&memInfo);
-    INFO("* Total Ram : %llu kB, Free: %lld kB\n",
-            memInfo.ullTotalPhys / DIV, memInfo.ullAvailPhys / DIV);
-
-#elif defined(CONFIG_LINUX)
-    INFO("* Linux\n");
-
-    /* depends on building */
-    INFO("* QEMU build machine linux kernel version : (%d, %d, %d)\n",
-            LINUX_VERSION_CODE >> 16,
-            (LINUX_VERSION_CODE >> 8) & 0xff,
-            LINUX_VERSION_CODE & 0xff);
-
-     /* depends on launching */
-    struct utsname host_uname_buf;
-    if (uname(&host_uname_buf) == 0) {
-        INFO("* Host machine uname : %s %s %s %s %s\n",
-            host_uname_buf.sysname, host_uname_buf.nodename,
-            host_uname_buf.release, host_uname_buf.version,
-            host_uname_buf.machine);
+    const char *str = qemu_opt_get (opts, "driver");
+    if (strcmp (str, devp->device_name) == 0) {
+        devp->found = 1;
     }
+    return 0;
+}
 
-    struct sysinfo sys_info;
-    if (sysinfo(&sys_info) == 0) {
-        INFO("* Total Ram : %llu kB, Free: %llu kB\n",
-            sys_info.totalram * (unsigned long long)sys_info.mem_unit / DIV,
-            sys_info.freeram * (unsigned long long)sys_info.mem_unit / DIV);
-    }
+#define DEFAULT_QEMU_DNS_IP "10.0.2.3"
+static void prepare_basic_features(void)
+{
+    char http_proxy[MIDBUF] ={0}, https_proxy[MIDBUF] = {0,},
+        ftp_proxy[MIDBUF] = {0,}, socks_proxy[MIDBUF] = {0,},
+        dns[MIDBUF] = {0};
 
-    /* get linux distribution */
-    INFO("* Linux distribution infomation :\n");
-    char lsb_release_cmd[MAXLEN] = "lsb_release -d -r -c >> ";
-    strcat(lsb_release_cmd, logpath);
-    if(system(lsb_release_cmd) < 0) {
-        INFO("system function command '%s' \
-            returns error !", lsb_release_cmd);
-    }
+    tizen_base_port = get_sdb_base_port();
 
-    /* pci device description */
-    INFO("* PCI devices :\n");
-    char lspci_cmd[MAXLEN] = "lspci >> ";
-    strcat(lspci_cmd, logpath);
-    if(system(lspci_cmd) < 0) {
-        INFO("system function command '%s' \
-            returns error !", lspci_cmd);
-    }
+    get_host_proxy(http_proxy, https_proxy, ftp_proxy, socks_proxy);
+    /* using "DNS" provided by default QEMU */
+    g_strlcpy(dns, DEFAULT_QEMU_DNS_IP, strlen(DEFAULT_QEMU_DNS_IP) + 1);
+
+    check_vm_lock();
+    socket_init();
+    make_vm_lock();
+
+    sdb_setup(); /* determine the base port for emulator */
+    set_emul_vm_base_port(tizen_base_port);
 
-#elif defined(CONFIG_DARWIN)
-    INFO("* Mac\n");
+    gchar * const tmp_str = g_strdup_printf(" sdb_port=%d,"
+        " http_proxy=%s https_proxy=%s ftp_proxy=%s socks_proxy=%s"
+        " dns1=%s", get_emul_vm_base_port(),
+        http_proxy, https_proxy, ftp_proxy, socks_proxy, dns);
 
-    /* uname */
-    INFO("* Host machine uname :\n");
-    char uname_cmd[MAXLEN] = "uname -a >> ";
-    strcat(uname_cmd, logpath);
-    if(system(uname_cmd) < 0) {
-        INFO("system function command '%s' \
-            returns error !", uname_cmd);
+    g_strlcat(maru_kernel_cmdline, tmp_str, LEN_MARU_KERNEL_CMDLINE);
+
+    g_free(tmp_str);
+}
+
+#define VIRTIOGL_DEV_NAME "virtio-gl-pci"
+#ifdef CONFIG_GL_BACKEND
+static void prepare_opengl_acceleration(void)
+{
+    int capability_check_gl = 0;
+
+    if (enable_gl && enable_yagl) {
+        ERR("Error: only one openGL passthrough device can be used at one time!\n");
+        exit(1);
     }
 
-    /* hw information */
-    int mib[2];
-    size_t len;
-    char *sys_info;
-    int sys_num = 0;
-
-    mib[0] = CTL_HW;
-    mib[1] = HW_MODEL;
-    sysctl(mib, 2, NULL, &len, NULL, 0);
-    sys_info = malloc(len * sizeof(char));
-    if (sysctl(mib, 2, sys_info, &len, NULL, 0) >= 0) {
-        INFO("* Machine model : %s\n", sys_info);
+
+    if (enable_gl || enable_yagl) {
+        capability_check_gl = gl_acceleration_capability_check();
+
+        if (capability_check_gl != 0) {
+            enable_gl = enable_yagl = 0;
+            WARN("Warn: GL acceleration was disabled due to the fail of GL check!\n");
+        }
     }
-    free(sys_info);
-
-    mib[0] = CTL_HW;
-    mib[1] = HW_MACHINE;
-    sysctl(mib, 2, NULL, &len, NULL, 0);
-    sys_info = malloc(len * sizeof(char));
-    if (sysctl(mib, 2, sys_info, &len, NULL, 0) >= 0) {
-        INFO("* Machine class : %s\n", sys_info);
+    if (enable_gl) {
+        device_opt_finding_t devp = {VIRTIOGL_DEV_NAME, 0};
+        qemu_opts_foreach(qemu_find_opts("device"), find_device_opt, &devp, 0);
+        if (devp.found == 0) {
+            if (!qemu_opts_parse(qemu_find_opts("device"), VIRTIOGL_DEV_NAME, 1)) {
+                exit(1);
+            }
+        }
     }
-    free(sys_info);
 
-    mib[0] = CTL_HW;
-    mib[1] = HW_NCPU;
-    len = sizeof(sys_num);
-    if (sysctl(mib, 2, &sys_num, &len, NULL, 0) >= 0) {
-        INFO("* Number of processors : %d\n", sys_num);
-    }
+    gchar * const tmp_str = g_strdup_printf(" gles=%d yagl=%d", enable_gl, enable_yagl);
+
+    g_strlcat(maru_kernel_cmdline, tmp_str, LEN_MARU_KERNEL_CMDLINE);
+
+    g_free(tmp_str);
+}
+#endif
 
-    mib[0] = CTL_HW;
-    mib[1] = HW_PHYSMEM;
-    len = sizeof(sys_num);
-    if (sysctl(mib, 2, &sys_num, &len, NULL, 0) >= 0) {
-        INFO("* Total memory : %llu bytes\n", sys_num);
+#define MARUCAM_DEV_NAME "maru_camera_pci"
+#define WEBCAM_INFO_IGNORE 0x00
+#define WEBCAM_INFO_WRITE 0x04
+static void prepare_host_webcam(void)
+{
+    is_webcam_enabled = marucam_device_check(WEBCAM_INFO_WRITE);
+
+    if (!is_webcam_enabled) {
+        INFO("[Webcam] <WARNING> Webcam support was disabled "
+                         "due to the fail of webcam capability check!\n");
+    }
+    else {
+        device_opt_finding_t devp = {MARUCAM_DEV_NAME, 0};
+        qemu_opts_foreach(qemu_find_opts("device"), find_device_opt, &devp, 0);
+        if (devp.found == 0) {
+            if (!qemu_opts_parse(qemu_find_opts("device"), MARUCAM_DEV_NAME, 1)) {
+                INFO("Failed to initialize the marucam device.\n");
+                exit(1);
+            }
+        }
+        INFO("[Webcam] Webcam support was enabled.\n");
     }
 
+    gchar * const tmp_str = g_strdup_printf(" enable_cam=%d", is_webcam_enabled);
+
+    g_strlcat(maru_kernel_cmdline, tmp_str, LEN_MARU_KERNEL_CMDLINE);
+
+    g_free(tmp_str);
+}
+
+const gchar * prepare_maru_devices(const gchar *kernel_cmdline)
+{
+    INFO("Prepare maru specified kernel command line\n");
+
+    g_strlcpy(maru_kernel_cmdline, kernel_cmdline, LEN_MARU_KERNEL_CMDLINE);
+
+    // Prepare basic features
+    prepare_basic_features();
+
+    // Prepare GL acceleration
+#ifdef CONFIG_GL_BACKEND
+    prepare_opengl_acceleration();
 #endif
 
-    INFO("\n");
+    // Prepare host webcam
+    prepare_host_webcam();
+
+    INFO("kernel command : %s\n", maru_kernel_cmdline);
+
+    return maru_kernel_cmdline;
+}
+
+int maru_device_check(QemuOpts *opts)
+{
+#if defined(CONFIG_GL_BACKEND)
+    // virtio-gl pci device
+    if (!enable_gl) {
+        // ignore virtio-gl-pci device, even if users set it in option.
+        const char *driver = qemu_opt_get(opts, "driver");
+        if (driver && (strcmp (driver, VIRTIOGL_DEV_NAME) == 0)) {
+            return -1;
+        }
+    }
+#endif
+    if (!is_webcam_enabled) {
+        const char *driver = qemu_opt_get(opts, "driver");
+        if (driver && (strcmp (driver, MARUCAM_DEV_NAME) == 0)) {
+            return -1;
+        }
+    }
+
+    return 0;
 }
 
 void prepare_maru(void)
@@ -653,7 +497,7 @@ static int emulator_main(int argc, char *argv[])
 {
     parse_options(argc, argv, &_skin_argc,
                 &_skin_argv, &_qemu_argc, &_qemu_argv);
-    set_bin_dir(_qemu_argv[0]);
+    set_bin_path(_qemu_argv[0]);
     extract_qemu_info(_qemu_argc, _qemu_argv);
 
     INFO("Emulator start !!!\n");
@@ -661,7 +505,7 @@ static int emulator_main(int argc, char *argv[])
 
     extract_skin_info(_skin_argc, _skin_argv);
 
-    system_info();
+    print_system_info();
 
     INFO("Prepare running...\n");
     /* Redirect stdout and stderr after debug_ch is initialized. */
index f5e93d8..d487892 100644 (file)
 
 /**
  * @file emulator.h
- * @brief - header of file these are config struecture and defines in emulator
+ * @brief - header file for emulator.c
  */
 
 #ifndef __EMULATOR_H__
 #define __EMULATOR_H__
 
+#include "maru_common.h"
+#include "qlist.h"
+#include "qemu-option.h"
+
 #define MAXLEN  512
 #define MAXPACKETLEN 60
 #define SHMKEY 26099
 
+extern gchar bin_path[];
+extern gchar log_path[];
+
 void exit_emulator(void);
 char *get_bin_path(void);
-void set_image_and_log_path(char *qemu_argv);
-void redir_output(void);
-void extract_qemu_info(int qemu_argc, char **qemu_argv);
-void extract_skin_info(int skin_argc, char **skin_argv);
 void prepare_maru(void);
-void check_shdmem(void);
-void make_shdmem(void);
+
+const gchar * get_log_path(void);
+const gchar * prepare_maru_devices(const gchar * kernel_cmdline);
+int maru_device_check(QemuOpts *opts);
 #endif /* __EMULATOR_H__ */
index 1488343..4d7ad9e 100644 (file)
@@ -60,6 +60,10 @@ MAGIC_MACRO(glXGetDriverConfig),
 MAGIC_MACRO(glXSwapIntervalSGI),
 MAGIC_MACRO(glXCreatePixmap),
 MAGIC_MACRO(glXDestroyPixmap),
+MAGIC_MACRO(glXBindTexImageARB_fake),
+MAGIC_MACRO(glXReleaseTexImageARB_fake),
+MAGIC_MACRO(glXCreatePbuffer),
+MAGIC_MACRO(glXDestroyPbuffer),
 
 MAGIC_MACRO(glGetString),
 
index 806db14..11547c7 100644 (file)
@@ -83,8 +83,10 @@ extern void glo_context_destroy(GloContext *context);
 /* Update the context in surface and free previous light-weight context */
 extern void glo_surface_update_context(GloSurface *surface, GloContext *context, int free_flags);
 
-/* Link the pixmap associated with surface as texture */
-extern void glo_surface_as_texture(GloSurface *surface);
+/* Link the pixmap/pbuffer associated with surface as texture.
+ * ctxt is the target context for the texture operation
+ */
+extern void glo_surface_as_texture(GloContext *ctxt, GloSurface *surface);
 
 /* Create a surface with given width and height, */
 extern GloSurface *glo_surface_create(int width, int height, GloContext *context);
diff --git a/tizen/src/hw/gloffscreen_agl.c b/tizen/src/hw/gloffscreen_agl.c
new file mode 100644 (file)
index 0000000..0d61423
--- /dev/null
@@ -0,0 +1,363 @@
+/*Offscreen OpenGL abstraction layer - AGL specific 
+* 
+*  Copyright (c) 2010 Intel Corporation 
+* 
+* Permission is hereby granted, free of charge, to any person obtaining a copy 
+* of this software and associated documentation files (the "Software"), to deal 
+* in the Software without restriction, including without limitation the rights 
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
+* copies of the Software, and to permit persons to whom the Software is 
+* furnished to do so, subject to the following conditions: 
+* 
+* The above copyright notice and this permission notice shall be included in 
+* all copies or substantial portions of the Software. 
+* 
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
+* THE SOFTWARE. 
+*/ 
+#ifdef __APPLE__ 
+  
+#include <stdlib.h> 
+#include <stdio.h> 
+#include <string.h> 
+#include <inttypes.h>
+#include <dlfcn.h>
+/*hack due to conflicting typedefs in qemu's softfloat.h*/
+#define __SECURITYHI__ 1
+  
+#include <OpenGL/OpenGL.h> 
+#include <AGL/agl.h> 
+#include "gloffscreen.h" 
+#ifdef GL_DEBUG 
+#define TRACE(fmt, ...) printf("%s@%d: " fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__) 
+#else 
+#define TRACE(...) 
+#endif 
+struct _GloContext 
+{ 
+     GLuint         formatFlags; 
+     AGLPixelFormat pixelFormat; 
+     AGLContext     context; 
+ }; 
+  
+struct _GloSurface 
+{ 
+     GLuint     width; 
+     GLuint     height;   
+     GloContext *context; 
+     AGLPbuffer pbuffer; 
+ }; 
+  
+extern void glo_surface_getcontents_readpixels(int formatFlags, int stride, 
+                                                int bpp, int width, int height, 
+                                                void *data); 
+
+
+  
+/* Initialise gloffscreen */ 
+int glo_init(void) 
+{
+       int major, minor;
+       aglGetVersion(&major, &minor);
+       fprintf(stdout, "%s----AGL version %d.%d\n",__FUNCTION__,  major, minor);
+       return 0;
+ } 
+  
+/* Uninitialise gloffscreen */ 
+void glo_kill(void) 
+{ 
+} 
+const char *glo_glXQueryExtensionsString(void) 
+{ 
+     return ""; 
+ } 
+  
+/* Like wglGetProcAddress/glxGetProcAddress */ 
+ void *glo_getprocaddress(const char *procName) 
+ { 
+    void *ret = NULL;
+
+    if (procName) 
+    {
+         if (!strncmp(procName, "glX", 3))
+             ret = (void *)1;
+         else 
+            ret = dlsym(RTLD_NEXT, procName);
+     }
+
+#if 0//standard code for mac to look up procaddress, but seems slow that above.
+       NSSymbol symbol;
+       char *symbolname;
+       symbolname = malloc(strlen(procName) +2);
+       strcpy(symbolname +1, procName);
+       symbolname[0] = '_';
+       symbol = NULL;
+       if(NSIsSymbolNameDefined(symbolname))
+               symbol = NSLookupAndBindSymbol(symbolname);
+       free(symbolname);
+       ret = symbol ? NSAddressOfSymbol (symbol) : NULL;
+#endif    
+    TRACE("'%s' --> %p", procName, ret); 
+    return ret; 
+} 
+/* Create an OpenGL context for a certain pixel format. 
+* formatflags are from the GLO_ constants 
+*/
+
+GloContext *__glo_context_create(int formatFlags)
+{
+       int rgba[4];
+       glo_flags_get_rgba_bits(formatFlags, rgba);
+       const int attribs[] = {
+        AGL_RGBA,
+        AGL_MINIMUM_POLICY,
+        AGL_PIXEL_SIZE, glo_flags_get_bytes_per_pixel(formatFlags) * 8,
+        AGL_RED_SIZE, rgba[0],
+        AGL_GREEN_SIZE, rgba[1],
+        AGL_BLUE_SIZE, rgba[2],
+        AGL_ALPHA_SIZE, rgba[3],
+        AGL_DEPTH_SIZE, glo_flags_get_depth_bits(formatFlags),
+        AGL_STENCIL_SIZE, glo_flags_get_stencil_bits(formatFlags),
+        AGL_ACCELERATED,
+        AGL_NO_RECOVERY,
+        AGL_NONE
+    };
+
+    TRACE("req %dbpp %d-%d-%d-%d depth %d stencil %d",
+          glo_flags_get_bytes_per_pixel(formatFlags) * 8,
+          rgba[0], rgba[1], rgba[2], rgba[3],
+          glo_flags_get_depth_bits(formatFlags),
+          glo_flags_get_stencil_bits(formatFlags));
+
+       AGLPixelFormat pf = aglChoosePixelFormat(NULL, 0, attribs);
+    if (pf == NULL)
+        fprintf(stderr, "No matching pixelformat found.");
+    else 
+    {
+        GLint bpp = 0, a = 0, d = 0, s = 0;
+        aglDescribePixelFormat(pf, AGL_PIXEL_SIZE, &bpp);
+        aglDescribePixelFormat(pf, AGL_ALPHA_SIZE, &a);
+        aglDescribePixelFormat(pf, AGL_DEPTH_SIZE, &d);
+        aglDescribePixelFormat(pf, AGL_STENCIL_SIZE, &s);
+
+        formatFlags &= ~(GLO_FF_ALPHA_MASK | GLO_FF_BITS_MASK | GLO_FF_DEPTH_MASK | GLO_FF_STENCIL_MASK);
+        switch (bpp) {
+           case 16: formatFlags |= GLO_FF_BITS_16; break;
+            case 24: formatFlags |= GLO_FF_BITS_24; break;
+            case 32: formatFlags |= GLO_FF_BITS_32; break;
+            default: fprintf(stderr, "got unsupported bpp %d", bpp); break;
+     }
+
+         if (a > 0) 
+       {
+            formatFlags |= GLO_FF_ALPHA;
+        }
+
+        switch (d) {
+            case 0: break;
+            case 16: formatFlags |= GLO_FF_DEPTH_16; break;
+            case 24: formatFlags |= GLO_FF_DEPTH_24; break;
+            case 32: formatFlags |= GLO_FF_DEPTH_32; break;
+            default: fprintf(stderr, "got unsupported depth %d", d); break;
+        }
+
+        switch (s) {
+            case 0: break;
+             case 8: formatFlags |= GLO_FF_STENCIL_8; break;
+            default: fprintf(stderr, "got unsupported stencil %d", s); break;
+         }
+     }
+    GloContext *context = (GloContext *)g_malloc(sizeof(*context));
+    memset(context, 0, sizeof(*context));
+    context->formatFlags = formatFlags;
+    context->pixelFormat = pf;
+
+    return context;
+
+}
+GloContext *glo_context_create(int formatFlags, GloContext *shareLists) 
+{ 
+       GloContext *context = __glo_context_create(formatFlags);
+       if(!context)
+               return NULL;
+
+       context->context = aglCreateContext(context->pixelFormat, shareLists ? shareLists->context : NULL); 
+       if (context->context == NULL) 
+       { 
+               fprintf(stderr, "aglCreateContext failed: %s", aglErrorString(aglGetError())); 
+       } 
+
+       else
+       {
+               if(context->pixelFormat != NULL)
+               {
+                       aglDestroyPixelFormat(context->pixelFormat);
+                       context->pixelFormat = NULL;    
+               }
+       }
+
+       TRACE("context=%p", context); 
+       return context; 
+} 
+  
+/* Destroy a previously created OpenGL context */ 
+void glo_context_destroy(GloContext *context) 
+{ 
+       TRACE("context=%p", context); 
+       if (context) 
+       { 
+               aglDestroyContext(context->context);
+               if(context->pixelFormat != NULL)
+               { 
+                       aglDestroyPixelFormat(context->pixelFormat);
+                       context->pixelFormat = NULL; 
+               }
+               context->context = NULL;  
+               g_free(context); 
+       } 
+}
+
+void glo_surface_update_context(GloSurface *surface, GloContext *context, int free_flags)
+{
+    if ( surface->context )
+    {
+               if ( free_flags) /* light-weight context */
+            g_free(surface->context);
+    }
+    surface->context = context;
+}
+
+  
+/* Create a surface with given width and height, formatflags are from the 
+  * GLO_ constants */ 
+GloSurface *glo_surface_create(int width, int height, GloContext *context) 
+{ 
+     GloSurface *surface = NULL; 
+     if (context) 
+     { 
+         surface = (GloSurface *)g_malloc(sizeof(*surface)); 
+         memset(surface, 0, sizeof(*surface)); 
+         surface->width = width; 
+         surface->height = height; 
+         surface->context = context; 
+        TRACE("%dx%d", surface->width, surface->height); 
+       if (aglCreatePBuffer(width, height, GL_TEXTURE_2D, GL_RGBA, 0, &surface->pbuffer) == GL_FALSE)
+                  fprintf(stderr, "aglCreatePbuffer failed: %s", aglErrorString(aglGetError())); 
+
+    } 
+    TRACE("surface=%p", surface); 
+    return surface; 
+} 
+/* Destroy the given surface */ 
+void glo_surface_destroy(GloSurface *surface) 
+{ 
+    TRACE("surface=%p", surface); 
+    if (surface) 
+    { 
+       aglDestroyPBuffer(surface->pbuffer); 
+       surface->pbuffer = NULL; 
+       g_free(surface); 
+    } 
+} 
+/* Make the given surface current */ 
+int glo_surface_makecurrent(GloSurface *surface) 
+{ 
+    int ret = GL_FALSE; 
+    TRACE("surface=%p", surface); 
+    if (surface) 
+   { 
+        if (aglSetPBuffer(surface->context->context, surface->pbuffer, 0, 0, 0) == GL_FALSE)
+             fprintf(stderr, "aglSetPbuffer failed: %s", aglErrorString(aglGetError())); 
+        ret = aglSetCurrentContext(surface->context->context); 
+   } else 
+   { 
+        ret = aglSetCurrentContext(NULL); 
+    } 
+
+    if (ret == GL_FALSE)
+           fprintf(stderr, "aglSetCurrentContext failed: %s",  aglErrorString(aglGetError())); 
+    
+     TRACE("Return ret=%d\n", ret);
+     return ret; 
+ } 
+
+void glo_surface_updatecontents(GloSurface *surface)
+{
+       const GLint swap_interval = 1;
+
+       if(!surface)
+               return;
+       aglSwapBuffers(surface->context->context);
+        aglSetInteger(surface->context->context, AGL_SWAP_INTERVAL, &swap_interval);
+}
+
+/* Get the contents of the given surface */ 
+void glo_surface_getcontents(GloSurface *surface, int stride, int bpp, 
+                             void *data) 
+{
+     const GLint swap_interval = 1; 
+     if (surface)
+     { 
+        aglSwapBuffers(surface->context->context);     
+       aglSetInteger(surface->context->context, AGL_SWAP_INTERVAL, &swap_interval);
+        glo_surface_getcontents_readpixels(surface->context->formatFlags, stride, bpp, surface->width, surface->height, data); 
+    } 
+} 
+  
+/* Return the width and height of the given surface */ 
+void glo_surface_get_size(GloSurface *surface, int *width, int *height) 
+{ 
+    if (width)
+    { 
+         *width = surface->width; 
+    } 
+
+    if (height)
+    { 
+        *height = surface->height; 
+    } 
+} 
+/* Bind the surface as texture */
+void glo_surface_as_texture(GloContext *ctxt, GloSurface *surface)
+{
+#if 0
+       //Not QUit sure about this function;
+       int glFormat, glType;
+       glo_surface_updatecontents(surface);
+       /*XXX: changet the fixed target: GL_TEXTURE_2D*/
+       glo_flags_get_readpixel_type(surface->context->formatFlags, &glFormat, &glType);
+    fprintf(stderr, "surface_as_texture:teximage:width=%d,height=%d, glFormat=0x%x, glType=0x%x.\n", surface->width, surface->height, glFormat, glType);
+    /* glTexImage2D use different RGB order than the contexts in the pixmap surface */
+/*    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surface->width, surface->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->image->data);*/
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surface->width, surface->height, 0, glFormat, glType, surface->pbuffer);
+#else
+       if (aglTexImagePBuffer(ctxt->context, surface->pbuffer, GL_BACK) == GL_FALSE)
+               fprintf(stderr, "aglTexImagePBuffer failed: %s", aglErrorString(aglGetError())); 
+
+#endif
+}
+
+void glo_surface_release_texture(GloSurface *surface)
+{
+
+}
+#endif 
+
index d5b65b9..2799421 100644 (file)
@@ -24,7 +24,7 @@
  * THE SOFTWARE.
  */
 
-#include "gloffscreen.h"
+#include "gloffscreen_test.h"
 
 #include <stdlib.h>
 #include <stdio.h>
diff --git a/tizen/src/hw/gloffscreen_test.h b/tizen/src/hw/gloffscreen_test.h
new file mode 100644 (file)
index 0000000..4527043
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ *  Offscreen OpenGL abstraction layer
+ *
+ *  Copyright (c) 2010 Intel Corporation
+ *  Written by: 
+ *    Gordon Williams <gordon.williams@collabora.co.uk>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef __GLOFFSCREEN_TEST_H__
+#define __GLOFFSCREEN_TEST_H__
+
+#include "gloffscreen.h"
+
+int gl_acceleration_capability_check(void);
+
+#endif /* __GLOFFSCREEN_TEST_H__ */
index a72e9be..15f22fe 100644 (file)
@@ -659,6 +659,9 @@ static const char *STANDARD_GL_FUNCTIONS ={
 "glXGetVisualFromFBConfig\0"
 "glXIsDirect\0"
 "glXCreatePixmap\0"
+"glXDestroyPixmap\0"
+"glXCreatePbuffer\n"
+"glXDestroyPbuffer\n"
 "\0"
 };
 
@@ -964,7 +967,7 @@ void glo_surface_get_size(GloSurface *surface, int *width, int *height) {
 }
 
 /* Bind the surface as texture */
-void glo_surface_as_texture(GloSurface *surface)
+void glo_surface_as_texture(GloContext *ctxt, GloSurface *surface)
 {
 #if 0
     int glFormat, glType;
index 85550ed..6162d72 100644 (file)
@@ -479,7 +479,7 @@ void glo_surface_get_size(GloSurface *surface, int *width, int *height) {
 }
 
 /* Bind the surface as texture */
-void glo_surface_as_texture(GloSurface *surface)
+void glo_surface_as_texture(GloContext *ctxt, GloSurface *surface)
 {
 #if 0
     void (*ptr_func_glXBindTexImageEXT) (Display *dpy, GLXDrawable draw, int buffer, int *attrib_list);
index 4b0f233..a170dba 100644 (file)
@@ -1,17 +1,10 @@
 /*
  * Maru brightness device for VGA
  *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Contact:
- * SeokYeon Hwang <syeon.hwang@samsung.com>
- * SangJin Kim <sangjin3.kim@samsung.com>
- * MunKyu Im <munkyu.im@samsung.com>
- * KiTae Kim <kt920.kim@samsung.com>
  * JinHyung Jo <jinhyung.jo@samsung.com>
- * SungMin Ha <sungmin82.ha@samsung.com>
- * JiHye Kim <jihye1128.kim@samsung.com>
- * GiWoong Kim <giwoong.kim@samsung.com>
  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
  * DongKyun Yun
  * DoHyung Hong
@@ -29,7 +22,8 @@
  *
  * 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.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
  *
  * Contributors:
  * - S-Core Co., Ltd
@@ -44,6 +38,7 @@
 #include "pci.h"
 #include "maru_device_ids.h"
 #include "maru_brightness.h"
+#include "skin/maruskin_server.h"
 #include "debug_ch.h"
 
 MULTI_DEBUG_CHANNEL(qemu, maru_brightness);
@@ -81,6 +76,8 @@ uint8_t brightness_tbl[] = {100, /* level 0 : for dimming */
 /* level 81 ~ 90 */         226, 228, 229, 231, 232, 234, 235, 237, 238, 240,
 /* level 91 ~ 99 */         241, 243, 244, 246, 247, 249, 250, 252, 253};
 
+QEMUBH *bh;
+
 static uint64_t brightness_reg_read(void *opaque,
                                     target_phys_addr_t addr,
                                     unsigned size)
@@ -123,10 +120,19 @@ static void brightness_reg_write(void *opaque,
         return;
     case BRIGHTNESS_OFF:
         INFO("brightness_off : %lld\n", val);
+        if (brightness_off == val) {
+            return;
+        }
+
         brightness_off = val;
+
 #ifdef TARGET_ARM
         vga_hw_invalidate();
 #endif
+
+        /* notify to skin process */
+        qemu_bh_schedule(bh);
+
         return;
     default:
         ERR("wrong brightness register write - addr : %d\n", (int)addr);
@@ -140,6 +146,22 @@ static const MemoryRegionOps brightness_mmio_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
+static void brightness_exitfn(PCIDevice *dev)
+{
+    if (bh) {
+        qemu_bh_delete(bh);
+    }
+}
+
+static void maru_brightness_bh(void *opaque)
+{
+    if (brightness_off == 0) {
+        notify_brightness(TRUE);
+    } else {
+        notify_brightness(FALSE);
+    }
+}
+
 static int brightness_initfn(PCIDevice *dev)
 {
     BrightnessState *s = DO_UPCAST(BrightnessState, dev, dev);
@@ -153,15 +175,12 @@ static int brightness_initfn(PCIDevice *dev)
                             "maru_brightness_mmio", BRIGHTNESS_REG_SIZE);
     pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio_addr);
 
+    bh = qemu_bh_new(maru_brightness_bh, s);
+
     return 0;
 }
 
 /* external interface */
-int pci_get_brightness(void)
-{
-    return brightness_level;
-}
-
 DeviceState *pci_maru_brightness_init(PCIBus *bus)
 {
     return &pci_create_simple(bus, -1, QEMU_DEV_NAME)->qdev;
@@ -173,6 +192,7 @@ static void brightness_classinit(ObjectClass *klass, void *data)
 
     k->no_hotplug = 1;
     k->init = brightness_initfn;
+    k->exit = brightness_exitfn;
 }
 
 static TypeInfo brightness_info = {
index eebaa5d..98787c3 100644 (file)
@@ -1,9 +1,10 @@
 /*
  * Maru brightness device for VGA
  *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Contact:
+ * Jinhyung Jo <jinhyung.jo@samsung.com>
  * GiWoong Kim <giwoong.kim@samsung.com>
  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
  * Hyunjun Son
@@ -20,7 +21,8 @@
  *
  * 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.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
  *
  * Contributors:
  * - S-Core Co., Ltd
@@ -39,7 +41,6 @@ extern uint32_t brightness_level;
 extern uint32_t brightness_off;
 extern uint8_t brightness_tbl[];
 
-int pci_get_brightness(void);
 DeviceState *pci_maru_brightness_init(PCIBus *bus);
 
 #endif /* MARU_BRIGHTNESS_H_ */
index 8020308..9d914ad 100644 (file)
-/*\r
- * Common header of MARU Virtual Camera device.\r
- *\r
- * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Contact:\r
- * JinHyung Jo <jinhyung.jo@samsung.com>\r
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
- *\r
- * Contributors:\r
- * - S-Core Co., Ltd\r
- *\r
- */\r
-\r
-#ifndef _MARU_CAMERA_COMMON_H_\r
-#define _MARU_CAMERA_COMMON_H_\r
-\r
-#include "pci.h"\r
-#include "qemu-thread.h"\r
-\r
-#define MARUCAM_MAX_PARAM    20\r
-#define MARUCAM_SKIPFRAMES    2\r
-\r
-/* must sync with GUEST camera_driver */\r
-#define MARUCAM_CMD_INIT           0x00\r
-#define MARUCAM_CMD_OPEN           0x04\r
-#define MARUCAM_CMD_CLOSE          0x08\r
-#define MARUCAM_CMD_ISR            0x0C\r
-#define MARUCAM_CMD_START_PREVIEW  0x10\r
-#define MARUCAM_CMD_STOP_PREVIEW   0x14\r
-#define MARUCAM_CMD_S_PARAM        0x18\r
-#define MARUCAM_CMD_G_PARAM        0x1C\r
-#define MARUCAM_CMD_ENUM_FMT       0x20\r
-#define MARUCAM_CMD_TRY_FMT        0x24\r
-#define MARUCAM_CMD_S_FMT          0x28\r
-#define MARUCAM_CMD_G_FMT          0x2C\r
-#define MARUCAM_CMD_QCTRL          0x30\r
-#define MARUCAM_CMD_S_CTRL         0x34\r
-#define MARUCAM_CMD_G_CTRL         0x38\r
-#define MARUCAM_CMD_ENUM_FSIZES    0x3C\r
-#define MARUCAM_CMD_ENUM_FINTV     0x40\r
-#define MARUCAM_CMD_S_DATA         0x44\r
-#define MARUCAM_CMD_G_DATA         0x48\r
-#define MARUCAM_CMD_DATACLR        0x50\r
-#define MARUCAM_CMD_REQFRAME       0x54\r
-\r
-typedef struct MaruCamState MaruCamState;\r
-typedef struct MaruCamParam MaruCamParam;\r
-\r
-struct MaruCamParam {\r
-    uint32_t    top;\r
-    uint32_t    retVal;\r
-    uint32_t    errCode;\r
-    uint32_t    stack[MARUCAM_MAX_PARAM];\r
-};\r
-\r
-struct MaruCamState {\r
-    PCIDevice           dev;\r
-    MaruCamParam        *param;\r
-    QemuThread          thread_id;\r
-    QemuMutex           thread_mutex;;\r
-    QemuCond            thread_cond;\r
-    QEMUBH              *tx_bh;\r
-\r
-    bool                destroying;\r
-    void                *vaddr;     /* vram ptr */\r
-    uint32_t            isr;\r
-    uint32_t            streamon;\r
-    uint32_t            buf_size;\r
-    uint32_t            req_frame;\r
-\r
-    MemoryRegion        vram;\r
-    MemoryRegion        mmio;\r
-};\r
-\r
-/* ------------------------------------------------------------------------- */\r
-/* Fucntion prototype                                                        */\r
-/* ------------------------------------------------------------------------- */\r
-int marucam_device_check(int log_flag);\r
-void marucam_device_init(MaruCamState *state);\r
-void marucam_device_exit(MaruCamState *state);\r
-void marucam_device_open(MaruCamState *state);\r
-void marucam_device_close(MaruCamState *state);\r
-void marucam_device_start_preview(MaruCamState *state);\r
-void marucam_device_stop_preview(MaruCamState *state);\r
-void marucam_device_s_param(MaruCamState *state);\r
-void marucam_device_g_param(MaruCamState *state);\r
-void marucam_device_s_fmt(MaruCamState *state);\r
-void marucam_device_g_fmt(MaruCamState *state);\r
-void marucam_device_try_fmt(MaruCamState *state);\r
-void marucam_device_enum_fmt(MaruCamState *state);\r
-void marucam_device_qctrl(MaruCamState *state);\r
-void marucam_device_s_ctrl(MaruCamState *state);\r
-void marucam_device_g_ctrl(MaruCamState *state);\r
-void marucam_device_enum_fsizes(MaruCamState *state);\r
-void marucam_device_enum_fintv(MaruCamState *state);\r
-\r
-int maru_camera_pci_init(PCIBus *bus);\r
-\r
-#endif  /* _MARU_CAMERA_COMMON_H_ */\r
+/*
+ * Common header of MARU Virtual Camera device.
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * 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 _MARU_CAMERA_COMMON_H_
+#define _MARU_CAMERA_COMMON_H_
+
+#include "pci.h"
+#include "qemu-thread.h"
+
+#define MARUCAM_MAX_PARAM    20
+#define MARUCAM_SKIPFRAMES    2
+
+/* must sync with GUEST camera_driver */
+#define MARUCAM_CMD_INIT           0x00
+#define MARUCAM_CMD_OPEN           0x04
+#define MARUCAM_CMD_CLOSE          0x08
+#define MARUCAM_CMD_ISR            0x0C
+#define MARUCAM_CMD_START_PREVIEW  0x10
+#define MARUCAM_CMD_STOP_PREVIEW   0x14
+#define MARUCAM_CMD_S_PARAM        0x18
+#define MARUCAM_CMD_G_PARAM        0x1C
+#define MARUCAM_CMD_ENUM_FMT       0x20
+#define MARUCAM_CMD_TRY_FMT        0x24
+#define MARUCAM_CMD_S_FMT          0x28
+#define MARUCAM_CMD_G_FMT          0x2C
+#define MARUCAM_CMD_QCTRL          0x30
+#define MARUCAM_CMD_S_CTRL         0x34
+#define MARUCAM_CMD_G_CTRL         0x38
+#define MARUCAM_CMD_ENUM_FSIZES    0x3C
+#define MARUCAM_CMD_ENUM_FINTV     0x40
+#define MARUCAM_CMD_S_DATA         0x44
+#define MARUCAM_CMD_G_DATA         0x48
+#define MARUCAM_CMD_DATACLR        0x50
+#define MARUCAM_CMD_REQFRAME       0x54
+
+typedef struct MaruCamState MaruCamState;
+typedef struct MaruCamParam MaruCamParam;
+
+struct MaruCamParam {
+    uint32_t    top;
+    uint32_t    retVal;
+    uint32_t    errCode;
+    uint32_t    stack[MARUCAM_MAX_PARAM];
+};
+
+struct MaruCamState {
+    PCIDevice           dev;
+    MaruCamParam        *param;
+    QemuThread          thread_id;
+    QemuMutex           thread_mutex;;
+    QemuCond            thread_cond;
+    QEMUBH              *tx_bh;
+
+    bool                destroying;
+    void                *vaddr;     /* vram ptr */
+    uint32_t            isr;
+    uint32_t            streamon;
+    uint32_t            buf_size;
+    uint32_t            req_frame;
+
+    MemoryRegion        vram;
+    MemoryRegion        mmio;
+};
+
+/* ------------------------------------------------------------------------- */
+/* Fucntion prototype                                                        */
+/* ------------------------------------------------------------------------- */
+int marucam_device_check(int log_flag);
+void marucam_device_init(MaruCamState *state);
+void marucam_device_exit(MaruCamState *state);
+void marucam_device_open(MaruCamState *state);
+void marucam_device_close(MaruCamState *state);
+void marucam_device_start_preview(MaruCamState *state);
+void marucam_device_stop_preview(MaruCamState *state);
+void marucam_device_s_param(MaruCamState *state);
+void marucam_device_g_param(MaruCamState *state);
+void marucam_device_s_fmt(MaruCamState *state);
+void marucam_device_g_fmt(MaruCamState *state);
+void marucam_device_try_fmt(MaruCamState *state);
+void marucam_device_enum_fmt(MaruCamState *state);
+void marucam_device_qctrl(MaruCamState *state);
+void marucam_device_s_ctrl(MaruCamState *state);
+void marucam_device_g_ctrl(MaruCamState *state);
+void marucam_device_enum_fsizes(MaruCamState *state);
+void marucam_device_enum_fintv(MaruCamState *state);
+
+int maru_camera_pci_init(PCIBus *bus);
+
+#endif  /* _MARU_CAMERA_COMMON_H_ */
index 42d853a..1dd20cc 100644 (file)
-/*\r
- * Common implementation of MARU Virtual Camera device by PCI bus.\r
- *\r
- * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Contact:\r
- * JinHyung Jo <jinhyung.jo@samsung.com>\r
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
- *\r
- * Contributors:\r
- * - S-Core Co., Ltd\r
- *\r
- */\r
-\r
-\r
-#include <stdarg.h>\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include <inttypes.h>\r
-#include <signal.h>\r
-\r
-#include "qemu-common.h"\r
-#include "cpu-common.h"\r
-\r
-#include "pci.h"\r
-#include "pci_ids.h"\r
-#include "maru_device_ids.h"\r
-\r
-#include "maru_camera_common.h"\r
-#include "tizen/src/debug_ch.h"\r
-\r
-MULTI_DEBUG_CHANNEL(tizen, camera_pci);\r
-\r
-#define MARU_PCI_CAMERA_DEVICE_NAME     "maru_camera_pci"\r
-\r
-#define MARUCAM_MEM_SIZE    (4 * 1024 * 1024)   /* 4MB */\r
-#define MARUCAM_REG_SIZE    (256)               /* 64 * 4Byte */\r
-\r
-/*\r
- *  I/O functions\r
- */\r
-static inline uint32_t\r
-marucam_mmio_read(void *opaque, target_phys_addr_t offset)\r
-{\r
-    uint32_t ret = 0;\r
-    MaruCamState *state = (MaruCamState*)opaque;\r
-\r
-    switch (offset & 0xFF) {\r
-    case MARUCAM_CMD_ISR:\r
-        qemu_mutex_lock(&state->thread_mutex);\r
-        ret = state->isr;\r
-        if (ret != 0) {\r
-            qemu_irq_lower(state->dev.irq[2]);\r
-            state->isr = 0;\r
-        }\r
-        qemu_mutex_unlock(&state->thread_mutex);\r
-        break;\r
-    case MARUCAM_CMD_G_DATA:\r
-        ret = state->param->stack[state->param->top++];\r
-        break;\r
-    case MARUCAM_CMD_OPEN:\r
-    case MARUCAM_CMD_CLOSE:\r
-    case MARUCAM_CMD_START_PREVIEW:\r
-    case MARUCAM_CMD_STOP_PREVIEW:\r
-    case MARUCAM_CMD_S_PARAM:\r
-    case MARUCAM_CMD_G_PARAM:\r
-    case MARUCAM_CMD_ENUM_FMT:\r
-    case MARUCAM_CMD_TRY_FMT:\r
-    case MARUCAM_CMD_S_FMT:\r
-    case MARUCAM_CMD_G_FMT:\r
-    case MARUCAM_CMD_QCTRL:\r
-    case MARUCAM_CMD_S_CTRL:\r
-    case MARUCAM_CMD_G_CTRL:\r
-    case MARUCAM_CMD_ENUM_FSIZES:\r
-    case MARUCAM_CMD_ENUM_FINTV:\r
-        ret = state->param->errCode;\r
-        state->param->errCode = 0;\r
-        break;\r
-    default:\r
-        ERR("Not supported command: 0x%x\n", offset);\r
-        ret = EINVAL;\r
-        break;\r
-    }\r
-    return ret;\r
-}\r
-\r
-static inline void\r
-marucam_mmio_write(void *opaque, target_phys_addr_t offset, uint32_t value)\r
-{\r
-    MaruCamState *state = (MaruCamState*)opaque;\r
-    \r
-    switch(offset & 0xFF) {\r
-    case MARUCAM_CMD_OPEN:\r
-        marucam_device_open(state);\r
-        break;\r
-    case MARUCAM_CMD_CLOSE:\r
-        marucam_device_close(state);\r
-        break;\r
-    case MARUCAM_CMD_START_PREVIEW:\r
-        marucam_device_start_preview(state);\r
-        break;\r
-    case MARUCAM_CMD_STOP_PREVIEW:\r
-        marucam_device_stop_preview(state);\r
-        memset(state->vaddr, 0, MARUCAM_MEM_SIZE);\r
-        break;\r
-    case MARUCAM_CMD_S_PARAM:\r
-        marucam_device_s_param(state);\r
-        break;\r
-    case MARUCAM_CMD_G_PARAM:\r
-        marucam_device_g_param(state);\r
-        break;\r
-    case MARUCAM_CMD_ENUM_FMT:\r
-        marucam_device_enum_fmt(state);\r
-        break;\r
-    case MARUCAM_CMD_TRY_FMT:\r
-        marucam_device_try_fmt(state);\r
-        break;\r
-    case MARUCAM_CMD_S_FMT:\r
-        marucam_device_s_fmt(state);\r
-        break;\r
-    case MARUCAM_CMD_G_FMT:\r
-        marucam_device_g_fmt(state);\r
-        break;\r
-    case MARUCAM_CMD_QCTRL:\r
-        marucam_device_qctrl(state);\r
-        break;\r
-    case MARUCAM_CMD_S_CTRL:\r
-        marucam_device_s_ctrl(state);\r
-        break;\r
-    case MARUCAM_CMD_G_CTRL:\r
-        marucam_device_g_ctrl(state);\r
-        break;\r
-    case MARUCAM_CMD_ENUM_FSIZES:\r
-        marucam_device_enum_fsizes(state);\r
-        break;\r
-    case MARUCAM_CMD_ENUM_FINTV:\r
-        marucam_device_enum_fintv(state);\r
-        break;\r
-    case MARUCAM_CMD_S_DATA:\r
-        state->param->stack[state->param->top++] = value;\r
-        break;\r
-    case MARUCAM_CMD_DATACLR:\r
-        memset(state->param, 0, sizeof(MaruCamParam));\r
-        break;\r
-    case MARUCAM_CMD_REQFRAME:\r
-        qemu_mutex_lock(&state->thread_mutex);\r
-        state->req_frame = value + 1;\r
-        qemu_mutex_unlock(&state->thread_mutex);\r
-        break;\r
-    default:\r
-        ERR("Not supported command: 0x%x\n", offset);\r
-        break;\r
-    }\r
-}\r
-\r
-static const MemoryRegionOps maru_camera_mmio_ops = {\r
-    .old_mmio = {\r
-        .read = {\r
-            marucam_mmio_read,\r
-            marucam_mmio_read,\r
-            marucam_mmio_read,\r
-        },\r
-        .write = {\r
-            marucam_mmio_write,\r
-            marucam_mmio_write,\r
-            marucam_mmio_write,\r
-        },\r
-    },\r
-    .endianness = DEVICE_LITTLE_ENDIAN,\r
-};\r
-\r
-/*\r
- *  QEMU bottom half funtion\r
- */\r
-static void marucam_tx_bh(void *opaque)\r
-{\r
-    MaruCamState *state = (MaruCamState *)opaque;\r
-\r
-    qemu_mutex_lock(&state->thread_mutex);\r
-    if (state->isr) {\r
-        qemu_irq_raise(state->dev.irq[2]);\r
-    }\r
-    qemu_mutex_unlock(&state->thread_mutex);\r
-}\r
-\r
-/*\r
- *  Initialization function\r
- */\r
-static int marucam_initfn(PCIDevice *dev)\r
-{\r
-    MaruCamState *s = DO_UPCAST(MaruCamState, dev, dev);\r
-    uint8_t *pci_conf = s->dev.config;\r
-\r
-    pci_config_set_interrupt_pin(pci_conf, 0x03);\r
-\r
-    memory_region_init_ram(&s->vram, "marucamera.ram", MARUCAM_MEM_SIZE);\r
-    s->vaddr = memory_region_get_ram_ptr(&s->vram);\r
-    memset(s->vaddr, 0, MARUCAM_MEM_SIZE);\r
-\r
-    memory_region_init_io (&s->mmio, &maru_camera_mmio_ops, s,\r
-            "maru-camera-mmio", MARUCAM_REG_SIZE);\r
-    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);\r
-    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);\r
-\r
-    /* for worker thread */\r
-    s->param = (MaruCamParam*)g_malloc0(sizeof(MaruCamParam));\r
-    qemu_cond_init(&s->thread_cond);\r
-    qemu_mutex_init(&s->thread_mutex);\r
-\r
-    marucam_device_init(s);\r
-\r
-    s->tx_bh = qemu_bh_new(marucam_tx_bh, s);\r
-    INFO("[%s] camera device was initialized.\n", __func__);\r
-\r
-    return 0;\r
-}\r
-\r
-/*\r
- *  Termination function\r
- */\r
-static void marucam_exitfn(PCIDevice *pci_dev)\r
-{\r
-    MaruCamState *s =\r
-        OBJECT_CHECK(MaruCamState, pci_dev, MARU_PCI_CAMERA_DEVICE_NAME);\r
-\r
-    marucam_device_exit(s);\r
-    g_free(s->param);\r
-    qemu_cond_destroy(&s->thread_cond);\r
-    qemu_mutex_destroy(&s->thread_mutex);\r
-\r
-    memory_region_destroy(&s->vram);\r
-    memory_region_destroy(&s->mmio);\r
-\r
-\r
-    INFO("[%s] camera device was released.\n", __func__);\r
-}\r
-\r
-int maru_camera_pci_init(PCIBus *bus)\r
-{\r
-    INFO("[%s] camera device was initialized.\n", __func__);\r
-    pci_create_simple(bus, -1, MARU_PCI_CAMERA_DEVICE_NAME);\r
-    return 0;\r
-}\r
-\r
-static void maru_camera_pci_class_init(ObjectClass *klass, void *data)\r
-{\r
-    DeviceClass *dc = DEVICE_CLASS(klass);\r
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);\r
-\r
-    k->no_hotplug = 1;\r
-    k->init = marucam_initfn;\r
-    k->exit = marucam_exitfn;\r
-    k->vendor_id = PCI_VENDOR_ID_TIZEN;\r
-    k->device_id = PCI_DEVICE_ID_VIRTUAL_CAMERA;\r
-    k->class_id = PCI_CLASS_OTHERS;\r
-    dc->desc = "MARU Virtual Camera device for Tizen emulator";\r
-}\r
-\r
-static TypeInfo maru_camera_info = {\r
-    .name          = MARU_PCI_CAMERA_DEVICE_NAME,\r
-    .parent        = TYPE_PCI_DEVICE,\r
-    .instance_size = sizeof(MaruCamState),\r
-    .class_init    = maru_camera_pci_class_init,\r
-};\r
-\r
-static void maru_camera_pci_register_types(void)\r
-{\r
-    type_register_static(&maru_camera_info);\r
-}\r
-\r
-type_init(maru_camera_pci_register_types)\r
+/*
+ * Common implementation of MARU Virtual Camera device by PCI bus.
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * 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 <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <signal.h>
+
+#include "qemu-common.h"
+#include "cpu-common.h"
+
+#include "pci.h"
+#include "pci_ids.h"
+#include "maru_device_ids.h"
+
+#include "maru_camera_common.h"
+#include "tizen/src/debug_ch.h"
+
+MULTI_DEBUG_CHANNEL(tizen, camera_pci);
+
+#define MARU_PCI_CAMERA_DEVICE_NAME     "maru_camera_pci"
+
+#define MARUCAM_MEM_SIZE    (4 * 1024 * 1024)   /* 4MB */
+#define MARUCAM_REG_SIZE    (256)               /* 64 * 4Byte */
+
+/*
+ *  I/O functions
+ */
+static inline uint32_t
+marucam_mmio_read(void *opaque, target_phys_addr_t offset)
+{
+    uint32_t ret = 0;
+    MaruCamState *state = (MaruCamState *)opaque;
+
+    switch (offset & 0xFF) {
+    case MARUCAM_CMD_ISR:
+        qemu_mutex_lock(&state->thread_mutex);
+        ret = state->isr;
+        if (ret != 0) {
+            qemu_irq_lower(state->dev.irq[2]);
+            state->isr = 0;
+        }
+        qemu_mutex_unlock(&state->thread_mutex);
+        break;
+    case MARUCAM_CMD_G_DATA:
+        ret = state->param->stack[state->param->top++];
+        break;
+    case MARUCAM_CMD_OPEN:
+    case MARUCAM_CMD_CLOSE:
+    case MARUCAM_CMD_START_PREVIEW:
+    case MARUCAM_CMD_STOP_PREVIEW:
+    case MARUCAM_CMD_S_PARAM:
+    case MARUCAM_CMD_G_PARAM:
+    case MARUCAM_CMD_ENUM_FMT:
+    case MARUCAM_CMD_TRY_FMT:
+    case MARUCAM_CMD_S_FMT:
+    case MARUCAM_CMD_G_FMT:
+    case MARUCAM_CMD_QCTRL:
+    case MARUCAM_CMD_S_CTRL:
+    case MARUCAM_CMD_G_CTRL:
+    case MARUCAM_CMD_ENUM_FSIZES:
+    case MARUCAM_CMD_ENUM_FINTV:
+        ret = state->param->errCode;
+        state->param->errCode = 0;
+        break;
+    default:
+        ERR("Not supported command: 0x%x\n", offset);
+        ret = EINVAL;
+        break;
+    }
+    return ret;
+}
+
+static inline void
+marucam_mmio_write(void *opaque, target_phys_addr_t offset, uint32_t value)
+{
+    MaruCamState *state = (MaruCamState *)opaque;
+
+    switch (offset & 0xFF) {
+    case MARUCAM_CMD_OPEN:
+        marucam_device_open(state);
+        break;
+    case MARUCAM_CMD_CLOSE:
+        marucam_device_close(state);
+        break;
+    case MARUCAM_CMD_START_PREVIEW:
+        marucam_device_start_preview(state);
+        break;
+    case MARUCAM_CMD_STOP_PREVIEW:
+        marucam_device_stop_preview(state);
+        memset(state->vaddr, 0, MARUCAM_MEM_SIZE);
+        break;
+    case MARUCAM_CMD_S_PARAM:
+        marucam_device_s_param(state);
+        break;
+    case MARUCAM_CMD_G_PARAM:
+        marucam_device_g_param(state);
+        break;
+    case MARUCAM_CMD_ENUM_FMT:
+        marucam_device_enum_fmt(state);
+        break;
+    case MARUCAM_CMD_TRY_FMT:
+        marucam_device_try_fmt(state);
+        break;
+    case MARUCAM_CMD_S_FMT:
+        marucam_device_s_fmt(state);
+        break;
+    case MARUCAM_CMD_G_FMT:
+        marucam_device_g_fmt(state);
+        break;
+    case MARUCAM_CMD_QCTRL:
+        marucam_device_qctrl(state);
+        break;
+    case MARUCAM_CMD_S_CTRL:
+        marucam_device_s_ctrl(state);
+        break;
+    case MARUCAM_CMD_G_CTRL:
+        marucam_device_g_ctrl(state);
+        break;
+    case MARUCAM_CMD_ENUM_FSIZES:
+        marucam_device_enum_fsizes(state);
+        break;
+    case MARUCAM_CMD_ENUM_FINTV:
+        marucam_device_enum_fintv(state);
+        break;
+    case MARUCAM_CMD_S_DATA:
+        state->param->stack[state->param->top++] = value;
+        break;
+    case MARUCAM_CMD_DATACLR:
+        memset(state->param, 0, sizeof(MaruCamParam));
+        break;
+    case MARUCAM_CMD_REQFRAME:
+        qemu_mutex_lock(&state->thread_mutex);
+        state->req_frame = value + 1;
+        qemu_mutex_unlock(&state->thread_mutex);
+        break;
+    default:
+        ERR("Not supported command: 0x%x\n", offset);
+        break;
+    }
+}
+
+static const MemoryRegionOps maru_camera_mmio_ops = {
+    .old_mmio = {
+        .read = {
+            marucam_mmio_read,
+            marucam_mmio_read,
+            marucam_mmio_read,
+        },
+        .write = {
+            marucam_mmio_write,
+            marucam_mmio_write,
+            marucam_mmio_write,
+        },
+    },
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+/*
+ *  QEMU bottom half funtion
+ */
+static void marucam_tx_bh(void *opaque)
+{
+    MaruCamState *state = (MaruCamState *)opaque;
+
+    qemu_mutex_lock(&state->thread_mutex);
+    if (state->isr) {
+        qemu_irq_raise(state->dev.irq[2]);
+    }
+    qemu_mutex_unlock(&state->thread_mutex);
+}
+
+/*
+ *  Initialization function
+ */
+static int marucam_initfn(PCIDevice *dev)
+{
+    MaruCamState *s = DO_UPCAST(MaruCamState, dev, dev);
+    uint8_t *pci_conf = s->dev.config;
+
+    pci_config_set_interrupt_pin(pci_conf, 0x03);
+
+    memory_region_init_ram(&s->vram, "marucamera.ram", MARUCAM_MEM_SIZE);
+    s->vaddr = memory_region_get_ram_ptr(&s->vram);
+    memset(s->vaddr, 0, MARUCAM_MEM_SIZE);
+
+    memory_region_init_io(&s->mmio,
+                          &maru_camera_mmio_ops,
+                          s,
+                          "maru-camera-mmio",
+                          MARUCAM_REG_SIZE);
+
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
+    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);
+
+    /* for worker thread */
+    s->param = (MaruCamParam *)g_malloc0(sizeof(MaruCamParam));
+    qemu_cond_init(&s->thread_cond);
+    qemu_mutex_init(&s->thread_mutex);
+
+    marucam_device_init(s);
+
+    s->tx_bh = qemu_bh_new(marucam_tx_bh, s);
+    INFO("[%s] camera device was initialized.\n", __func__);
+
+    return 0;
+}
+
+/*
+ *  Termination function
+ */
+static void marucam_exitfn(PCIDevice *pci_dev)
+{
+    MaruCamState *s =
+        OBJECT_CHECK(MaruCamState, pci_dev, MARU_PCI_CAMERA_DEVICE_NAME);
+
+    marucam_device_exit(s);
+    g_free(s->param);
+    qemu_cond_destroy(&s->thread_cond);
+    qemu_mutex_destroy(&s->thread_mutex);
+
+    memory_region_destroy(&s->vram);
+    memory_region_destroy(&s->mmio);
+
+
+    INFO("[%s] camera device was released.\n", __func__);
+}
+
+int maru_camera_pci_init(PCIBus *bus)
+{
+    INFO("[%s] camera device was initialized.\n", __func__);
+    pci_create_simple(bus, -1, MARU_PCI_CAMERA_DEVICE_NAME);
+    return 0;
+}
+
+static void maru_camera_pci_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = marucam_initfn;
+    k->exit = marucam_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_TIZEN;
+    k->device_id = PCI_DEVICE_ID_VIRTUAL_CAMERA;
+    k->class_id = PCI_CLASS_OTHERS;
+    dc->desc = "MARU Virtual Camera device for Tizen emulator";
+}
+
+static TypeInfo maru_camera_info = {
+    .name          = MARU_PCI_CAMERA_DEVICE_NAME,
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(MaruCamState),
+    .class_init    = maru_camera_pci_class_init,
+};
+
+static void maru_camera_pci_register_types(void)
+{
+    type_register_static(&maru_camera_info);
+}
+
+type_init(maru_camera_pci_register_types)
index 25e4807..2ac39f9 100644 (file)
@@ -1,4 +1,13 @@
 /*
+ * Header of MARU Virtual Camera device for MacOS.
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * Jun Tian <jun.j.tian@intel.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
  * 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.
+ * MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
  *
  */
 
 #ifndef _MARU_CAMERA_DARWIN_H_
 #define _MARU_CAMERA_DARWIN_H_
 
-#define MAKEFOURCC(a,b,c,d)\
-    (((uint32_t)(a)<<0)|((uint32_t)(b)<<8)|((uint32_t)(c)<<16)|((uint32_t)(d)<<24))
+#define MAKEFOURCC(a, b, c, d) \
+    (((uint32_t)(a) << 0) | \
+     ((uint32_t)(b) << 8) | \
+     ((uint32_t)(c) << 16) | \
+     ((uint32_t)(d) << 24))
 
-/*      Pixel format         FOURCC                        depth  Description  */
-#define V4L2_PIX_FMT_RGB555  MAKEFOURCC('R','G','B','O') /* 16  RGB-5-5-5     */
-#define V4L2_PIX_FMT_RGB565  MAKEFOURCC('R','G','B','P') /* 16  RGB-5-6-5     */
-#define V4L2_PIX_FMT_RGB555X MAKEFOURCC('R','G','B','Q') /* 16  RGB-5-5-5 BE  */
-#define V4L2_PIX_FMT_RGB565X MAKEFOURCC('R','G','B','R') /* 16  RGB-5-6-5 BE  */
-#define V4L2_PIX_FMT_BGR24   MAKEFOURCC('B','G','R','3') /* 24  BGR-8-8-8     */
-#define V4L2_PIX_FMT_RGB24   MAKEFOURCC('R','G','B','3') /* 24  RGB-8-8-8     */
-#define V4L2_PIX_FMT_BGR32   MAKEFOURCC('B','G','R','4') /* 32  BGR-8-8-8-8   */
-#define V4L2_PIX_FMT_RGB32   MAKEFOURCC('R','G','B','4') /* 32  RGB-8-8-8-8   */
-#define V4L2_PIX_FMT_YVU410  MAKEFOURCC('Y','V','U','9') /*  9  YVU 4:1:0     */
-#define V4L2_PIX_FMT_YVU420  MAKEFOURCC('Y','V','1','2') /* 12  YVU 4:2:0     */
-#define V4L2_PIX_FMT_YUYV    MAKEFOURCC('Y','U','Y','V') /* 16  YUV 4:2:2     */
-#define V4L2_PIX_FMT_UYVY    MAKEFOURCC('U','Y','V','Y') /* 16  YUV 4:2:2     */
-#define V4L2_PIX_FMT_YUV422P MAKEFOURCC('4','2','2','P') /* 16  YVU422 planar */
-#define V4L2_PIX_FMT_YUV411P MAKEFOURCC('4','1','1','P') /* 16  YVU411 planar */
-#define V4L2_PIX_FMT_Y41P    MAKEFOURCC('Y','4','1','P') /* 12  YUV 4:1:1     */
-#define V4L2_PIX_FMT_YUV444  MAKEFOURCC('Y','4','4','4') /* 16  xxxxyyyy uuuuvvvv */
-#define V4L2_PIX_FMT_YUV555  MAKEFOURCC('Y','U','V','O') /* 16  YUV-5-5-5     */
-#define V4L2_PIX_FMT_YUV565  MAKEFOURCC('Y','U','V','P') /* 16  YUV-5-6-5     */
-#define V4L2_PIX_FMT_YUV32   MAKEFOURCC('Y','U','V','4') /* 32  YUV-8-8-8-8   */
-#define V4L2_PIX_FMT_YUV410  MAKEFOURCC('Y','U','V','9') /*  9  YUV 4:1:0     */
-#define V4L2_PIX_FMT_YUV420  MAKEFOURCC('Y','U','1','2') /* 12  YUV 4:2:0     */
-#define V4L2_PIX_FMT_YYUV    MAKEFOURCC('Y','Y','U','V') /* 16  YUV 4:2:2     */
+/* 16  RGB-5-5-5     */
+#define V4L2_PIX_FMT_RGB555  MAKEFOURCC('R', 'G', 'B', 'O')
+/* 16  RGB-5-6-5     */
+#define V4L2_PIX_FMT_RGB565  MAKEFOURCC('R', 'G', 'B', 'P')
+/* 16  RGB-5-5-5 BE  */
+#define V4L2_PIX_FMT_RGB555X MAKEFOURCC('R', 'G', 'B', 'Q')
+/* 16  RGB-5-6-5 BE  */
+#define V4L2_PIX_FMT_RGB565X MAKEFOURCC('R', 'G', 'B', 'R')
+/* 24  BGR-8-8-8     */
+#define V4L2_PIX_FMT_BGR24   MAKEFOURCC('B', 'G', 'R', '3')
+/* 24  RGB-8-8-8     */
+#define V4L2_PIX_FMT_RGB24   MAKEFOURCC('R', 'G', 'B', '3')
+/* 32  BGR-8-8-8-8   */
+#define V4L2_PIX_FMT_BGR32   MAKEFOURCC('B', 'G', 'R', '4')
+/* 32  RGB-8-8-8-8   */
+#define V4L2_PIX_FMT_RGB32   MAKEFOURCC('R', 'G', 'B', '4')
+/*  9  YVU 4:1:0     */
+#define V4L2_PIX_FMT_YVU410  MAKEFOURCC('Y', 'V', 'U', '9')
+/* 12  YVU 4:2:0     */
+#define V4L2_PIX_FMT_YVU420  MAKEFOURCC('Y', 'V', '1', '2')
+/* 16  YUV 4:2:2     */
+#define V4L2_PIX_FMT_YUYV    MAKEFOURCC('Y', 'U', 'Y', 'V')
+/* 16  YUV 4:2:2     */
+#define V4L2_PIX_FMT_UYVY    MAKEFOURCC('U', 'Y', 'V', 'Y')
+/* 16  YVU422 planar */
+#define V4L2_PIX_FMT_YUV422P MAKEFOURCC('4', '2', '2', 'P')
+/* 16  YVU411 planar */
+#define V4L2_PIX_FMT_YUV411P MAKEFOURCC('4', '1', '1', 'P')
+/* 12  YUV 4:1:1     */
+#define V4L2_PIX_FMT_Y41P    MAKEFOURCC('Y', '4', '1', 'P')
+/* 16  xxxxyyyy uuuuvvvv */
+#define V4L2_PIX_FMT_YUV444  MAKEFOURCC('Y', '4', '4', '4')
+/* 16  YUV-5-5-5     */
+#define V4L2_PIX_FMT_YUV555  MAKEFOURCC('Y', 'U', 'V', 'O')
+/* 16  YUV-5-6-5     */
+#define V4L2_PIX_FMT_YUV565  MAKEFOURCC('Y', 'U', 'V', 'P')
+/* 32  YUV-8-8-8-8   */
+#define V4L2_PIX_FMT_YUV32   MAKEFOURCC('Y', 'U', 'V', '4')
+/*  9  YUV 4:1:0     */
+#define V4L2_PIX_FMT_YUV410  MAKEFOURCC('Y', 'U', 'V', '9')
+/* 12  YUV 4:2:0     */
+#define V4L2_PIX_FMT_YUV420  MAKEFOURCC('Y', 'U', '1', '2')
+/* 16  YUV 4:2:2     */
+#define V4L2_PIX_FMT_YYUV    MAKEFOURCC('Y', 'Y', 'U', 'V')
 
 void convert_frame(uint32_t pixel_format, int frame_width, int frame_height,
-                   size_t frame_size, void* frame_pixels, void* video_buf);
+                   size_t frame_size, void *frame_pixels, void *video_buf);
 
 #endif /* _MARU_CAMERA_DARWIN_H_ */
index 817e705..7105e66 100644 (file)
@@ -1,4 +1,13 @@
 /*
+ * Implementation of color conversion for MARU Virtual Camera device on MacOS.
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * Jun Tian <jun.j.tian@intel.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
  * 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.
+ * MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
  *
  */
 
index 336ef3b..d8d3a2f 100644 (file)
@@ -1,12 +1,12 @@
 /*
- * Implementation of MARU Virtual Camera device by PCI bus on Linux.
+ * Implementation of MARU Virtual Camera device by PCI bus on MacOS.
  *
- * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Contact:
+ * Jun Tian <jun.j.tian@intel.com>
  * JinHyung Jo <jinhyung.jo@samsung.com>
  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- * Jun Tian <jun.j.tian@intel.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -20,7 +20,8 @@
  *
  * 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.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
  *
  * Contributors:
  * - S-Core Co., Ltd
@@ -635,7 +636,7 @@ void marucam_device_stop_preview(MaruCamState *state)
             usleep(10000);
         }
     }
-    
+
     if (mcd->driver != nil) {
         [mcd->driver stopCapture];
     }
index 7cd0394..be5dc6c 100644 (file)
-/*\r
- * Implementation of MARU Virtual Camera device by PCI bus on Linux.\r
- *\r
- * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Contact:\r
- * JinHyung Jo <jinhyung.jo@samsung.com>\r
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
- *\r
- * Contributors:\r
- * - S-Core Co., Ltd\r
- *\r
- */\r
-\r
-#include "qemu-common.h"\r
-#include "maru_camera_common.h"\r
-#include "pci.h"\r
-#include "kvm.h"\r
-#include "tizen/src/debug_ch.h"\r
-\r
-#include <linux/videodev2.h>\r
-\r
-#include <sys/stat.h>\r
-#include <sys/ioctl.h>\r
-#include <sys/mman.h>\r
-\r
-#include <libv4l2.h>\r
-#include <libv4lconvert.h>\r
-\r
-MULTI_DEBUG_CHANNEL(tizen, camera_linux);\r
-\r
-#define CLEAR(x) memset(&(x), 0, sizeof(x))\r
-\r
-#define MARUCAM_DEFAULT_BUFFER_COUNT    4\r
-\r
-#define MARUCAM_CTRL_VALUE_MAX      20\r
-#define MARUCAM_CTRL_VALUE_MIN      1\r
-#define MARUCAM_CTRL_VALUE_MID      10\r
-#define MARUCAM_CTRL_VALUE_STEP     1\r
-\r
-enum {\r
-    _MC_THREAD_PAUSED,\r
-    _MC_THREAD_STREAMON,\r
-    _MC_THREAD_STREAMOFF,\r
-};\r
-\r
-typedef struct marucam_framebuffer {\r
-    void *data;\r
-    size_t size;\r
-} marucam_framebuffer;\r
-\r
-static int n_framebuffer;\r
-static struct marucam_framebuffer *framebuffer;\r
-\r
-static const char *dev_name = "/dev/video0";\r
-static int v4l2_fd;\r
-static int convert_trial;\r
-static int ready_count;\r
-\r
-static struct v4l2_format dst_fmt;\r
-\r
-static int yioctl(int fd, int req, void *arg)\r
-{\r
-    int r;\r
-\r
-    do {\r
-        r = ioctl(fd, req, arg);\r
-    } while (r < 0 && errno == EINTR);\r
-\r
-    return r;\r
-}\r
-\r
-static int xioctl(int fd, int req, void *arg)\r
-{\r
-    int r;\r
-\r
-    do {\r
-        r = v4l2_ioctl(fd, req, arg);\r
-    } while (r < 0 && errno == EINTR);\r
-\r
-    return r;\r
-}\r
-\r
-typedef struct tagMaruCamConvertPixfmt {\r
-    uint32_t fmt;   /* fourcc */\r
-} MaruCamConvertPixfmt;\r
-\r
-static MaruCamConvertPixfmt supported_dst_pixfmts[] = {\r
-        { V4L2_PIX_FMT_YUYV },\r
-        { V4L2_PIX_FMT_YUV420 },\r
-        { V4L2_PIX_FMT_YVU420 },\r
-};\r
-\r
-typedef struct tagMaruCamConvertFrameInfo {\r
-    uint32_t width;\r
-    uint32_t height;\r
-} MaruCamConvertFrameInfo;\r
-\r
-static MaruCamConvertFrameInfo supported_dst_frames[] = {\r
-        { 640, 480 },\r
-        { 352, 288 },\r
-        { 320, 240 },\r
-        { 176, 144 },\r
-        { 160, 120 },\r
-};\r
-\r
-struct marucam_qctrl {\r
-    uint32_t id;\r
-    uint32_t hit;\r
-    int32_t min;\r
-    int32_t max;\r
-    int32_t step;\r
-    int32_t init_val;\r
-};\r
-\r
-static struct marucam_qctrl qctrl_tbl[] = {\r
-    { V4L2_CID_BRIGHTNESS, 0, },\r
-    { V4L2_CID_CONTRAST, 0, },\r
-    { V4L2_CID_SATURATION, 0, },\r
-    { V4L2_CID_SHARPNESS, 0, },\r
-};\r
-\r
-static void marucam_reset_controls(void)\r
-{\r
-    uint32_t i;\r
-    for (i = 0; i < ARRAY_SIZE(qctrl_tbl); i++) {\r
-        if (qctrl_tbl[i].hit) {\r
-            struct v4l2_control ctrl = {0,};\r
-            qctrl_tbl[i].hit = 0;\r
-            ctrl.id = qctrl_tbl[i].id;\r
-            ctrl.value = qctrl_tbl[i].init_val;\r
-            if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &ctrl) < 0) {\r
-                ERR("Failed to reset control value: id(0x%x), errstr(%s)\n",\r
-                    ctrl.id, strerror(errno));\r
-            }\r
-        }\r
-    }\r
-}\r
-\r
-static int32_t value_convert_from_guest(int32_t min, int32_t max, int32_t value)\r
-{\r
-    double rate = 0.0;\r
-    int32_t dist = 0, ret = 0;\r
-\r
-    dist = max - min;\r
-\r
-    if (dist < MARUCAM_CTRL_VALUE_MAX) {\r
-        rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;\r
-        ret = min + (int32_t)(value / rate);\r
-    } else {\r
-        rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;\r
-        ret = min + (int32_t)(rate * value);\r
-    }\r
-    return ret;\r
-}\r
-\r
-static int32_t value_convert_to_guest(int32_t min, int32_t max, int32_t value)\r
-{\r
-    double rate  = 0.0;\r
-    int32_t dist = 0, ret = 0;\r
-\r
-    dist = max - min;\r
-\r
-    if (dist < MARUCAM_CTRL_VALUE_MAX) {\r
-        rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;\r
-        ret = (int32_t)((double)(value - min) * rate);\r
-    } else {\r
-        rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;\r
-        ret = (int32_t)((double)(value - min) / rate);\r
-    }\r
-\r
-    return ret;\r
-}\r
-\r
-static void set_maxframeinterval(MaruCamState *state, uint32_t pixel_format,\r
-                        uint32_t width, uint32_t height)\r
-{\r
-    struct v4l2_frmivalenum fival;\r
-    struct v4l2_streamparm sp;\r
-    uint32_t min_num = 0, min_denom = 0;\r
-\r
-    CLEAR(fival);\r
-    fival.pixel_format = pixel_format;\r
-    fival.width = width;\r
-    fival.height = height;\r
-\r
-    if (xioctl(v4l2_fd, VIDIOC_ENUM_FRAMEINTERVALS, &fival) < 0) {\r
-        ERR("Unable to enumerate intervals for pixelformat(0x%x), (%d:%d)\n",\r
-            pixel_format, width, height);\r
-        return;\r
-    }\r
-\r
-    if (fival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {\r
-        float max_ival = -1.0;\r
-        do {\r
-            float cur_ival = (float)fival.discrete.numerator\r
-                        / (float)fival.discrete.denominator;\r
-            if (cur_ival > max_ival) {\r
-                max_ival = cur_ival;\r
-                min_num = fival.discrete.numerator;\r
-                min_denom = fival.discrete.denominator;\r
-            }\r
-            TRACE("Discrete frame interval %u/%u supported\n",\r
-                 fival.discrete.numerator, fival.discrete.denominator);\r
-            fival.index++;\r
-        } while (xioctl(v4l2_fd, VIDIOC_ENUM_FRAMEINTERVALS, &fival) >= 0);\r
-    } else if ((fival.type == V4L2_FRMIVAL_TYPE_STEPWISE) ||\r
-                (fival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS)) {\r
-        TRACE("Frame intervals from %u/%u to %u/%u supported",\r
-            fival.stepwise.min.numerator, fival.stepwise.min.denominator,\r
-            fival.stepwise.max.numerator, fival.stepwise.max.denominator);\r
-        if (fival.type == V4L2_FRMIVAL_TYPE_STEPWISE) {\r
-            TRACE("with %u/%u step", fival.stepwise.step.numerator,\r
-                  fival.stepwise.step.denominator);\r
-        }\r
-        if (((float)fival.stepwise.max.denominator /\r
-             (float)fival.stepwise.max.numerator) >\r
-            ((float)fival.stepwise.min.denominator /\r
-             (float)fival.stepwise.min.numerator)) {\r
-            min_num = fival.stepwise.max.numerator;\r
-            min_denom = fival.stepwise.max.denominator;\r
-        } else {\r
-            min_num = fival.stepwise.min.numerator;\r
-            min_denom = fival.stepwise.min.denominator;\r
-        }\r
-    }\r
-    TRACE("The actual min values: %u/%u\n", min_num, min_denom);\r
-\r
-    CLEAR(sp);\r
-    sp.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
-    sp.parm.capture.timeperframe.numerator = min_num;\r
-    sp.parm.capture.timeperframe.denominator = min_denom;\r
-\r
-    if (xioctl(v4l2_fd, VIDIOC_S_PARM, &sp) < 0) {\r
-        ERR("Failed to set to minimum FPS(%u/%u)\n", min_num, min_denom);\r
-    }\r
-}\r
-\r
-static uint32_t stop_capturing(void)\r
-{\r
-    enum v4l2_buf_type type;\r
-\r
-    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
-    if (xioctl(v4l2_fd, VIDIOC_STREAMOFF, &type) < 0) {\r
-        ERR("Failed to ioctl() with VIDIOC_STREAMOFF: %s\n", strerror(errno));\r
-        return errno;\r
-    }\r
-    return 0;\r
-}\r
-\r
-static uint32_t start_capturing(void)\r
-{\r
-    enum v4l2_buf_type type;\r
-\r
-    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
-    if (xioctl(v4l2_fd, VIDIOC_STREAMON, &type) < 0) {\r
-        ERR("Failed to ioctl() with VIDIOC_STREAMON: %s\n", strerror(errno));\r
-        return errno;\r
-    }\r
-    return 0;\r
-}\r
-\r
-static void free_framebuffers(marucam_framebuffer *fb, int buf_num)\r
-{\r
-    int i;\r
-\r
-    if (fb == NULL) {\r
-        ERR("The framebuffer is NULL. Failed to release the framebuffer\n");\r
-        return;\r
-    } else if (buf_num == 0) {\r
-        ERR("The buffer count is 0. Failed to release the framebuffer\n");\r
-        return;\r
-    } else {\r
-        TRACE("[%s]:fb(0x%p), buf_num(%d)\n", __func__, fb, buf_num);\r
-    }\r
-\r
-    /* Unmap framebuffers. */\r
-    for (i = 0; i < buf_num; i++) {\r
-        if (fb[i].data != NULL) {\r
-            v4l2_munmap(fb[i].data, fb[i].size);\r
-            fb[i].data = NULL;\r
-            fb[i].size = 0;\r
-        } else {\r
-            ERR("framebuffer[%d].data is NULL.\n", i);\r
-        }\r
-    }\r
-}\r
-\r
-static uint32_t\r
-mmap_framebuffers(marucam_framebuffer **fb, int *buf_num)\r
-{\r
-    struct v4l2_requestbuffers req;\r
-\r
-    CLEAR(req);\r
-    req.count   = MARUCAM_DEFAULT_BUFFER_COUNT;\r
-    req.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
-    req.memory  = V4L2_MEMORY_MMAP;\r
-    if (xioctl(v4l2_fd, VIDIOC_REQBUFS, &req) < 0) {\r
-        if (errno == EINVAL) {\r
-            ERR("%s does not support memory mapping: %s\n",\r
-                dev_name, strerror(errno));\r
-        } else {\r
-            ERR("Failed to request bufs: %s\n", strerror(errno));\r
-        }\r
-        return errno;\r
-    }\r
-    if (req.count == 0) {\r
-        ERR("Insufficient buffer memory on %s\n", dev_name);\r
-        return EINVAL;\r
-    }\r
-\r
-    *fb = g_new0(marucam_framebuffer, req.count);\r
-    if (*fb == NULL) {\r
-        ERR("Not enough memory to allocate framebuffers\n");\r
-        return ENOMEM;\r
-    }\r
-\r
-    for (*buf_num = 0; *buf_num < req.count; ++*buf_num) {\r
-        struct v4l2_buffer buf;\r
-        CLEAR(buf);\r
-        buf.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
-        buf.memory  = V4L2_MEMORY_MMAP;\r
-        buf.index   = *buf_num;\r
-        if (xioctl(v4l2_fd, VIDIOC_QUERYBUF, &buf) < 0) {\r
-            ERR("Failed to ioctl() with VIDIOC_QUERYBUF: %s\n",\r
-                strerror(errno));\r
-            return errno;\r
-        }\r
-\r
-        (*fb)[*buf_num].size = buf.length;\r
-        (*fb)[*buf_num].data = v4l2_mmap(NULL,\r
-                     buf.length,\r
-                     PROT_READ | PROT_WRITE,\r
-                     MAP_SHARED,\r
-                     v4l2_fd, buf.m.offset);\r
-        if (MAP_FAILED == (*fb)[*buf_num].data) {\r
-            ERR("Failed to mmap: %s\n", strerror(errno));\r
-            return errno;\r
-        }\r
-\r
-        /* Queue the mapped buffer. */\r
-        CLEAR(buf);\r
-        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
-        buf.memory = V4L2_MEMORY_MMAP;\r
-        buf.index = *buf_num;\r
-        if (xioctl(v4l2_fd, VIDIOC_QBUF, &buf) < 0) {\r
-            ERR("Failed to ioctl() with VIDIOC_QBUF: %s\n", strerror(errno));\r
-            return errno;\r
-        }\r
-    }\r
-    return 0;\r
-}\r
-\r
-static int is_streamon(MaruCamState *state)\r
-{\r
-    int st;\r
-    qemu_mutex_lock(&state->thread_mutex);\r
-    st = state->streamon;\r
-    qemu_mutex_unlock(&state->thread_mutex);\r
-    return (st == _MC_THREAD_STREAMON);\r
-}\r
-\r
-static int is_stream_paused(MaruCamState *state)\r
-{\r
-    int st;\r
-    qemu_mutex_lock(&state->thread_mutex);\r
-    st = state->streamon;\r
-    qemu_mutex_unlock(&state->thread_mutex);\r
-    return (st == _MC_THREAD_PAUSED);\r
-}\r
-\r
-static void __raise_err_intr(MaruCamState *state)\r
-{\r
-    qemu_mutex_lock(&state->thread_mutex);\r
-    if (state->streamon == _MC_THREAD_STREAMON) {\r
-        state->req_frame = 0; /* clear request */\r
-        state->isr = 0x08;   /* set a error flag of rasing a interrupt */\r
-        qemu_bh_schedule(state->tx_bh);\r
-    }\r
-    qemu_mutex_unlock(&state->thread_mutex);\r
-}\r
-\r
-static void\r
-notify_buffer_ready(MaruCamState *state, void *ptr, size_t size)\r
-{\r
-    void *buf = NULL;\r
-\r
-    qemu_mutex_lock(&state->thread_mutex);\r
-    if (state->streamon == _MC_THREAD_STREAMON) {\r
-        if (ready_count < MARUCAM_SKIPFRAMES) {\r
-            /* skip a frame cause first some frame are distorted */\r
-            ++ready_count;\r
-            TRACE("Skip %d frame\n", ready_count);\r
-            qemu_mutex_unlock(&state->thread_mutex);\r
-            return;\r
-        }\r
-        if (state->req_frame == 0) {\r
-            TRACE("There is no request\n");\r
-            qemu_mutex_unlock(&state->thread_mutex);\r
-            return;\r
-        }\r
-        buf = state->vaddr + state->buf_size * (state->req_frame - 1);\r
-        memcpy(buf, ptr, state->buf_size);\r
-        state->req_frame = 0; /* clear request */\r
-        state->isr |= 0x01;   /* set a flag of rasing a interrupt */\r
-        qemu_bh_schedule(state->tx_bh);\r
-    }\r
-    qemu_mutex_unlock(&state->thread_mutex);\r
-}\r
-\r
-static int read_frame(MaruCamState *state)\r
-{\r
-    struct v4l2_buffer buf;\r
-\r
-    CLEAR(buf);\r
-    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
-    buf.memory = V4L2_MEMORY_MMAP;\r
-    if (xioctl(v4l2_fd, VIDIOC_DQBUF, &buf) < 0) {\r
-        switch (errno) {\r
-        case EAGAIN:\r
-        case EINTR:\r
-            ERR("DQBUF error, try again: %s\n", strerror(errno));\r
-            return 0;\r
-        case EIO:\r
-            ERR("The v4l2_read() met the EIO\n");\r
-            if (convert_trial-- == -1) {\r
-                ERR("Try count for v4l2_read is exceeded: %s\n",\r
-                    strerror(errno));\r
-                return -1;\r
-            }\r
-            return 0;\r
-        default:\r
-            ERR("DQBUF error: %s\n", strerror(errno));\r
-            return -1;\r
-        }\r
-    }\r
-\r
-    notify_buffer_ready(state, framebuffer[buf.index].data, buf.bytesused);\r
-\r
-    if (xioctl(v4l2_fd, VIDIOC_QBUF, &buf) < 0) {\r
-        ERR("QBUF error: %s\n", strerror(errno));\r
-        return -1;\r
-    }\r
-    return 0;\r
-}\r
-\r
-static int __v4l2_streaming(MaruCamState *state)\r
-{\r
-    fd_set fds;\r
-    struct timeval tv;\r
-    int ret;\r
-    static uint32_t timeout_n = 0;\r
-\r
-    FD_ZERO(&fds);\r
-    FD_SET(v4l2_fd, &fds);\r
-\r
-    tv.tv_sec = 1;\r
-    tv.tv_usec = 0;\r
-\r
-    ret = select(v4l2_fd + 1, &fds, NULL, NULL, &tv);\r
-    if (ret < 0) {\r
-        if (errno == EAGAIN || errno == EINTR) {\r
-            ERR("Select again: %s\n", strerror(errno));\r
-            return 0;\r
-        }\r
-        ERR("Failed to select: %s\n", strerror(errno));\r
-        __raise_err_intr(state);\r
-        return -1;\r
-    } else if (!ret) {\r
-        timeout_n++;\r
-        ERR("Select timed out: count(%u)\n", timeout_n);\r
-        if (timeout_n >= 5) {\r
-            __raise_err_intr(state);\r
-            return -1;\r
-        }\r
-        return 0;\r
-    }\r
-\r
-    if (!v4l2_fd || (v4l2_fd == -1)) {\r
-        ERR("The file descriptor is closed or not opened\n");\r
-        __raise_err_intr(state);\r
-        return -1;\r
-    }\r
-\r
-    ret = read_frame(state);\r
-    if (ret < 0) {\r
-        ERR("Failed to operate the read_frame()\n");\r
-        __raise_err_intr(state);\r
-        return -1;\r
-    }\r
-\r
-    /* clear the skip count for select time-out */\r
-    if (timeout_n > 0) {\r
-        timeout_n = 0;\r
-    }\r
-\r
-    return 0;\r
-}\r
-\r
-/* Worker thread */\r
-static void *marucam_worker_thread(void *thread_param)\r
-{\r
-    MaruCamState *state = (MaruCamState *)thread_param;\r
-\r
-    while (1) {\r
-        qemu_mutex_lock(&state->thread_mutex);\r
-        state->streamon = _MC_THREAD_PAUSED;\r
-        qemu_cond_wait(&state->thread_cond, &state->thread_mutex);\r
-        qemu_mutex_unlock(&state->thread_mutex);\r
-\r
-        if (state->destroying) {\r
-            break;\r
-        }\r
-\r
-        convert_trial = 10;\r
-        ready_count = 0;\r
-        qemu_mutex_lock(&state->thread_mutex);\r
-        state->streamon = _MC_THREAD_STREAMON;\r
-        qemu_mutex_unlock(&state->thread_mutex);\r
-        INFO("Streaming on ......\n");\r
-\r
-        while (1) {\r
-            if (is_streamon(state)) {\r
-                if (__v4l2_streaming(state) < 0) {\r
-                    INFO("...... Streaming off\n");\r
-                    break;\r
-                }\r
-            } else {\r
-                INFO("...... Streaming off\n");\r
-                break;\r
-            }\r
-        }\r
-    }\r
-\r
-    return NULL;\r
-}\r
-\r
-int marucam_device_check(int log_flag)\r
-{\r
-    int tmp_fd;\r
-    struct timeval t1, t2;\r
-    struct stat st;\r
-    struct v4l2_fmtdesc format;\r
-    struct v4l2_frmsizeenum size;\r
-    struct v4l2_capability cap;\r
-    int ret = 0;\r
-\r
-    gettimeofday(&t1, NULL);\r
-    if (stat(dev_name, &st) < 0) {\r
-        fprintf(stdout, "[Webcam] <WARNING> Cannot identify '%s': %s\n",\r
-                dev_name, strerror(errno));\r
-    } else {\r
-        if (!S_ISCHR(st.st_mode)) {\r
-            fprintf(stdout, "[Webcam] <WARNING>%s is no character device\n",\r
-                    dev_name);\r
-        }\r
-    }\r
-\r
-    tmp_fd = open(dev_name, O_RDWR | O_NONBLOCK, 0);\r
-    if (tmp_fd < 0) {\r
-        fprintf(stdout, "[Webcam] Camera device open failed: %s\n", dev_name);\r
-        gettimeofday(&t2, NULL);\r
-        fprintf(stdout, "[Webcam] Elapsed time: %lu:%06lu\n",\r
-                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-        return ret;\r
-    }\r
-    if (ioctl(tmp_fd, VIDIOC_QUERYCAP, &cap) < 0) {\r
-        fprintf(stdout, "[Webcam] Could not qeury video capabilities\n");\r
-        close(tmp_fd);\r
-        gettimeofday(&t2, NULL);\r
-        fprintf(stdout, "[Webcam] Elapsed time: %lu:%06lu\n",\r
-                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-        return ret;\r
-    }\r
-    if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) ||\r
-            !(cap.capabilities & V4L2_CAP_STREAMING)) {\r
-        fprintf(stdout, "[Webcam] Not supported video driver\n");\r
-        close(tmp_fd);\r
-        gettimeofday(&t2, NULL);\r
-        fprintf(stdout, "[Webcam] Elapsed time: %lu:%06lu\n",\r
-                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-        return ret;\r
-    }\r
-    ret = 1;\r
-\r
-    if (log_flag) {\r
-        fprintf(stdout, "[Webcam] Driver: %s\n", cap.driver);\r
-        fprintf(stdout, "[Webcam] Card:  %s\n", cap.card);\r
-        fprintf(stdout, "[Webcam] Bus info: %s\n", cap.bus_info);\r
-\r
-        CLEAR(format);\r
-        format.index = 0;\r
-        format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
-\r
-        if (yioctl(tmp_fd, VIDIOC_ENUM_FMT, &format) < 0) {\r
-            close(tmp_fd);\r
-            gettimeofday(&t2, NULL);\r
-            fprintf(stdout, "[Webcam] Elapsed time: %lu:%06lu\n",\r
-                    t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-            return ret;\r
-        }\r
-\r
-        do {\r
-            CLEAR(size);\r
-            size.index = 0;\r
-            size.pixel_format = format.pixelformat;\r
-\r
-            fprintf(stdout, "[Webcam] PixelFormat: %c%c%c%c\n",\r
-                             (char)(format.pixelformat),\r
-                             (char)(format.pixelformat >> 8),\r
-                             (char)(format.pixelformat >> 16),\r
-                             (char)(format.pixelformat >> 24));\r
-\r
-            if (yioctl(tmp_fd, VIDIOC_ENUM_FRAMESIZES, &size) < 0) {\r
-                close(tmp_fd);\r
-                gettimeofday(&t2, NULL);\r
-                fprintf(stdout, "[Webcam] Elapsed time: %lu:%06lu\n",\r
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-                return ret;\r
-            }\r
-\r
-            if (size.type == V4L2_FRMSIZE_TYPE_DISCRETE) {\r
-                do {\r
-                    fprintf(stdout, "[Webcam] got discrete frame size %dx%d\n",\r
-                                    size.discrete.width, size.discrete.height);\r
-                    size.index++;\r
-                } while (yioctl(tmp_fd, VIDIOC_ENUM_FRAMESIZES, &size) >= 0);\r
-            } else if (size.type == V4L2_FRMSIZE_TYPE_STEPWISE) {\r
-                fprintf(stdout, "[Webcam] we have stepwise frame sizes:\n");\r
-                fprintf(stdout, "[Webcam] min width: %d, min height: %d\n",\r
-                        size.stepwise.min_width, size.stepwise.min_height);\r
-                fprintf(stdout, "[Webcam] max width: %d, max height: %d\n",\r
-                        size.stepwise.max_width, size.stepwise.max_height);\r
-                fprintf(stdout, "[Webcam] step width: %d, step height: %d\n",\r
-                        size.stepwise.step_width, size.stepwise.step_height);\r
-            } else if (size.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) {\r
-                fprintf(stdout, "[Webcam] we have continuous frame sizes:\n");\r
-                fprintf(stdout, "[Webcam] min width: %d, min height: %d\n",\r
-                        size.stepwise.min_width, size.stepwise.min_height);\r
-                fprintf(stdout, "[Webcam] max width: %d, max height: %d\n",\r
-                        size.stepwise.max_width, size.stepwise.max_height);\r
-\r
-            }\r
-            format.index++;\r
-        } while (yioctl(tmp_fd, VIDIOC_ENUM_FMT, &format) >= 0);\r
-    }\r
-\r
-    close(tmp_fd);\r
-    gettimeofday(&t2, NULL);\r
-    fprintf(stdout, "[Webcam] Elapsed time: %lu:%06lu\n",\r
-                    t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-    return ret;\r
-}\r
-\r
-void marucam_device_init(MaruCamState *state)\r
-{\r
-    state->destroying = false;\r
-    qemu_thread_create(&state->thread_id, marucam_worker_thread, (void *)state,\r
-            QEMU_THREAD_JOINABLE);\r
-}\r
-\r
-void marucam_device_exit(MaruCamState *state)\r
-{\r
-    state->destroying = true;\r
-    qemu_mutex_lock(&state->thread_mutex);\r
-    qemu_cond_signal(&state->thread_cond);\r
-    qemu_mutex_unlock(&state->thread_mutex);\r
-    qemu_thread_join(&state->thread_id);\r
-}\r
-\r
-void marucam_device_open(MaruCamState *state)\r
-{\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-    v4l2_fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0);\r
-    if (v4l2_fd < 0) {\r
-        ERR("The v4l2 device open failed: %s\n", dev_name);\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-    INFO("Opened\n");\r
-\r
-    /* FIXME : Do not use fixed values */\r
-    CLEAR(dst_fmt);\r
-    dst_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
-    dst_fmt.fmt.pix.width = 640;\r
-    dst_fmt.fmt.pix.height = 480;\r
-    dst_fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;\r
-    dst_fmt.fmt.pix.field = V4L2_FIELD_ANY;\r
-\r
-    if (xioctl(v4l2_fd, VIDIOC_S_FMT, &dst_fmt) < 0) {\r
-        ERR("Failed to set video format: format(0x%x), width:height(%d:%d), "\r
-          "errstr(%s)\n", dst_fmt.fmt.pix.pixelformat, dst_fmt.fmt.pix.width,\r
-          dst_fmt.fmt.pix.height, strerror(errno));\r
-        param->errCode = errno;\r
-        return;\r
-    }\r
-    TRACE("Set the default format: w:h(%dx%d), fmt(0x%x), size(%d), "\r
-         "color(%d), field(%d)\n",\r
-         dst_fmt.fmt.pix.width, dst_fmt.fmt.pix.height,\r
-         dst_fmt.fmt.pix.pixelformat, dst_fmt.fmt.pix.sizeimage,\r
-         dst_fmt.fmt.pix.colorspace, dst_fmt.fmt.pix.field);\r
-}\r
-\r
-void marucam_device_start_preview(MaruCamState *state)\r
-{\r
-    struct timespec req;\r
-    MaruCamParam *param = state->param;\r
-    param->top = 0;\r
-    req.tv_sec = 0;\r
-    req.tv_nsec = 10000000;\r
-\r
-    INFO("Pixfmt(%c%c%c%C), W:H(%d:%d), buf size(%u)\n",\r
-         (char)(dst_fmt.fmt.pix.pixelformat),\r
-         (char)(dst_fmt.fmt.pix.pixelformat >> 8),\r
-         (char)(dst_fmt.fmt.pix.pixelformat >> 16),\r
-         (char)(dst_fmt.fmt.pix.pixelformat >> 24),\r
-         dst_fmt.fmt.pix.width,\r
-         dst_fmt.fmt.pix.height,\r
-         dst_fmt.fmt.pix.sizeimage);\r
-\r
-    param->errCode = mmap_framebuffers(&framebuffer, &n_framebuffer);\r
-    if (param->errCode) {\r
-        ERR("Failed to mmap framebuffers\n");\r
-        if (framebuffer != NULL) {\r
-            free_framebuffers(framebuffer, n_framebuffer);\r
-            g_free(framebuffer);\r
-            framebuffer = NULL;\r
-            n_framebuffer = 0;\r
-        }\r
-        return;\r
-    }\r
-\r
-    param->errCode = start_capturing();\r
-    if (param->errCode) {\r
-        if (framebuffer != NULL) {\r
-            free_framebuffers(framebuffer, n_framebuffer);\r
-            g_free(framebuffer);\r
-            framebuffer = NULL;\r
-            n_framebuffer = 0;\r
-        }\r
-        return;\r
-    }\r
-\r
-    INFO("Starting preview\n");\r
-    state->buf_size = dst_fmt.fmt.pix.sizeimage;\r
-    qemu_mutex_lock(&state->thread_mutex);\r
-    qemu_cond_signal(&state->thread_cond);\r
-    qemu_mutex_unlock(&state->thread_mutex);\r
-\r
-    /* nanosleep until thread is streamon  */\r
-    while (!is_streamon(state)) {\r
-        nanosleep(&req, NULL);\r
-    }\r
-}\r
-\r
-void marucam_device_stop_preview(MaruCamState *state)\r
-{\r
-    struct timespec req;\r
-    struct v4l2_requestbuffers reqbuf;\r
-    MaruCamParam *param = state->param;\r
-    param->top = 0;\r
-    req.tv_sec = 0;\r
-    req.tv_nsec = 50000000;\r
-\r
-    if (is_streamon(state)) {\r
-        qemu_mutex_lock(&state->thread_mutex);\r
-        state->streamon = _MC_THREAD_STREAMOFF;\r
-        qemu_mutex_unlock(&state->thread_mutex);\r
-\r
-        /* nanosleep until thread is paused  */\r
-        while (!is_stream_paused(state)) {\r
-            nanosleep(&req, NULL);\r
-        }\r
-    }\r
-\r
-    param->errCode = stop_capturing();\r
-    if (framebuffer != NULL) {\r
-        free_framebuffers(framebuffer, n_framebuffer);\r
-        g_free(framebuffer);\r
-        framebuffer = NULL;\r
-        n_framebuffer = 0;\r
-    }\r
-    state->buf_size = 0;\r
-\r
-    reqbuf.count = 0;\r
-    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
-    reqbuf.memory = V4L2_MEMORY_MMAP;\r
-    if (xioctl(v4l2_fd, VIDIOC_REQBUFS, &reqbuf) < 0) {\r
-        ERR("Failed to ioctl() with VIDIOC_REQBUF in stop_preview: %s\n",\r
-            strerror(errno));\r
-    }\r
-    INFO("Stopping preview\n");\r
-}\r
-\r
-void marucam_device_s_param(MaruCamState *state)\r
-{\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-\r
-    /* If KVM enabled, We use default FPS of the webcam.\r
-     * If KVM disabled, we use mininum FPS of the webcam */\r
-    if (!kvm_enabled()) {\r
-        set_maxframeinterval(state, dst_fmt.fmt.pix.pixelformat,\r
-                     dst_fmt.fmt.pix.width,\r
-                     dst_fmt.fmt.pix.height);\r
-    }\r
-}\r
-\r
-void marucam_device_g_param(MaruCamState *state)\r
-{\r
-    MaruCamParam *param = state->param;\r
-\r
-    /* We use default FPS of the webcam\r
-     * return a fixed value on guest ini file (1/30).\r
-     */\r
-    param->top = 0;\r
-    param->stack[0] = 0x1000; /* V4L2_CAP_TIMEPERFRAME */\r
-    param->stack[1] = 1; /* numerator */\r
-    param->stack[2] = 30; /* denominator */\r
-}\r
-\r
-void marucam_device_s_fmt(MaruCamState *state)\r
-{\r
-    struct v4l2_format format;\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-    CLEAR(format);\r
-    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
-    format.fmt.pix.width = param->stack[0];\r
-    format.fmt.pix.height = param->stack[1];\r
-    format.fmt.pix.pixelformat = param->stack[2];\r
-    format.fmt.pix.field = V4L2_FIELD_ANY;\r
-\r
-    if (xioctl(v4l2_fd, VIDIOC_S_FMT, &format) < 0) {\r
-        ERR("Failed to set video format: format(0x%x), width:height(%d:%d), "\r
-          "errstr(%s)\n", format.fmt.pix.pixelformat, format.fmt.pix.width,\r
-          format.fmt.pix.height, strerror(errno));\r
-        param->errCode = errno;\r
-        return;\r
-    }\r
-\r
-    memcpy(&dst_fmt, &format, sizeof(format));\r
-    param->stack[0] = dst_fmt.fmt.pix.width;\r
-    param->stack[1] = dst_fmt.fmt.pix.height;\r
-    param->stack[2] = dst_fmt.fmt.pix.field;\r
-    param->stack[3] = dst_fmt.fmt.pix.pixelformat;\r
-    param->stack[4] = dst_fmt.fmt.pix.bytesperline;\r
-    param->stack[5] = dst_fmt.fmt.pix.sizeimage;\r
-    param->stack[6] = dst_fmt.fmt.pix.colorspace;\r
-    param->stack[7] = dst_fmt.fmt.pix.priv;\r
-    TRACE("Set the format: w:h(%dx%d), fmt(0x%x), size(%d), "\r
-         "color(%d), field(%d)\n",\r
-         dst_fmt.fmt.pix.width, dst_fmt.fmt.pix.height,\r
-         dst_fmt.fmt.pix.pixelformat, dst_fmt.fmt.pix.sizeimage,\r
-         dst_fmt.fmt.pix.colorspace, dst_fmt.fmt.pix.field);\r
-}\r
-\r
-void marucam_device_g_fmt(MaruCamState *state)\r
-{\r
-    struct v4l2_format format;\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-    CLEAR(format);\r
-    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
-\r
-    if (xioctl(v4l2_fd, VIDIOC_G_FMT, &format) < 0) {\r
-        ERR("Failed to get video format: %s\n", strerror(errno));\r
-        param->errCode = errno;\r
-    } else {\r
-        param->stack[0] = format.fmt.pix.width;\r
-        param->stack[1] = format.fmt.pix.height;\r
-        param->stack[2] = format.fmt.pix.field;\r
-        param->stack[3] = format.fmt.pix.pixelformat;\r
-        param->stack[4] = format.fmt.pix.bytesperline;\r
-        param->stack[5] = format.fmt.pix.sizeimage;\r
-        param->stack[6] = format.fmt.pix.colorspace;\r
-        param->stack[7] = format.fmt.pix.priv;\r
-        TRACE("Get the format: w:h(%dx%d), fmt(0x%x), size(%d), "\r
-             "color(%d), field(%d)\n",\r
-             format.fmt.pix.width, format.fmt.pix.height,\r
-             format.fmt.pix.pixelformat, format.fmt.pix.sizeimage,\r
-             format.fmt.pix.colorspace, format.fmt.pix.field);\r
-    }\r
-}\r
-\r
-void marucam_device_try_fmt(MaruCamState *state)\r
-{\r
-    struct v4l2_format format;\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-    CLEAR(format);\r
-    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;\r
-    format.fmt.pix.width = param->stack[0];\r
-    format.fmt.pix.height = param->stack[1];\r
-    format.fmt.pix.pixelformat = param->stack[2];\r
-    format.fmt.pix.field = V4L2_FIELD_ANY;\r
-\r
-    if (xioctl(v4l2_fd, VIDIOC_TRY_FMT, &format) < 0) {\r
-        ERR("Failed to check video format: format(0x%x), width:height(%d:%d),"\r
-            " errstr(%s)\n", format.fmt.pix.pixelformat, format.fmt.pix.width,\r
-            format.fmt.pix.height, strerror(errno));\r
-        param->errCode = errno;\r
-        return;\r
-    }\r
-    param->stack[0] = format.fmt.pix.width;\r
-    param->stack[1] = format.fmt.pix.height;\r
-    param->stack[2] = format.fmt.pix.field;\r
-    param->stack[3] = format.fmt.pix.pixelformat;\r
-    param->stack[4] = format.fmt.pix.bytesperline;\r
-    param->stack[5] = format.fmt.pix.sizeimage;\r
-    param->stack[6] = format.fmt.pix.colorspace;\r
-    param->stack[7] = format.fmt.pix.priv;\r
-    TRACE("Check the format: w:h(%dx%d), fmt(0x%x), size(%d), "\r
-         "color(%d), field(%d)\n",\r
-         format.fmt.pix.width, format.fmt.pix.height,\r
-         format.fmt.pix.pixelformat, format.fmt.pix.sizeimage,\r
-         format.fmt.pix.colorspace, format.fmt.pix.field);\r
-}\r
-\r
-void marucam_device_enum_fmt(MaruCamState *state)\r
-{\r
-    uint32_t index;\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-    index = param->stack[0];\r
-\r
-    if (index >= ARRAY_SIZE(supported_dst_pixfmts)) {\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-    param->stack[1] = 0; /* flags = NONE */\r
-    param->stack[2] = supported_dst_pixfmts[index].fmt; /* pixelformat */\r
-    /* set description */\r
-    switch (supported_dst_pixfmts[index].fmt) {\r
-    case V4L2_PIX_FMT_YUYV:\r
-        memcpy(&param->stack[3], "YUYV", 32);\r
-        break;\r
-    case V4L2_PIX_FMT_YUV420:\r
-        memcpy(&param->stack[3], "YU12", 32);\r
-        break;\r
-    case V4L2_PIX_FMT_YVU420:\r
-        memcpy(&param->stack[3], "YV12", 32);\r
-        break;\r
-    default:\r
-        ERR("Invalid fixel format\n");\r
-        param->errCode = EINVAL;\r
-        break;\r
-    }\r
-}\r
-\r
-void marucam_device_qctrl(MaruCamState *state)\r
-{\r
-    uint32_t i;\r
-    char name[32] = {0,};\r
-    struct v4l2_queryctrl ctrl;\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-    CLEAR(ctrl);\r
-    ctrl.id = param->stack[0];\r
-\r
-    switch (ctrl.id) {\r
-    case V4L2_CID_BRIGHTNESS:\r
-        TRACE("Query : BRIGHTNESS\n");\r
-        memcpy((void *)name, (void *)"brightness", 32);\r
-        i = 0;\r
-        break;\r
-    case V4L2_CID_CONTRAST:\r
-        TRACE("Query : CONTRAST\n");\r
-        memcpy((void *)name, (void *)"contrast", 32);\r
-        i = 1;\r
-        break;\r
-    case V4L2_CID_SATURATION:\r
-        TRACE("Query : SATURATION\n");\r
-        memcpy((void *)name, (void *)"saturation", 32);\r
-        i = 2;\r
-        break;\r
-    case V4L2_CID_SHARPNESS:\r
-        TRACE("Query : SHARPNESS\n");\r
-        memcpy((void *)name, (void *)"sharpness", 32);\r
-        i = 3;\r
-        break;\r
-    default:\r
-        ERR("Invalid control ID\n");\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-\r
-    if (xioctl(v4l2_fd, VIDIOC_QUERYCTRL, &ctrl) < 0) {\r
-        if (errno != EINVAL) {\r
-            ERR("Failed to query video controls: %s\n", strerror(errno));\r
-        }\r
-        param->errCode = errno;\r
-        return;\r
-    } else {\r
-        struct v4l2_control sctrl;\r
-        CLEAR(sctrl);\r
-        sctrl.id = ctrl.id;\r
-        if ((ctrl.maximum + ctrl.minimum) == 0) {\r
-            sctrl.value = 0;\r
-        } else {\r
-            sctrl.value = (ctrl.maximum + ctrl.minimum) / 2;\r
-        }\r
-        if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &sctrl) < 0) {\r
-            ERR("Failed to set control value: id(0x%x), value(%d), "\r
-                "errstr(%s)\n", sctrl.id, sctrl.value, strerror(errno));\r
-            param->errCode = errno;\r
-            return;\r
-        }\r
-        qctrl_tbl[i].hit = 1;\r
-        qctrl_tbl[i].min = ctrl.minimum;\r
-        qctrl_tbl[i].max = ctrl.maximum;\r
-        qctrl_tbl[i].step = ctrl.step;\r
-        qctrl_tbl[i].init_val = ctrl.default_value;\r
-    }\r
-\r
-    /* set fixed values by FW configuration file */\r
-    param->stack[0] = ctrl.id;\r
-    param->stack[1] = MARUCAM_CTRL_VALUE_MIN;    /* minimum */\r
-    param->stack[2] = MARUCAM_CTRL_VALUE_MAX;    /* maximum */\r
-    param->stack[3] = MARUCAM_CTRL_VALUE_STEP;   /* step */\r
-    param->stack[4] = MARUCAM_CTRL_VALUE_MID;    /* default_value */\r
-    param->stack[5] = ctrl.flags;\r
-    /* name field setting */\r
-    memcpy(&param->stack[6], (void *)name, sizeof(ctrl.name));\r
-}\r
-\r
-void marucam_device_s_ctrl(MaruCamState *state)\r
-{\r
-    uint32_t i;\r
-    struct v4l2_control ctrl;\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-    CLEAR(ctrl);\r
-    ctrl.id = param->stack[0];\r
-\r
-    switch (ctrl.id) {\r
-    case V4L2_CID_BRIGHTNESS:\r
-        i = 0;\r
-        TRACE("%d is set to the value of the BRIGHTNESS\n", param->stack[1]);\r
-        break;\r
-    case V4L2_CID_CONTRAST:\r
-        i = 1;\r
-        TRACE("%d is set to the value of the CONTRAST\n", param->stack[1]);\r
-        break;\r
-    case V4L2_CID_SATURATION:\r
-        i = 2;\r
-        TRACE("%d is set to the value of the SATURATION\n", param->stack[1]);\r
-        break;\r
-    case V4L2_CID_SHARPNESS:\r
-        i = 3;\r
-        TRACE("%d is set to the value of the SHARPNESS\n", param->stack[1]);\r
-        break;\r
-    default:\r
-        ERR("Our emulator does not support this control: 0x%x\n", ctrl.id);\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-\r
-    ctrl.value = value_convert_from_guest(qctrl_tbl[i].min,\r
-            qctrl_tbl[i].max, param->stack[1]);\r
-    if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &ctrl) < 0) {\r
-        ERR("Failed to set control value: id(0x%x), value(r:%d, c:%d), "\r
-            "errstr(%s)\n", ctrl.id, param->stack[1], ctrl.value,\r
-            strerror(errno));\r
-        param->errCode = errno;\r
-        return;\r
-    }\r
-}\r
-\r
-void marucam_device_g_ctrl(MaruCamState *state)\r
-{\r
-    uint32_t i;\r
-    struct v4l2_control ctrl;\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-    CLEAR(ctrl);\r
-    ctrl.id = param->stack[0];\r
-\r
-    switch (ctrl.id) {\r
-    case V4L2_CID_BRIGHTNESS:\r
-        TRACE("Gets the value of the BRIGHTNESS\n");\r
-        i = 0;\r
-        break;\r
-    case V4L2_CID_CONTRAST:\r
-        TRACE("Gets the value of the CONTRAST\n");\r
-        i = 1;\r
-        break;\r
-    case V4L2_CID_SATURATION:\r
-        TRACE("Gets the value of the SATURATION\n");\r
-        i = 2;\r
-        break;\r
-    case V4L2_CID_SHARPNESS:\r
-        TRACE("Gets the value of the SHARPNESS\n");\r
-        i = 3;\r
-        break;\r
-    default:\r
-        ERR("Our emulator does not support this control: 0x%x\n", ctrl.id);\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-\r
-    if (xioctl(v4l2_fd, VIDIOC_G_CTRL, &ctrl) < 0) {\r
-        ERR("Failed to get video control value: %s\n", strerror(errno));\r
-        param->errCode = errno;\r
-        return;\r
-    }\r
-    param->stack[0] = value_convert_to_guest(qctrl_tbl[i].min,\r
-            qctrl_tbl[i].max, ctrl.value);\r
-    TRACE("Value: %d\n", param->stack[0]);\r
-}\r
-\r
-void marucam_device_enum_fsizes(MaruCamState *state)\r
-{\r
-    uint32_t index, pixfmt, i;\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-    index = param->stack[0];\r
-    pixfmt = param->stack[1];\r
-\r
-    if (index >= ARRAY_SIZE(supported_dst_frames)) {\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-    for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) {\r
-        if (supported_dst_pixfmts[i].fmt == pixfmt) {\r
-            break;\r
-        }\r
-    }\r
-\r
-    if (i == ARRAY_SIZE(supported_dst_pixfmts)) {\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-\r
-    param->stack[0] = supported_dst_frames[index].width;\r
-    param->stack[1] = supported_dst_frames[index].height;\r
-}\r
-\r
-void marucam_device_enum_fintv(MaruCamState *state)\r
-{\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-\r
-    /* switch by index(param->stack[0]) */\r
-    switch (param->stack[0]) {\r
-    case 0:\r
-        /* we only use 1/30 frame interval */\r
-        param->stack[1] = 30;   /* denominator */\r
-        break;\r
-    default:\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-    param->stack[0] = 1;    /* numerator */\r
-}\r
-\r
-void marucam_device_close(MaruCamState *state)\r
-{\r
-    if (!is_stream_paused(state)) {\r
-        marucam_device_stop_preview(state);\r
-    }\r
-\r
-    marucam_reset_controls();\r
-\r
-    v4l2_close(v4l2_fd);\r
-    v4l2_fd = 0;\r
-    INFO("Closed\n");\r
-}\r
+/*
+ * Implementation of MARU Virtual Camera device by PCI bus on Linux.
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * 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 "qemu-common.h"
+#include "maru_camera_common.h"
+#include "pci.h"
+#include "kvm.h"
+#include "tizen/src/debug_ch.h"
+
+#include <linux/videodev2.h>
+
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include <libv4l2.h>
+#include <libv4lconvert.h>
+
+MULTI_DEBUG_CHANNEL(tizen, camera_linux);
+
+#define CLEAR(x) memset(&(x), 0, sizeof(x))
+
+#define MARUCAM_DEFAULT_BUFFER_COUNT    4
+#define MARUCAM_DUMMYFRAME_COUNT    2
+
+#define MARUCAM_CTRL_VALUE_MAX      20
+#define MARUCAM_CTRL_VALUE_MIN      1
+#define MARUCAM_CTRL_VALUE_MID      10
+#define MARUCAM_CTRL_VALUE_STEP     1
+
+enum {
+    _MC_THREAD_PAUSED,
+    _MC_THREAD_STREAMON,
+    _MC_THREAD_STREAMOFF,
+};
+
+typedef struct marucam_framebuffer {
+    void *data;
+    size_t size;
+} marucam_framebuffer;
+
+static int n_framebuffer;
+static struct marucam_framebuffer *framebuffer;
+
+static const char *dev_name = "/dev/video0";
+static int v4l2_fd;
+static int convert_trial;
+static int ready_count;
+static int timeout_n;
+
+static struct v4l2_format dst_fmt;
+
+static void make_yu12_black(unsigned char *dest, uint32_t width, uint32_t height)
+{
+    uint32_t x, y;
+    unsigned char *udest, *vdest;
+
+    /* Y */
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x++) {
+            *dest++ = 16;
+        }
+    }
+
+    /* U + V */
+    udest = dest;
+    vdest = dest + width * height / 4;
+
+    for (y = 0; y < height / 2; y++) {
+        for (x = 0; x < width / 2; x++) {
+            *udest++ = *vdest++ = 128;
+        }
+    }
+}
+
+static int yioctl(int fd, int req, void *arg)
+{
+    int r;
+
+    do {
+        r = ioctl(fd, req, arg);
+    } while (r < 0 && errno == EINTR);
+
+    return r;
+}
+
+static int xioctl(int fd, int req, void *arg)
+{
+    int r;
+
+    do {
+        r = v4l2_ioctl(fd, req, arg);
+    } while (r < 0 && errno == EINTR);
+
+    return r;
+}
+
+typedef struct tagMaruCamConvertPixfmt {
+    uint32_t fmt;   /* fourcc */
+} MaruCamConvertPixfmt;
+
+static MaruCamConvertPixfmt supported_dst_pixfmts[] = {
+        { V4L2_PIX_FMT_YUYV },
+        { V4L2_PIX_FMT_YUV420 },
+        { V4L2_PIX_FMT_YVU420 },
+};
+
+typedef struct tagMaruCamConvertFrameInfo {
+    uint32_t width;
+    uint32_t height;
+} MaruCamConvertFrameInfo;
+
+static MaruCamConvertFrameInfo supported_dst_frames[] = {
+        { 640, 480 },
+        { 352, 288 },
+        { 320, 240 },
+        { 176, 144 },
+        { 160, 120 },
+};
+
+struct marucam_qctrl {
+    uint32_t id;
+    uint32_t hit;
+    int32_t min;
+    int32_t max;
+    int32_t step;
+    int32_t init_val;
+};
+
+static struct marucam_qctrl qctrl_tbl[] = {
+    { V4L2_CID_BRIGHTNESS, 0, },
+    { V4L2_CID_CONTRAST, 0, },
+    { V4L2_CID_SATURATION, 0, },
+    { V4L2_CID_SHARPNESS, 0, },
+};
+
+static void marucam_reset_controls(void)
+{
+    uint32_t i;
+    for (i = 0; i < ARRAY_SIZE(qctrl_tbl); i++) {
+        if (qctrl_tbl[i].hit) {
+            struct v4l2_control ctrl = {0,};
+            qctrl_tbl[i].hit = 0;
+            ctrl.id = qctrl_tbl[i].id;
+            ctrl.value = qctrl_tbl[i].init_val;
+            if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &ctrl) < 0) {
+                ERR("Failed to reset control value: id(0x%x), errstr(%s)\n",
+                    ctrl.id, strerror(errno));
+            }
+        }
+    }
+}
+
+static int32_t value_convert_from_guest(int32_t min, int32_t max, int32_t value)
+{
+    double rate = 0.0;
+    int32_t dist = 0, ret = 0;
+
+    dist = max - min;
+
+    if (dist < MARUCAM_CTRL_VALUE_MAX) {
+        rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;
+        ret = min + (int32_t)(value / rate);
+    } else {
+        rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;
+        ret = min + (int32_t)(rate * value);
+    }
+    return ret;
+}
+
+static int32_t value_convert_to_guest(int32_t min, int32_t max, int32_t value)
+{
+    double rate  = 0.0;
+    int32_t dist = 0, ret = 0;
+
+    dist = max - min;
+
+    if (dist < MARUCAM_CTRL_VALUE_MAX) {
+        rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;
+        ret = (int32_t)((double)(value - min) * rate);
+    } else {
+        rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;
+        ret = (int32_t)((double)(value - min) / rate);
+    }
+
+    return ret;
+}
+
+static void set_maxframeinterval(MaruCamState *state, uint32_t pixel_format,
+                        uint32_t width, uint32_t height)
+{
+    struct v4l2_frmivalenum fival;
+    struct v4l2_streamparm sp;
+    uint32_t min_num = 0, min_denom = 0;
+
+    CLEAR(fival);
+    fival.pixel_format = pixel_format;
+    fival.width = width;
+    fival.height = height;
+
+    if (xioctl(v4l2_fd, VIDIOC_ENUM_FRAMEINTERVALS, &fival) < 0) {
+        ERR("Unable to enumerate intervals for pixelformat(0x%x), (%d:%d)\n",
+            pixel_format, width, height);
+        return;
+    }
+
+    if (fival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
+        float max_ival = -1.0;
+        do {
+            float cur_ival = (float)fival.discrete.numerator
+                        / (float)fival.discrete.denominator;
+            if (cur_ival > max_ival) {
+                max_ival = cur_ival;
+                min_num = fival.discrete.numerator;
+                min_denom = fival.discrete.denominator;
+            }
+            TRACE("Discrete frame interval %u/%u supported\n",
+                 fival.discrete.numerator, fival.discrete.denominator);
+            fival.index++;
+        } while (xioctl(v4l2_fd, VIDIOC_ENUM_FRAMEINTERVALS, &fival) >= 0);
+    } else if ((fival.type == V4L2_FRMIVAL_TYPE_STEPWISE) ||
+                (fival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS)) {
+        TRACE("Frame intervals from %u/%u to %u/%u supported",
+            fival.stepwise.min.numerator, fival.stepwise.min.denominator,
+            fival.stepwise.max.numerator, fival.stepwise.max.denominator);
+        if (fival.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
+            TRACE("with %u/%u step", fival.stepwise.step.numerator,
+                  fival.stepwise.step.denominator);
+        }
+        if (((float)fival.stepwise.max.denominator /
+             (float)fival.stepwise.max.numerator) >
+            ((float)fival.stepwise.min.denominator /
+             (float)fival.stepwise.min.numerator)) {
+            min_num = fival.stepwise.max.numerator;
+            min_denom = fival.stepwise.max.denominator;
+        } else {
+            min_num = fival.stepwise.min.numerator;
+            min_denom = fival.stepwise.min.denominator;
+        }
+    }
+    TRACE("The actual min values: %u/%u\n", min_num, min_denom);
+
+    CLEAR(sp);
+    sp.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    sp.parm.capture.timeperframe.numerator = min_num;
+    sp.parm.capture.timeperframe.denominator = min_denom;
+
+    if (xioctl(v4l2_fd, VIDIOC_S_PARM, &sp) < 0) {
+        ERR("Failed to set to minimum FPS(%u/%u)\n", min_num, min_denom);
+    }
+}
+
+static uint32_t stop_capturing(void)
+{
+    enum v4l2_buf_type type;
+
+    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    if (xioctl(v4l2_fd, VIDIOC_STREAMOFF, &type) < 0) {
+        ERR("Failed to ioctl() with VIDIOC_STREAMOFF: %s\n", strerror(errno));
+        return errno;
+    }
+    return 0;
+}
+
+static uint32_t start_capturing(void)
+{
+    enum v4l2_buf_type type;
+
+    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    if (xioctl(v4l2_fd, VIDIOC_STREAMON, &type) < 0) {
+        ERR("Failed to ioctl() with VIDIOC_STREAMON: %s\n", strerror(errno));
+        return errno;
+    }
+    return 0;
+}
+
+static void free_framebuffers(marucam_framebuffer *fb, int buf_num)
+{
+    int i;
+
+    if (fb == NULL) {
+        ERR("The framebuffer is NULL. Failed to release the framebuffer\n");
+        return;
+    } else if (buf_num == 0) {
+        ERR("The buffer count is 0. Failed to release the framebuffer\n");
+        return;
+    } else {
+        TRACE("[%s]:fb(0x%p), buf_num(%d)\n", __func__, fb, buf_num);
+    }
+
+    /* Unmap framebuffers. */
+    for (i = 0; i < buf_num; i++) {
+        if (fb[i].data != NULL) {
+            v4l2_munmap(fb[i].data, fb[i].size);
+            fb[i].data = NULL;
+            fb[i].size = 0;
+        } else {
+            ERR("framebuffer[%d].data is NULL.\n", i);
+        }
+    }
+}
+
+static uint32_t
+mmap_framebuffers(marucam_framebuffer **fb, int *buf_num)
+{
+    struct v4l2_requestbuffers req;
+
+    CLEAR(req);
+    req.count   = MARUCAM_DEFAULT_BUFFER_COUNT;
+    req.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    req.memory  = V4L2_MEMORY_MMAP;
+    if (xioctl(v4l2_fd, VIDIOC_REQBUFS, &req) < 0) {
+        if (errno == EINVAL) {
+            ERR("%s does not support memory mapping: %s\n",
+                dev_name, strerror(errno));
+        } else {
+            ERR("Failed to request bufs: %s\n", strerror(errno));
+        }
+        return errno;
+    }
+    if (req.count == 0) {
+        ERR("Insufficient buffer memory on %s\n", dev_name);
+        return EINVAL;
+    }
+
+    *fb = g_new0(marucam_framebuffer, req.count);
+    if (*fb == NULL) {
+        ERR("Not enough memory to allocate framebuffers\n");
+        return ENOMEM;
+    }
+
+    for (*buf_num = 0; *buf_num < req.count; ++*buf_num) {
+        struct v4l2_buffer buf;
+        CLEAR(buf);
+        buf.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+        buf.memory  = V4L2_MEMORY_MMAP;
+        buf.index   = *buf_num;
+        if (xioctl(v4l2_fd, VIDIOC_QUERYBUF, &buf) < 0) {
+            ERR("Failed to ioctl() with VIDIOC_QUERYBUF: %s\n",
+                strerror(errno));
+            return errno;
+        }
+
+        (*fb)[*buf_num].size = buf.length;
+        (*fb)[*buf_num].data = v4l2_mmap(NULL,
+                     buf.length,
+                     PROT_READ | PROT_WRITE,
+                     MAP_SHARED,
+                     v4l2_fd, buf.m.offset);
+        if (MAP_FAILED == (*fb)[*buf_num].data) {
+            ERR("Failed to mmap: %s\n", strerror(errno));
+            return errno;
+        }
+
+        /* Queue the mapped buffer. */
+        CLEAR(buf);
+        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+        buf.memory = V4L2_MEMORY_MMAP;
+        buf.index = *buf_num;
+        if (xioctl(v4l2_fd, VIDIOC_QBUF, &buf) < 0) {
+            ERR("Failed to ioctl() with VIDIOC_QBUF: %s\n", strerror(errno));
+            return errno;
+        }
+    }
+    return 0;
+}
+
+static int is_streamon(MaruCamState *state)
+{
+    int st;
+    qemu_mutex_lock(&state->thread_mutex);
+    st = state->streamon;
+    qemu_mutex_unlock(&state->thread_mutex);
+    return (st == _MC_THREAD_STREAMON);
+}
+
+static int is_stream_paused(MaruCamState *state)
+{
+    int st;
+    qemu_mutex_lock(&state->thread_mutex);
+    st = state->streamon;
+    qemu_mutex_unlock(&state->thread_mutex);
+    return (st == _MC_THREAD_PAUSED);
+}
+
+/* sends a frame, YU12/black color  */
+static void __raise_empty_intr(MaruCamState *state)
+{
+    void *buf = NULL;
+    qemu_mutex_lock(&state->thread_mutex);
+    if (state->streamon == _MC_THREAD_STREAMON && state->req_frame) {
+        buf = state->vaddr + state->buf_size * (state->req_frame - 1);
+        make_yu12_black(buf, dst_fmt.fmt.pix.width, dst_fmt.fmt.pix.height);
+        state->req_frame = 0; /* clear request */
+        state->isr = 0x01;   /* set a flag of raising a interrupt */
+        qemu_bh_schedule(state->tx_bh);
+    }
+    qemu_mutex_unlock(&state->thread_mutex);
+}
+
+static void __raise_err_intr(MaruCamState *state)
+{
+    qemu_mutex_lock(&state->thread_mutex);
+    if (state->streamon == _MC_THREAD_STREAMON) {
+        state->req_frame = 0; /* clear request */
+        state->isr = 0x08;   /* set a error flag of raising a interrupt */
+        qemu_bh_schedule(state->tx_bh);
+    }
+    qemu_mutex_unlock(&state->thread_mutex);
+}
+
+static void
+notify_buffer_ready(MaruCamState *state, void *ptr, size_t size)
+{
+    void *buf = NULL;
+
+    qemu_mutex_lock(&state->thread_mutex);
+    if (state->streamon == _MC_THREAD_STREAMON) {
+        if (ready_count < MARUCAM_SKIPFRAMES) {
+            /* skip a frame cause first some frame are distorted */
+            ++ready_count;
+            TRACE("Skip %d frame\n", ready_count);
+            qemu_mutex_unlock(&state->thread_mutex);
+            return;
+        }
+        if (state->req_frame == 0) {
+            TRACE("There is no request\n");
+            qemu_mutex_unlock(&state->thread_mutex);
+            return;
+        }
+        buf = state->vaddr + state->buf_size * (state->req_frame - 1);
+        memcpy(buf, ptr, state->buf_size);
+        state->req_frame = 0; /* clear request */
+        state->isr |= 0x01;   /* set a flag of rasing a interrupt */
+        qemu_bh_schedule(state->tx_bh);
+    }
+    qemu_mutex_unlock(&state->thread_mutex);
+}
+
+static int read_frame(MaruCamState *state)
+{
+    struct v4l2_buffer buf;
+
+    CLEAR(buf);
+    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    buf.memory = V4L2_MEMORY_MMAP;
+    if (xioctl(v4l2_fd, VIDIOC_DQBUF, &buf) < 0) {
+        switch (errno) {
+        case EAGAIN:
+        case EINTR:
+            ERR("DQBUF error, try again: %s\n", strerror(errno));
+            return 0;
+        case EIO:
+            ERR("The v4l2_read() met the EIO\n");
+            if (convert_trial-- == -1) {
+                ERR("Try count for v4l2_read is exceeded: %s\n",
+                    strerror(errno));
+                return -1;
+            }
+            return 0;
+        default:
+            ERR("DQBUF error: %s\n", strerror(errno));
+            return -1;
+        }
+    }
+
+    notify_buffer_ready(state, framebuffer[buf.index].data, buf.bytesused);
+
+    if (xioctl(v4l2_fd, VIDIOC_QBUF, &buf) < 0) {
+        ERR("QBUF error: %s\n", strerror(errno));
+        return -1;
+    }
+    return 0;
+}
+
+static int __v4l2_streaming(MaruCamState *state)
+{
+    fd_set fds;
+    struct timeval tv;
+    int ret;
+
+    FD_ZERO(&fds);
+    FD_SET(v4l2_fd, &fds);
+
+    tv.tv_sec = 1;
+    tv.tv_usec = 0;
+
+    ret = select(v4l2_fd + 1, &fds, NULL, NULL, &tv);
+    if (ret < 0) {
+        if (errno == EAGAIN || errno == EINTR) {
+            ERR("Select again: %s\n", strerror(errno));
+            return 0;
+        }
+        ERR("Failed to select: %s\n", strerror(errno));
+        __raise_err_intr(state);
+        return -1;
+    } else if (!ret) {
+        timeout_n++;
+        ERR("Select timed out: count(%u)\n", timeout_n);
+        if (ready_count == 0) {
+            if (timeout_n <= MARUCAM_DUMMYFRAME_COUNT) {
+                ERR("Sends dummy data to initialize the camera\n");
+                __raise_empty_intr(state);
+                return 0;
+            } else {
+                ERR("Webcam is busy, failed to a read frame."
+                    " Raises an error\n");
+                __raise_err_intr(state);
+                return -1;
+            }
+        }
+        if (timeout_n >= 5) {
+            ERR("Webcam is busy, failed to a read frame. Raises an error\n");
+            __raise_err_intr(state);
+            return -1;
+        }
+        return 0;
+    }
+
+    if (!v4l2_fd || (v4l2_fd == -1)) {
+        ERR("The file descriptor is closed or not opened\n");
+        __raise_err_intr(state);
+        return -1;
+    }
+
+    ret = read_frame(state);
+    if (ret < 0) {
+        ERR("Failed to operate the read_frame()\n");
+        __raise_err_intr(state);
+        return -1;
+    }
+
+    /* clear the skip count for select time-out */
+    if (timeout_n > 0) {
+        timeout_n = 0;
+    }
+
+    return 0;
+}
+
+/* Worker thread */
+static void *marucam_worker_thread(void *thread_param)
+{
+    MaruCamState *state = (MaruCamState *)thread_param;
+
+    while (1) {
+        qemu_mutex_lock(&state->thread_mutex);
+        state->streamon = _MC_THREAD_PAUSED;
+        qemu_cond_wait(&state->thread_cond, &state->thread_mutex);
+        qemu_mutex_unlock(&state->thread_mutex);
+
+        if (state->destroying) {
+            break;
+        }
+
+        convert_trial = 10;
+        ready_count = 0;
+        timeout_n = 0;
+        qemu_mutex_lock(&state->thread_mutex);
+        state->streamon = _MC_THREAD_STREAMON;
+        qemu_mutex_unlock(&state->thread_mutex);
+        INFO("Streaming on ......\n");
+
+        while (1) {
+            if (is_streamon(state)) {
+                if (__v4l2_streaming(state) < 0) {
+                    INFO("...... Streaming off\n");
+                    break;
+                }
+            } else {
+                INFO("...... Streaming off\n");
+                break;
+            }
+        }
+    }
+
+    return NULL;
+}
+
+int marucam_device_check(int log_flag)
+{
+    int tmp_fd;
+    struct timeval t1, t2;
+    struct stat st;
+    struct v4l2_fmtdesc format;
+    struct v4l2_frmsizeenum size;
+    struct v4l2_capability cap;
+    int ret = 0;
+
+    gettimeofday(&t1, NULL);
+    if (stat(dev_name, &st) < 0) {
+        fprintf(stdout, "[Webcam] <WARNING> Cannot identify '%s': %s\n",
+                dev_name, strerror(errno));
+    } else {
+        if (!S_ISCHR(st.st_mode)) {
+            fprintf(stdout, "[Webcam] <WARNING>%s is no character device\n",
+                    dev_name);
+        }
+    }
+
+    tmp_fd = open(dev_name, O_RDWR | O_NONBLOCK, 0);
+    if (tmp_fd < 0) {
+        fprintf(stdout, "[Webcam] Camera device open failed: %s\n", dev_name);
+        gettimeofday(&t2, NULL);
+        fprintf(stdout, "[Webcam] Elapsed time: %lu:%06lu\n",
+                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+    if (ioctl(tmp_fd, VIDIOC_QUERYCAP, &cap) < 0) {
+        fprintf(stdout, "[Webcam] Could not qeury video capabilities\n");
+        close(tmp_fd);
+        gettimeofday(&t2, NULL);
+        fprintf(stdout, "[Webcam] Elapsed time: %lu:%06lu\n",
+                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+    if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) ||
+            !(cap.capabilities & V4L2_CAP_STREAMING)) {
+        fprintf(stdout, "[Webcam] Not supported video driver\n");
+        close(tmp_fd);
+        gettimeofday(&t2, NULL);
+        fprintf(stdout, "[Webcam] Elapsed time: %lu:%06lu\n",
+                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+    ret = 1;
+
+    if (log_flag) {
+        fprintf(stdout, "[Webcam] Driver: %s\n", cap.driver);
+        fprintf(stdout, "[Webcam] Card:  %s\n", cap.card);
+        fprintf(stdout, "[Webcam] Bus info: %s\n", cap.bus_info);
+
+        CLEAR(format);
+        format.index = 0;
+        format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+        if (yioctl(tmp_fd, VIDIOC_ENUM_FMT, &format) < 0) {
+            close(tmp_fd);
+            gettimeofday(&t2, NULL);
+            fprintf(stdout, "[Webcam] Elapsed time: %lu:%06lu\n",
+                    t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+            return ret;
+        }
+
+        do {
+            CLEAR(size);
+            size.index = 0;
+            size.pixel_format = format.pixelformat;
+
+            fprintf(stdout, "[Webcam] PixelFormat: %c%c%c%c\n",
+                             (char)(format.pixelformat),
+                             (char)(format.pixelformat >> 8),
+                             (char)(format.pixelformat >> 16),
+                             (char)(format.pixelformat >> 24));
+
+            if (yioctl(tmp_fd, VIDIOC_ENUM_FRAMESIZES, &size) < 0) {
+                close(tmp_fd);
+                gettimeofday(&t2, NULL);
+                fprintf(stdout, "[Webcam] Elapsed time: %lu:%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+                return ret;
+            }
+
+            if (size.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
+                do {
+                    fprintf(stdout, "[Webcam] got discrete frame size %dx%d\n",
+                                    size.discrete.width, size.discrete.height);
+                    size.index++;
+                } while (yioctl(tmp_fd, VIDIOC_ENUM_FRAMESIZES, &size) >= 0);
+            } else if (size.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
+                fprintf(stdout, "[Webcam] we have stepwise frame sizes:\n");
+                fprintf(stdout, "[Webcam] min width: %d, min height: %d\n",
+                        size.stepwise.min_width, size.stepwise.min_height);
+                fprintf(stdout, "[Webcam] max width: %d, max height: %d\n",
+                        size.stepwise.max_width, size.stepwise.max_height);
+                fprintf(stdout, "[Webcam] step width: %d, step height: %d\n",
+                        size.stepwise.step_width, size.stepwise.step_height);
+            } else if (size.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) {
+                fprintf(stdout, "[Webcam] we have continuous frame sizes:\n");
+                fprintf(stdout, "[Webcam] min width: %d, min height: %d\n",
+                        size.stepwise.min_width, size.stepwise.min_height);
+                fprintf(stdout, "[Webcam] max width: %d, max height: %d\n",
+                        size.stepwise.max_width, size.stepwise.max_height);
+
+            }
+            format.index++;
+        } while (yioctl(tmp_fd, VIDIOC_ENUM_FMT, &format) >= 0);
+    }
+
+    close(tmp_fd);
+    gettimeofday(&t2, NULL);
+    fprintf(stdout, "[Webcam] Elapsed time: %lu:%06lu\n",
+                    t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+    return ret;
+}
+
+void marucam_device_init(MaruCamState *state)
+{
+    state->destroying = false;
+    qemu_thread_create(&state->thread_id, marucam_worker_thread, (void *)state,
+            QEMU_THREAD_JOINABLE);
+}
+
+void marucam_device_exit(MaruCamState *state)
+{
+    state->destroying = true;
+    qemu_mutex_lock(&state->thread_mutex);
+    qemu_cond_signal(&state->thread_cond);
+    qemu_mutex_unlock(&state->thread_mutex);
+    qemu_thread_join(&state->thread_id);
+}
+
+void marucam_device_open(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    v4l2_fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0);
+    if (v4l2_fd < 0) {
+        ERR("The v4l2 device open failed: %s\n", dev_name);
+        param->errCode = EINVAL;
+        return;
+    }
+    INFO("Opened\n");
+
+    /* FIXME : Do not use fixed values */
+    CLEAR(dst_fmt);
+    dst_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    dst_fmt.fmt.pix.width = 640;
+    dst_fmt.fmt.pix.height = 480;
+    dst_fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+    dst_fmt.fmt.pix.field = V4L2_FIELD_ANY;
+
+    if (xioctl(v4l2_fd, VIDIOC_S_FMT, &dst_fmt) < 0) {
+        ERR("Failed to set video format: format(0x%x), width:height(%d:%d), "
+          "errstr(%s)\n", dst_fmt.fmt.pix.pixelformat, dst_fmt.fmt.pix.width,
+          dst_fmt.fmt.pix.height, strerror(errno));
+        param->errCode = errno;
+        return;
+    }
+    TRACE("Set the default format: w:h(%dx%d), fmt(0x%x), size(%d), "
+         "color(%d), field(%d)\n",
+         dst_fmt.fmt.pix.width, dst_fmt.fmt.pix.height,
+         dst_fmt.fmt.pix.pixelformat, dst_fmt.fmt.pix.sizeimage,
+         dst_fmt.fmt.pix.colorspace, dst_fmt.fmt.pix.field);
+}
+
+void marucam_device_start_preview(MaruCamState *state)
+{
+    struct timespec req;
+    MaruCamParam *param = state->param;
+    param->top = 0;
+    req.tv_sec = 0;
+    req.tv_nsec = 10000000;
+
+    INFO("Pixfmt(%c%c%c%C), W:H(%d:%d), buf size(%u)\n",
+         (char)(dst_fmt.fmt.pix.pixelformat),
+         (char)(dst_fmt.fmt.pix.pixelformat >> 8),
+         (char)(dst_fmt.fmt.pix.pixelformat >> 16),
+         (char)(dst_fmt.fmt.pix.pixelformat >> 24),
+         dst_fmt.fmt.pix.width,
+         dst_fmt.fmt.pix.height,
+         dst_fmt.fmt.pix.sizeimage);
+
+    param->errCode = mmap_framebuffers(&framebuffer, &n_framebuffer);
+    if (param->errCode) {
+        ERR("Failed to mmap framebuffers\n");
+        if (framebuffer != NULL) {
+            free_framebuffers(framebuffer, n_framebuffer);
+            g_free(framebuffer);
+            framebuffer = NULL;
+            n_framebuffer = 0;
+        }
+        return;
+    }
+
+    param->errCode = start_capturing();
+    if (param->errCode) {
+        if (framebuffer != NULL) {
+            free_framebuffers(framebuffer, n_framebuffer);
+            g_free(framebuffer);
+            framebuffer = NULL;
+            n_framebuffer = 0;
+        }
+        return;
+    }
+
+    INFO("Starting preview\n");
+    state->buf_size = dst_fmt.fmt.pix.sizeimage;
+    qemu_mutex_lock(&state->thread_mutex);
+    qemu_cond_signal(&state->thread_cond);
+    qemu_mutex_unlock(&state->thread_mutex);
+
+    /* nanosleep until thread is streamon  */
+    while (!is_streamon(state)) {
+        nanosleep(&req, NULL);
+    }
+}
+
+void marucam_device_stop_preview(MaruCamState *state)
+{
+    struct timespec req;
+    struct v4l2_requestbuffers reqbuf;
+    MaruCamParam *param = state->param;
+    param->top = 0;
+    req.tv_sec = 0;
+    req.tv_nsec = 50000000;
+
+    if (is_streamon(state)) {
+        qemu_mutex_lock(&state->thread_mutex);
+        state->streamon = _MC_THREAD_STREAMOFF;
+        qemu_mutex_unlock(&state->thread_mutex);
+
+        /* nanosleep until thread is paused  */
+        while (!is_stream_paused(state)) {
+            nanosleep(&req, NULL);
+        }
+    }
+
+    param->errCode = stop_capturing();
+    if (framebuffer != NULL) {
+        free_framebuffers(framebuffer, n_framebuffer);
+        g_free(framebuffer);
+        framebuffer = NULL;
+        n_framebuffer = 0;
+    }
+    state->buf_size = 0;
+
+    reqbuf.count = 0;
+    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    reqbuf.memory = V4L2_MEMORY_MMAP;
+    if (xioctl(v4l2_fd, VIDIOC_REQBUFS, &reqbuf) < 0) {
+        ERR("Failed to ioctl() with VIDIOC_REQBUF in stop_preview: %s\n",
+            strerror(errno));
+    }
+    INFO("Stopping preview\n");
+}
+
+void marucam_device_s_param(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+
+    /* If KVM enabled, We use default FPS of the webcam.
+     * If KVM disabled, we use mininum FPS of the webcam */
+    if (!kvm_enabled()) {
+        set_maxframeinterval(state, dst_fmt.fmt.pix.pixelformat,
+                     dst_fmt.fmt.pix.width,
+                     dst_fmt.fmt.pix.height);
+    }
+}
+
+void marucam_device_g_param(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+
+    /* We use default FPS of the webcam
+     * return a fixed value on guest ini file (1/30).
+     */
+    param->top = 0;
+    param->stack[0] = 0x1000; /* V4L2_CAP_TIMEPERFRAME */
+    param->stack[1] = 1; /* numerator */
+    param->stack[2] = 30; /* denominator */
+}
+
+void marucam_device_s_fmt(MaruCamState *state)
+{
+    struct v4l2_format format;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    CLEAR(format);
+    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    format.fmt.pix.width = param->stack[0];
+    format.fmt.pix.height = param->stack[1];
+    format.fmt.pix.pixelformat = param->stack[2];
+    format.fmt.pix.field = V4L2_FIELD_ANY;
+
+    if (xioctl(v4l2_fd, VIDIOC_S_FMT, &format) < 0) {
+        ERR("Failed to set video format: format(0x%x), width:height(%d:%d), "
+          "errstr(%s)\n", format.fmt.pix.pixelformat, format.fmt.pix.width,
+          format.fmt.pix.height, strerror(errno));
+        param->errCode = errno;
+        return;
+    }
+
+    memcpy(&dst_fmt, &format, sizeof(format));
+    param->stack[0] = dst_fmt.fmt.pix.width;
+    param->stack[1] = dst_fmt.fmt.pix.height;
+    param->stack[2] = dst_fmt.fmt.pix.field;
+    param->stack[3] = dst_fmt.fmt.pix.pixelformat;
+    param->stack[4] = dst_fmt.fmt.pix.bytesperline;
+    param->stack[5] = dst_fmt.fmt.pix.sizeimage;
+    param->stack[6] = dst_fmt.fmt.pix.colorspace;
+    param->stack[7] = dst_fmt.fmt.pix.priv;
+    TRACE("Set the format: w:h(%dx%d), fmt(0x%x), size(%d), "
+         "color(%d), field(%d)\n",
+         dst_fmt.fmt.pix.width, dst_fmt.fmt.pix.height,
+         dst_fmt.fmt.pix.pixelformat, dst_fmt.fmt.pix.sizeimage,
+         dst_fmt.fmt.pix.colorspace, dst_fmt.fmt.pix.field);
+}
+
+void marucam_device_g_fmt(MaruCamState *state)
+{
+    struct v4l2_format format;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    CLEAR(format);
+    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+    if (xioctl(v4l2_fd, VIDIOC_G_FMT, &format) < 0) {
+        ERR("Failed to get video format: %s\n", strerror(errno));
+        param->errCode = errno;
+    } else {
+        param->stack[0] = format.fmt.pix.width;
+        param->stack[1] = format.fmt.pix.height;
+        param->stack[2] = format.fmt.pix.field;
+        param->stack[3] = format.fmt.pix.pixelformat;
+        param->stack[4] = format.fmt.pix.bytesperline;
+        param->stack[5] = format.fmt.pix.sizeimage;
+        param->stack[6] = format.fmt.pix.colorspace;
+        param->stack[7] = format.fmt.pix.priv;
+        TRACE("Get the format: w:h(%dx%d), fmt(0x%x), size(%d), "
+             "color(%d), field(%d)\n",
+             format.fmt.pix.width, format.fmt.pix.height,
+             format.fmt.pix.pixelformat, format.fmt.pix.sizeimage,
+             format.fmt.pix.colorspace, format.fmt.pix.field);
+    }
+}
+
+void marucam_device_try_fmt(MaruCamState *state)
+{
+    struct v4l2_format format;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    CLEAR(format);
+    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    format.fmt.pix.width = param->stack[0];
+    format.fmt.pix.height = param->stack[1];
+    format.fmt.pix.pixelformat = param->stack[2];
+    format.fmt.pix.field = V4L2_FIELD_ANY;
+
+    if (xioctl(v4l2_fd, VIDIOC_TRY_FMT, &format) < 0) {
+        ERR("Failed to check video format: format(0x%x), width:height(%d:%d),"
+            " errstr(%s)\n", format.fmt.pix.pixelformat, format.fmt.pix.width,
+            format.fmt.pix.height, strerror(errno));
+        param->errCode = errno;
+        return;
+    }
+    param->stack[0] = format.fmt.pix.width;
+    param->stack[1] = format.fmt.pix.height;
+    param->stack[2] = format.fmt.pix.field;
+    param->stack[3] = format.fmt.pix.pixelformat;
+    param->stack[4] = format.fmt.pix.bytesperline;
+    param->stack[5] = format.fmt.pix.sizeimage;
+    param->stack[6] = format.fmt.pix.colorspace;
+    param->stack[7] = format.fmt.pix.priv;
+    TRACE("Check the format: w:h(%dx%d), fmt(0x%x), size(%d), "
+         "color(%d), field(%d)\n",
+         format.fmt.pix.width, format.fmt.pix.height,
+         format.fmt.pix.pixelformat, format.fmt.pix.sizeimage,
+         format.fmt.pix.colorspace, format.fmt.pix.field);
+}
+
+void marucam_device_enum_fmt(MaruCamState *state)
+{
+    uint32_t index;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    index = param->stack[0];
+
+    if (index >= ARRAY_SIZE(supported_dst_pixfmts)) {
+        param->errCode = EINVAL;
+        return;
+    }
+    param->stack[1] = 0; /* flags = NONE */
+    param->stack[2] = supported_dst_pixfmts[index].fmt; /* pixelformat */
+    /* set description */
+    switch (supported_dst_pixfmts[index].fmt) {
+    case V4L2_PIX_FMT_YUYV:
+        memcpy(&param->stack[3], "YUYV", 32);
+        break;
+    case V4L2_PIX_FMT_YUV420:
+        memcpy(&param->stack[3], "YU12", 32);
+        break;
+    case V4L2_PIX_FMT_YVU420:
+        memcpy(&param->stack[3], "YV12", 32);
+        break;
+    default:
+        ERR("Invalid fixel format\n");
+        param->errCode = EINVAL;
+        break;
+    }
+}
+
+void marucam_device_qctrl(MaruCamState *state)
+{
+    uint32_t i;
+    char name[32] = {0,};
+    struct v4l2_queryctrl ctrl;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    CLEAR(ctrl);
+    ctrl.id = param->stack[0];
+
+    switch (ctrl.id) {
+    case V4L2_CID_BRIGHTNESS:
+        TRACE("Query : BRIGHTNESS\n");
+        memcpy((void *)name, (void *)"brightness", 32);
+        i = 0;
+        break;
+    case V4L2_CID_CONTRAST:
+        TRACE("Query : CONTRAST\n");
+        memcpy((void *)name, (void *)"contrast", 32);
+        i = 1;
+        break;
+    case V4L2_CID_SATURATION:
+        TRACE("Query : SATURATION\n");
+        memcpy((void *)name, (void *)"saturation", 32);
+        i = 2;
+        break;
+    case V4L2_CID_SHARPNESS:
+        TRACE("Query : SHARPNESS\n");
+        memcpy((void *)name, (void *)"sharpness", 32);
+        i = 3;
+        break;
+    default:
+        ERR("Invalid control ID\n");
+        param->errCode = EINVAL;
+        return;
+    }
+
+    if (xioctl(v4l2_fd, VIDIOC_QUERYCTRL, &ctrl) < 0) {
+        if (errno != EINVAL) {
+            ERR("Failed to query video controls: %s\n", strerror(errno));
+        }
+        param->errCode = errno;
+        return;
+    } else {
+        struct v4l2_control sctrl;
+        CLEAR(sctrl);
+        sctrl.id = ctrl.id;
+        if ((ctrl.maximum + ctrl.minimum) == 0) {
+            sctrl.value = 0;
+        } else {
+            sctrl.value = (ctrl.maximum + ctrl.minimum) / 2;
+        }
+        if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &sctrl) < 0) {
+            ERR("Failed to set control value: id(0x%x), value(%d), "
+                "errstr(%s)\n", sctrl.id, sctrl.value, strerror(errno));
+            param->errCode = errno;
+            return;
+        }
+        qctrl_tbl[i].hit = 1;
+        qctrl_tbl[i].min = ctrl.minimum;
+        qctrl_tbl[i].max = ctrl.maximum;
+        qctrl_tbl[i].step = ctrl.step;
+        qctrl_tbl[i].init_val = ctrl.default_value;
+    }
+
+    /* set fixed values by FW configuration file */
+    param->stack[0] = ctrl.id;
+    param->stack[1] = MARUCAM_CTRL_VALUE_MIN;    /* minimum */
+    param->stack[2] = MARUCAM_CTRL_VALUE_MAX;    /* maximum */
+    param->stack[3] = MARUCAM_CTRL_VALUE_STEP;   /* step */
+    param->stack[4] = MARUCAM_CTRL_VALUE_MID;    /* default_value */
+    param->stack[5] = ctrl.flags;
+    /* name field setting */
+    memcpy(&param->stack[6], (void *)name, sizeof(ctrl.name));
+}
+
+void marucam_device_s_ctrl(MaruCamState *state)
+{
+    uint32_t i;
+    struct v4l2_control ctrl;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    CLEAR(ctrl);
+    ctrl.id = param->stack[0];
+
+    switch (ctrl.id) {
+    case V4L2_CID_BRIGHTNESS:
+        i = 0;
+        TRACE("%d is set to the value of the BRIGHTNESS\n", param->stack[1]);
+        break;
+    case V4L2_CID_CONTRAST:
+        i = 1;
+        TRACE("%d is set to the value of the CONTRAST\n", param->stack[1]);
+        break;
+    case V4L2_CID_SATURATION:
+        i = 2;
+        TRACE("%d is set to the value of the SATURATION\n", param->stack[1]);
+        break;
+    case V4L2_CID_SHARPNESS:
+        i = 3;
+        TRACE("%d is set to the value of the SHARPNESS\n", param->stack[1]);
+        break;
+    default:
+        ERR("Our emulator does not support this control: 0x%x\n", ctrl.id);
+        param->errCode = EINVAL;
+        return;
+    }
+
+    ctrl.value = value_convert_from_guest(qctrl_tbl[i].min,
+            qctrl_tbl[i].max, param->stack[1]);
+    if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &ctrl) < 0) {
+        ERR("Failed to set control value: id(0x%x), value(r:%d, c:%d), "
+            "errstr(%s)\n", ctrl.id, param->stack[1], ctrl.value,
+            strerror(errno));
+        param->errCode = errno;
+        return;
+    }
+}
+
+void marucam_device_g_ctrl(MaruCamState *state)
+{
+    uint32_t i;
+    struct v4l2_control ctrl;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    CLEAR(ctrl);
+    ctrl.id = param->stack[0];
+
+    switch (ctrl.id) {
+    case V4L2_CID_BRIGHTNESS:
+        TRACE("Gets the value of the BRIGHTNESS\n");
+        i = 0;
+        break;
+    case V4L2_CID_CONTRAST:
+        TRACE("Gets the value of the CONTRAST\n");
+        i = 1;
+        break;
+    case V4L2_CID_SATURATION:
+        TRACE("Gets the value of the SATURATION\n");
+        i = 2;
+        break;
+    case V4L2_CID_SHARPNESS:
+        TRACE("Gets the value of the SHARPNESS\n");
+        i = 3;
+        break;
+    default:
+        ERR("Our emulator does not support this control: 0x%x\n", ctrl.id);
+        param->errCode = EINVAL;
+        return;
+    }
+
+    if (xioctl(v4l2_fd, VIDIOC_G_CTRL, &ctrl) < 0) {
+        ERR("Failed to get video control value: %s\n", strerror(errno));
+        param->errCode = errno;
+        return;
+    }
+    param->stack[0] = value_convert_to_guest(qctrl_tbl[i].min,
+            qctrl_tbl[i].max, ctrl.value);
+    TRACE("Value: %d\n", param->stack[0]);
+}
+
+void marucam_device_enum_fsizes(MaruCamState *state)
+{
+    uint32_t index, pixfmt, i;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    index = param->stack[0];
+    pixfmt = param->stack[1];
+
+    if (index >= ARRAY_SIZE(supported_dst_frames)) {
+        param->errCode = EINVAL;
+        return;
+    }
+    for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) {
+        if (supported_dst_pixfmts[i].fmt == pixfmt) {
+            break;
+        }
+    }
+
+    if (i == ARRAY_SIZE(supported_dst_pixfmts)) {
+        param->errCode = EINVAL;
+        return;
+    }
+
+    param->stack[0] = supported_dst_frames[index].width;
+    param->stack[1] = supported_dst_frames[index].height;
+}
+
+void marucam_device_enum_fintv(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+
+    /* switch by index(param->stack[0]) */
+    switch (param->stack[0]) {
+    case 0:
+        /* we only use 1/30 frame interval */
+        param->stack[1] = 30;   /* denominator */
+        break;
+    default:
+        param->errCode = EINVAL;
+        return;
+    }
+    param->stack[0] = 1;    /* numerator */
+}
+
+void marucam_device_close(MaruCamState *state)
+{
+    if (!is_stream_paused(state)) {
+        marucam_device_stop_preview(state);
+    }
+
+    marucam_reset_controls();
+
+    v4l2_close(v4l2_fd);
+    v4l2_fd = 0;
+    INFO("Closed\n");
+}
index 9c0e126..11e0e24 100644 (file)
-/*\r
- * Interface definition header for Windows host.\r
- *\r
- * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Contact:\r
- * JinHyung Jo <jinhyung.jo@samsung.com>\r
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
- *\r
- * Contributors:\r
- * - S-Core Co., Ltd\r
- *\r
- */\r
-\r
-#ifndef _MARU_CAMERA_INTERFACE_H_\r
-#define _MARU_CAMERA_INTERFACE_H_\r
-\r
-static const WCHAR HWCPinName[] = L"HWCInputPin\0";\r
-static const WCHAR HWCFilterName[] = L"HWCFilter\0";\r
-\r
-/* Forward Declarations */\r
-FWD_DECL(IBaseFilter);\r
-FWD_DECL(IFilterGraph);\r
-\r
-/* defines */\r
-#define MAX_PIN_NAME     128\r
-#define MAX_FILTER_NAME  128\r
-\r
-#define DECLARE_INTERFACE2(i) \\r
-   _COM_interface i { CONST_VTABLE struct i##Vtbl *lpVtbl; }; \\r
-   typedef CONST_VTABLE struct i##Vtbl i##Vtbl; \\r
-   CONST_VTABLE struct i##Vtbl\r
-#define DECLARE_INTERFACE2_(i,b) DECLARE_INTERFACE2(i)\r
-\r
-typedef LONGLONG REFERENCE_TIME;\r
-typedef long OAFilterState;\r
-typedef DWORD_PTR HSEMAPHORE;\r
-typedef DWORD_PTR HEVENT;\r
-\r
-typedef enum _FilterState {\r
-  State_Stopped,\r
-  State_Paused,\r
-  State_Running\r
-} FILTER_STATE;\r
-\r
-typedef struct _FilterInfo {\r
-  WCHAR achName[MAX_FILTER_NAME];\r
-  IFilterGraph *pGraph;\r
-} FILTER_INFO;\r
-\r
-typedef enum _PinDirection\r
-{   PINDIR_INPUT    = 0,\r
-    PINDIR_OUTPUT   = ( PINDIR_INPUT + 1 )\r
-} PIN_DIRECTION;\r
-\r
-typedef struct _PinInfo {\r
-  IBaseFilter *pFilter;\r
-  PIN_DIRECTION dir;\r
-  WCHAR achName[MAX_PIN_NAME];\r
-} PIN_INFO;\r
-\r
-typedef struct _AllocatorProperties {\r
-  long cBuffers;\r
-  long cbBuffer;\r
-  long cbAlign;\r
-  long cbPrefix;\r
-} ALLOCATOR_PROPERTIES;\r
-\r
-typedef struct _AMMediaType {\r
-  GUID majortype;\r
-  GUID subtype;\r
-  BOOL bFixedSizeSamples;\r
-  BOOL bTemporalCompression;\r
-  ULONG lSampleSize;\r
-  GUID formattype;\r
-  IUnknown *pUnk;\r
-  ULONG cbFormat;\r
-  BYTE *pbFormat;\r
-} AM_MEDIA_TYPE;\r
-\r
-typedef enum tagVideoProcAmpFlags {\r
-    VideoProcAmp_Flags_Auto = 0x0001,\r
-    VideoProcAmp_Flags_Manual = 0x0002\r
-} VideoProcAmpFlags;\r
-\r
-typedef enum tagVideoProcAmpProperty {\r
-    VideoProcAmp_Brightness,\r
-    VideoProcAmp_Contrast,\r
-    VideoProcAmp_Hue,\r
-    VideoProcAmp_Saturation,\r
-    VideoProcAmp_Sharpness,\r
-    VideoProcAmp_Gamma,\r
-    VideoProcAmp_ColorEnable,\r
-    VideoProcAmp_WhiteBalance,\r
-    VideoProcAmp_BacklightCompensation,\r
-    VideoProcAmp_Gain\r
-} VideoProcAmpProperty;\r
-\r
-typedef struct tagVIDEOINFOHEADER {\r
-    RECT rcSource;\r
-    RECT rcTarget;\r
-    DWORD dwBitRate;\r
-    DWORD dwBitErrorRate;\r
-    REFERENCE_TIME AvgTimePerFrame;\r
-    BITMAPINFOHEADER bmiHeader;\r
-} VIDEOINFOHEADER;\r
-\r
-typedef struct _VIDEO_STREAM_CONFIG_CAPS\r
-{\r
-  GUID guid;\r
-  ULONG VideoStandard;\r
-  SIZE InputSize;\r
-  SIZE MinCroppingSize;\r
-  SIZE MaxCroppingSize;\r
-  int CropGranularityX;\r
-  int CropGranularityY;\r
-  int CropAlignX;\r
-  int CropAlignY;\r
-  SIZE MinOutputSize;\r
-  SIZE MaxOutputSize;\r
-  int OutputGranularityX;\r
-  int OutputGranularityY;\r
-  int StretchTapsX;\r
-  int StretchTapsY;\r
-  int ShrinkTapsX;\r
-  int ShrinkTapsY;\r
-  LONGLONG MinFrameInterval;\r
-  LONGLONG MaxFrameInterval;\r
-  LONG MinBitsPerSecond;\r
-  LONG MaxBitsPerSecond;\r
-} VIDEO_STREAM_CONFIG_CAPS;\r
-\r
-\r
-/* Interface & Class GUIDs */\r
-static const IID IID_IGrabCallback   = {0x4C337035,0xC89E,0x4B42,{0x9B,0x0C,0x36,0x74,0x44,0xDD,0x70,0xDD}};\r
-\r
-EXTERN_C const IID IID_IBaseFilter;\r
-EXTERN_C const IID IID_ICreateDevEnum;\r
-EXTERN_C const IID IID_IGraphBuilder;\r
-EXTERN_C const IID IID_IMediaSeeking;\r
-EXTERN_C const IID IID_IMediaEventSink;\r
-EXTERN_C const IID IID_IMemInputPin;\r
-EXTERN_C const IID IID_IEnumPins;\r
-EXTERN_C const IID IID_IMediaFilter;\r
-EXTERN_C const IID IID_IEnumMediaTypes;\r
-EXTERN_C const IID IID_IMemAllocator;\r
-EXTERN_C const IID IID_IPin;\r
-EXTERN_C const IID IID_ICaptureGraphBuilder2;\r
-EXTERN_C const IID IID_IFileSinkFilter;\r
-EXTERN_C const IID IID_IAMCopyCaptureFileProgress;\r
-EXTERN_C const IID IID_IEnumFilters;\r
-EXTERN_C const IID IID_IMediaSample;\r
-EXTERN_C const IID IID_IMediaControl;\r
-EXTERN_C const IID IID_IAMStreamConfig;\r
-EXTERN_C const IID IID_IAMVideoProcAmp;\r
-\r
-EXTERN_C const IID CLSID_CaptureGraphBuilder2;\r
-EXTERN_C const IID CLSID_VideoInputDeviceCategory;\r
-EXTERN_C const IID CLSID_AudioRender;\r
-EXTERN_C const IID CLSID_SystemDeviceEnum;\r
-EXTERN_C const IID CLSID_AudioRendererCategory;\r
-EXTERN_C const IID CLSID_FilterGraph;\r
-EXTERN_C const IID CLSID_InfTee;\r
-EXTERN_C const IID CLSID_VideoMixingRenderer9;\r
-EXTERN_C const IID CLSID_MemoryAllocator;\r
-\r
-\r
-/* other types GUIDs*/\r
-EXTERN_C const IID MEDIATYPE_Audio;\r
-EXTERN_C const IID MEDIATYPE_Video;\r
-EXTERN_C const IID MEDIATYPE_Stream;\r
-EXTERN_C const IID MEDIASUBTYPE_PCM;\r
-EXTERN_C const IID MEDIASUBTYPE_WAVE;\r
-EXTERN_C const IID MEDIASUBTYPE_Avi;\r
-EXTERN_C const IID MEDIASUBTYPE_RGB32;\r
-EXTERN_C const IID MEDIASUBTYPE_YV12;\r
-EXTERN_C const IID MEDIASUBTYPE_YUY2;\r
-EXTERN_C const IID MEDIASUBTYPE_I420;\r
-EXTERN_C const IID MEDIASUBTYPE_YUYV;\r
-EXTERN_C const IID FORMAT_WaveFormatEx;\r
-EXTERN_C const IID FORMAT_VideoInfo;\r
-EXTERN_C const IID FORMAT_VideoInfo2;\r
-EXTERN_C const IID PIN_CATEGORY_CAPTURE;\r
-EXTERN_C const IID PIN_CATEGORY_PREVIEW;\r
-\r
-\r
-#define MEDIATYPE_NULL       GUID_NULL\r
-#define MEDIASUBTYPE_NULL    GUID_NULL\r
-\r
-#define INTERFACE IGrabCallback\r
-DECLARE_INTERFACE_(IGrabCallback, IUnknown)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(Grab)(THIS_ ULONG,BYTE*) PURE;\r
-};\r
-#undef INTERFACE\r
-\r
-#ifdef COBJMACROS\r
-#define IGrabCallback_QueryInterface(T,a,b) (T)->lpVtbl->QueryInterface(T,a,b)\r
-#define IGrabCallback_AddRef(T) (T)->lpVtbl->AddRef(T)\r
-#define IGrabCallback_Release(T) (T)->lpVtbl->Release(T)\r
-#define IGrabCallback_Grab(T,a,b) (T)->lpVtbl->Grab(T,a,b)\r
-#endif /* COBJMACROS */\r
-\r
-#define INTERFACE IAMCopyCaptureFileProgress\r
-DECLARE_INTERFACE_(IAMCopyCaptureFileProgress, IUnknown)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(Progress)(THIS_ int) PURE;\r
-};\r
-#undef INTERFACE\r
-#define INTERFACE IReferenceClock\r
-DECLARE_INTERFACE_(IReferenceClock, IUnknown)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(GetTime)(THIS_ REFERENCE_TIME *) PURE;\r
-    STDMETHOD(AdviseTime)(THIS_ REFERENCE_TIME, REFERENCE_TIME, HEVENT, DWORD_PTR *) PURE;\r
-    STDMETHOD(AdvisePeriodic)(THIS_ REFERENCE_TIME, REFERENCE_TIME, HSEMAPHORE, DWORD_PTR *) PURE;\r
-    STDMETHOD(Unadvise)(THIS_ DWORD_PTR) PURE;\r
-};\r
-#undef INTERFACE\r
-#define INTERFACE IEnumFilters\r
-DECLARE_INTERFACE_(IEnumFilters, IUnknown)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(Next)(THIS_ ULONG, IBaseFilter **, ULONG *) PURE;\r
-    STDMETHOD(Skip)(THIS_ ULONG) PURE;\r
-    STDMETHOD(Reset)(THIS) PURE;\r
-    STDMETHOD(Clone)(THIS_ IEnumFilters **) PURE;\r
-};\r
-#undef INTERFACE\r
-#define INTERFACE IEnumMediaTypes\r
-DECLARE_INTERFACE_(IEnumMediaTypes, IUnknown)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(Next)(THIS_ ULONG, AM_MEDIA_TYPE **, ULONG *) PURE;\r
-    STDMETHOD(Skip)(THIS_ ULONG) PURE;\r
-    STDMETHOD(Reset)(THIS) PURE;\r
-    STDMETHOD(Clone)(THIS_ IEnumMediaTypes **) PURE;\r
-};\r
-#undef INTERFACE\r
-#define INTERFACE IPin\r
-DECLARE_INTERFACE_(IPin, IUnknown)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(Connect)(THIS_ IPin *, const AM_MEDIA_TYPE *) PURE;\r
-    STDMETHOD(ReceiveConnection)(THIS_ IPin *, const AM_MEDIA_TYPE *) PURE;\r
-    STDMETHOD(Disconnect)(THIS) PURE;\r
-    STDMETHOD(ConnectedTo)(THIS_ IPin **) PURE;\r
-    STDMETHOD(ConnectionMediaType)(THIS_ AM_MEDIA_TYPE *) PURE;\r
-    STDMETHOD(QueryPinInfo)(THIS_ PIN_INFO *) PURE;\r
-    STDMETHOD(QueryDirection)(THIS_ PIN_DIRECTION *) PURE;\r
-    STDMETHOD(QueryId)(THIS_ LPWSTR *) PURE;\r
-    STDMETHOD(QueryAccept)(THIS_ const AM_MEDIA_TYPE *) PURE;\r
-    STDMETHOD(EnumMediaTypes)(THIS_ IEnumMediaTypes **) PURE;\r
-    STDMETHOD(QueryInternalConnections)(THIS_ IPin **, ULONG *) PURE;\r
-    STDMETHOD(EndOfStream)(THIS) PURE;\r
-    STDMETHOD(BeginFlush)(THIS) PURE;\r
-    STDMETHOD(EndFlush)(THIS) PURE;\r
-    STDMETHOD(NewSegment)(THIS_ REFERENCE_TIME, REFERENCE_TIME, double) PURE;\r
-};\r
-#undef INTERFACE\r
-#define INTERFACE IEnumPins\r
-DECLARE_INTERFACE_(IEnumPins, IUnknown)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(Next)(THIS_ ULONG, IPin **, ULONG *) PURE;\r
-    STDMETHOD(Skip)(THIS_ ULONG) PURE;\r
-    STDMETHOD(Reset)(THIS) PURE;\r
-    STDMETHOD(Clone)(THIS_ IEnumPins **) PURE;\r
-};\r
-#undef INTERFACE\r
-#define INTERFACE IMediaFilter\r
-DECLARE_INTERFACE_(IMediaFilter, IPersist)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(GetClassID)(THIS_ CLSID*) PURE;\r
-    STDMETHOD(Stop)(THIS) PURE;\r
-    STDMETHOD(Pause)(THIS) PURE;\r
-    STDMETHOD(Run)(THIS_ REFERENCE_TIME) PURE;\r
-    STDMETHOD(GetState)(THIS_ DWORD, FILTER_STATE *) PURE;\r
-    STDMETHOD(SetSyncSource)(THIS_ IReferenceClock *) PURE;\r
-    STDMETHOD(GetSyncSource)(THIS_ IReferenceClock **) PURE;\r
-};\r
-#undef INTERFACE\r
-#define INTERFACE IBaseFilter\r
-DECLARE_INTERFACE2_(IBaseFilter, IMediaFilter)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(GetClassID)(THIS_ CLSID*) PURE;\r
-    STDMETHOD(Stop)(THIS) PURE;\r
-    STDMETHOD(Pause)(THIS) PURE;\r
-    STDMETHOD(Run)(THIS_ REFERENCE_TIME) PURE;\r
-    STDMETHOD(GetState)(THIS_ DWORD, FILTER_STATE *) PURE;\r
-    STDMETHOD(SetSyncSource)(THIS_ IReferenceClock *) PURE;\r
-    STDMETHOD(GetSyncSource)(THIS_ IReferenceClock **) PURE;\r
-    STDMETHOD(EnumPins)(THIS_ IEnumPins **) PURE;\r
-    STDMETHOD(FindPin)(THIS_ LPCWSTR, IPin **) PURE;\r
-    STDMETHOD(QueryFilterInfo)(THIS_ FILTER_INFO *) PURE;\r
-    STDMETHOD(JoinFilterGraph)(THIS_ IFilterGraph *, LPCWSTR) PURE;\r
-    STDMETHOD(QueryVendorInfo)(THIS_ LPWSTR *) PURE;\r
-};\r
-#undef INTERFACE\r
-#define INTERFACE IFilterGraph\r
-DECLARE_INTERFACE2_(IFilterGraph, IUnknown)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(AddFilter)(THIS_ IBaseFilter *, LPCWSTR) PURE;\r
-    STDMETHOD(RemoveFilter)(THIS_ IBaseFilter *) PURE;\r
-    STDMETHOD(EnumFilters)(THIS_ IEnumFilters **) PURE;\r
-    STDMETHOD(FindFilterByName)(THIS_ LPCWSTR, IBaseFilter **) PURE;\r
-    STDMETHOD(ConnectDirect)(THIS_ IPin *, IPin *, const AM_MEDIA_TYPE *) PURE;\r
-    STDMETHOD(Reconnect)(THIS_ IPin *) PURE;\r
-    STDMETHOD(Disconnect)(THIS_ IPin *) PURE;\r
-    STDMETHOD(SetDefaultSyncSource)(THIS) PURE;\r
-};\r
-#undef INTERFACE\r
-#define INTERFACE IGraphBuilder\r
-DECLARE_INTERFACE_(IGraphBuilder ,IFilterGraph)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(AddFilter)(THIS_ IBaseFilter *, LPCWSTR) PURE;\r
-    STDMETHOD(RemoveFilter)(THIS_ IBaseFilter *) PURE;\r
-    STDMETHOD(EnumFilters)(THIS_ IEnumFilters **) PURE;\r
-    STDMETHOD(FindFilterByName)(THIS_ LPCWSTR, IBaseFilter **) PURE;\r
-    STDMETHOD(ConnectDirect)(THIS_ IPin *, IPin *, const AM_MEDIA_TYPE *) PURE;\r
-    STDMETHOD(Reconnect)(THIS_ IPin *) PURE;\r
-    STDMETHOD(Disconnect)(THIS_ IPin *) PURE;\r
-    STDMETHOD(SetDefaultSyncSource)(THIS) PURE;\r
-    STDMETHOD(Connect)(THIS_ IPin *, IPin *) PURE;\r
-    STDMETHOD(Render)(THIS_ IPin *) PURE;\r
-    STDMETHOD(RenderFile)(THIS_ LPCWSTR, LPCWSTR) PURE;\r
-    STDMETHOD(AddSourceFilter)(THIS_ LPCWSTR, LPCWSTR, IBaseFilter **) PURE;\r
-    STDMETHOD(SetLogFile)(THIS_ DWORD_PTR) PURE;\r
-    STDMETHOD(Abort)(THIS) PURE;\r
-    STDMETHOD(ShouldOperationContinue)(THIS) PURE;\r
-};\r
-#undef INTERFACE\r
-#define INTERFACE ICreateDevEnum\r
-DECLARE_INTERFACE_(ICreateDevEnum, IUnknown)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(CreateClassEnumerator)(THIS_ REFCLSID, IEnumMoniker **, DWORD) PURE;\r
-};\r
-#undef INTERFACE\r
-#define INTERFACE IMediaSample\r
-DECLARE_INTERFACE_(IMediaSample, IUnknown)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(GetPointer)(THIS_ BYTE **) PURE;\r
-    STDMETHOD_(long, GetSize)(THIS) PURE;\r
-    STDMETHOD(GetTime)(THIS_ REFERENCE_TIME *, REFERENCE_TIME *) PURE;\r
-    STDMETHOD(SetTime)(THIS_ REFERENCE_TIME *, REFERENCE_TIME *) PURE;\r
-    STDMETHOD(IsSyncPoint)(THIS) PURE;\r
-    STDMETHOD(SetSyncPoint)(THIS_ BOOL) PURE;\r
-    STDMETHOD(IsPreroll)(THIS) PURE;\r
-    STDMETHOD(SetPreroll)(THIS_ BOOL) PURE;\r
-    STDMETHOD_(long, GetActualDataLength)(THIS) PURE;\r
-    STDMETHOD(SetActualDataLength)(THIS_ long) PURE;\r
-    STDMETHOD(GetMediaType)(THIS_ AM_MEDIA_TYPE **) PURE;\r
-    STDMETHOD(SetMediaType)(THIS_ AM_MEDIA_TYPE *) PURE;\r
-    STDMETHOD(IsDiscontinuity)(THIS) PURE;\r
-    STDMETHOD(SetDiscontinuity)(THIS_ BOOL) PURE;\r
-    STDMETHOD(GetMediaTime)(THIS_ LONGLONG *, LONGLONG *) PURE;\r
-    STDMETHOD(SetMediaTime)(THIS_ LONGLONG *, LONGLONG *) PURE;\r
-};\r
-#undef INTERFACE\r
-#define INTERFACE IMemAllocator\r
-DECLARE_INTERFACE_(IMemAllocator, IUnknown)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(SetProperties)(THIS_ ALLOCATOR_PROPERTIES *, ALLOCATOR_PROPERTIES *) PURE;\r
-    STDMETHOD(GetProperties)(THIS_ ALLOCATOR_PROPERTIES *) PURE;\r
-    STDMETHOD(Commit)(THIS) PURE;\r
-    STDMETHOD(Decommit)(THIS) PURE;\r
-    STDMETHOD(GetBuffer)(THIS_ IMediaSample **, REFERENCE_TIME *, REFERENCE_TIME *, DWORD) PURE;\r
-    STDMETHOD(ReleaseBuffer)(THIS_ IMediaSample *) PURE;\r
-\r
-};\r
-#undef INTERFACE\r
-#define INTERFACE IMemInputPin\r
-DECLARE_INTERFACE_(IMemInputPin, IUnknown)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(GetAllocator)(THIS_ IMemAllocator **) PURE;\r
-    STDMETHOD(NotifyAllocator)(THIS_ IMemAllocator *, BOOL) PURE;\r
-    STDMETHOD(GetAllocatorRequirements)(THIS_ ALLOCATOR_PROPERTIES *) PURE;\r
-    STDMETHOD(Receive)(THIS_ IMediaSample *) PURE;\r
-    STDMETHOD(ReceiveMultiple)(THIS_ IMediaSample **, long, long *) PURE;\r
-    STDMETHOD(ReceiveCanBlock)(THIS) PURE;\r
-};\r
-#undef INTERFACE\r
-#define INTERFACE IFileSinkFilter\r
-DECLARE_INTERFACE_(IFileSinkFilter, IUnknown)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(SetFileName)(THIS_ LPCOLESTR,const AM_MEDIA_TYPE *) PURE;\r
-    STDMETHOD(GetCurFile)(THIS_ LPOLESTR *,AM_MEDIA_TYPE*) PURE;\r
-};\r
-#undef INTERFACE\r
-#define INTERFACE ICaptureGraphBuilder2\r
-DECLARE_INTERFACE_(ICaptureGraphBuilder2, IUnknown)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(SetFiltergraph)(THIS_ IGraphBuilder*) PURE;\r
-    STDMETHOD(GetFiltergraph)(THIS_ IGraphBuilder**) PURE;\r
-    STDMETHOD(SetOutputFileName)(THIS_ const GUID*,LPCOLESTR,IBaseFilter**,IFileSinkFilter**) PURE;\r
-    STDMETHOD(FindInterface)(THIS_ const GUID*,const GUID*,IBaseFilter*,REFIID,void**) PURE;\r
-    STDMETHOD(RenderStream)(THIS_ const GUID*,const GUID*,IUnknown*,IBaseFilter*,IBaseFilter*) PURE;\r
-    STDMETHOD(ControlStream)(THIS_ const GUID*,const GUID*,IBaseFilter*,REFERENCE_TIME*,REFERENCE_TIME*,WORD,WORD) PURE;\r
-    STDMETHOD(AllocCapFile)(THIS_ LPCOLESTR,DWORDLONG) PURE;\r
-    STDMETHOD(CopyCaptureFile)(THIS_ LPOLESTR,LPOLESTR,int,IAMCopyCaptureFileProgress*) PURE;\r
-    STDMETHOD(FindPin)(THIS_ IUnknown*,PIN_DIRECTION,const GUID*,const GUID*,BOOL,int,IPin**) PURE;\r
-};\r
-#undef INTERFACE\r
-#define INTERFACE IAMStreamConfig\r
-DECLARE_INTERFACE_(IAMStreamConfig, IUnknown)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(SetFormat)(THIS_ AM_MEDIA_TYPE*) PURE;\r
-    STDMETHOD(GetFormat)(THIS_ AM_MEDIA_TYPE**) PURE;\r
-    STDMETHOD(GetNumberOfCapabilities)(THIS_ int*,int*) PURE;\r
-    STDMETHOD(GetStreamCaps)(THIS_ int,AM_MEDIA_TYPE**,BYTE*) PURE;\r
-};\r
-#undef INTERFACE\r
-#define INTERFACE IAMVideoProcAmp\r
-DECLARE_INTERFACE_(IAMVideoProcAmp, IUnknown)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(GetRange)(THIS_ long,long*,long*,long*,long*,long*) PURE;\r
-    STDMETHOD(Set)(THIS_ long,long,long) PURE;\r
-    STDMETHOD(Get)(THIS_ long,long*,long*) PURE;\r
-};\r
-#undef INTERFACE\r
-#define INTERFACE IMediaControl\r
-DECLARE_INTERFACE_(IMediaControl, IDispatch)\r
-{\r
-    STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;\r
-    STDMETHOD_(ULONG,AddRef)(THIS) PURE;\r
-    STDMETHOD_(ULONG,Release)(THIS) PURE;\r
-    STDMETHOD(GetTypeInfoCount)(THIS_ UINT*);\r
-    STDMETHOD(GetTypeInfo)(THIS_ UINT,LCID,ITypeInfo**);\r
-    STDMETHOD(GetIDsOfNames)(THIS_ REFIID,LPOLESTR*,UINT,LCID,DISPID*);\r
-    STDMETHOD(Invoke)(THIS_ DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*);\r
-    STDMETHOD(Run)(THIS);\r
-    STDMETHOD(Pause)(THIS);\r
-    STDMETHOD(Stop)(THIS);\r
-    STDMETHOD(GetState)(THIS_ LONG, OAFilterState*);\r
-    STDMETHOD(RenderFile)(THIS_ BSTR);\r
-    STDMETHOD(AddSourceFilter)(THIS_ BSTR,IDispatch**);\r
-    STDMETHOD(get_FilterCollection)(THIS_ IDispatch**);\r
-    STDMETHOD(get_RegFilterCollection)(THIS_ IDispatch**);\r
-    STDMETHOD(StopWhenReady)(THIS);\r
-};\r
-#undef INTERFACE\r
-\r
-#ifdef COBJMACROS\r
-#define ICreateDevEnum_QueryInterface(This,riid,ppvObject)  \\r
-    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
-#define ICreateDevEnum_AddRef(This) \\r
-    ( (This)->lpVtbl -> AddRef(This) )\r
-#define ICreateDevEnum_Release(This)    \\r
-    ( (This)->lpVtbl -> Release(This) )\r
-#define ICreateDevEnum_CreateClassEnumerator(This,clsidDeviceClass,ppEnumMoniker,dwFlags)   \\r
-    ( (This)->lpVtbl -> CreateClassEnumerator(This,clsidDeviceClass,ppEnumMoniker,dwFlags) )\r
-#endif /* COBJMACROS */\r
-\r
-#ifdef COBJMACROS\r
-#define IPin_QueryInterface(This,riid,ppvObject)    \\r
-    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
-#define IPin_AddRef(This)   \\r
-    ( (This)->lpVtbl -> AddRef(This) )\r
-#define IPin_Release(This)  \\r
-    ( (This)->lpVtbl -> Release(This) )\r
-#define IPin_Connect(This,pReceivePin,pmt)  \\r
-    ( (This)->lpVtbl -> Connect(This,pReceivePin,pmt) )\r
-#define IPin_ReceiveConnection(This,pConnector,pmt) \\r
-    ( (This)->lpVtbl -> ReceiveConnection(This,pConnector,pmt) )\r
-#define IPin_Disconnect(This)   \\r
-    ( (This)->lpVtbl -> Disconnect(This) )\r
-#define IPin_ConnectedTo(This,pPin) \\r
-    ( (This)->lpVtbl -> ConnectedTo(This,pPin) )\r
-#define IPin_ConnectionMediaType(This,pmt)  \\r
-    ( (This)->lpVtbl -> ConnectionMediaType(This,pmt) )\r
-#define IPin_QueryPinInfo(This,pInfo)   \\r
-    ( (This)->lpVtbl -> QueryPinInfo(This,pInfo) )\r
-#define IPin_QueryDirection(This,pPinDir)   \\r
-    ( (This)->lpVtbl -> QueryDirection(This,pPinDir) )\r
-#define IPin_QueryId(This,Id)   \\r
-    ( (This)->lpVtbl -> QueryId(This,Id) )\r
-#define IPin_QueryAccept(This,pmt)  \\r
-    ( (This)->lpVtbl -> QueryAccept(This,pmt) )\r
-#define IPin_EnumMediaTypes(This,ppEnum)    \\r
-    ( (This)->lpVtbl -> EnumMediaTypes(This,ppEnum) )\r
-#define IPin_QueryInternalConnections(This,apPin,nPin)  \\r
-    ( (This)->lpVtbl -> QueryInternalConnections(This,apPin,nPin) )\r
-#define IPin_EndOfStream(This)  \\r
-    ( (This)->lpVtbl -> EndOfStream(This) )\r
-#define IPin_BeginFlush(This)   \\r
-    ( (This)->lpVtbl -> BeginFlush(This) )\r
-#define IPin_EndFlush(This) \\r
-    ( (This)->lpVtbl -> EndFlush(This) )\r
-#define IPin_NewSegment(This,tStart,tStop,dRate)    \\r
-    ( (This)->lpVtbl -> NewSegment(This,tStart,tStop,dRate) )\r
-#endif /* COBJMACROS */\r
-\r
-#ifdef COBJMACROS\r
-#define IEnumPins_QueryInterface(This,riid,ppvObject)   \\r
-    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
-#define IEnumPins_AddRef(This)  \\r
-    ( (This)->lpVtbl -> AddRef(This) )\r
-#define IEnumPins_Release(This) \\r
-    ( (This)->lpVtbl -> Release(This) )\r
-#define IEnumPins_Next(This,cPins,ppPins,pcFetched) \\r
-    ( (This)->lpVtbl -> Next(This,cPins,ppPins,pcFetched) )\r
-#define IEnumPins_Skip(This,cPins)  \\r
-    ( (This)->lpVtbl -> Skip(This,cPins) )\r
-#define IEnumPins_Reset(This)   \\r
-    ( (This)->lpVtbl -> Reset(This) )\r
-#define IEnumPins_Clone(This,ppEnum)    \\r
-    ( (This)->lpVtbl -> Clone(This,ppEnum) )\r
-#endif /* COBJMACROS */\r
-\r
-#ifdef COBJMACROS\r
-#define IAMStreamConfig_QueryInterface(This,riid,ppvObject) \\r
-    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
-#define IAMStreamConfig_AddRef(This)    \\r
-    ( (This)->lpVtbl -> AddRef(This) )\r
-#define IAMStreamConfig_Release(This)   \\r
-    ( (This)->lpVtbl -> Release(This) )\r
-#define IAMStreamConfig_SetFormat(This,pmt) \\r
-    ( (This)->lpVtbl -> SetFormat(This,pmt) )\r
-#define IAMStreamConfig_GetFormat(This,ppmt)    \\r
-    ( (This)->lpVtbl -> GetFormat(This,ppmt) )\r
-#define IAMStreamConfig_GetNumberOfCapabilities(This,piCount,piSize)    \\r
-    ( (This)->lpVtbl -> GetNumberOfCapabilities(This,piCount,piSize) )\r
-#define IAMStreamConfig_GetStreamCaps(This,iIndex,ppmt,pSCC)    \\r
-    ( (This)->lpVtbl -> GetStreamCaps(This,iIndex,ppmt,pSCC) )\r
-#endif /* COBJMACROS */\r
-\r
-#ifdef COBJMACROS\r
-#define IFilterGraph_QueryInterface(This,riid,ppvObject)    \\r
-    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
-#define IFilterGraph_AddRef(This)   \\r
-    ( (This)->lpVtbl -> AddRef(This) )\r
-#define IFilterGraph_Release(This)  \\r
-    ( (This)->lpVtbl -> Release(This) )\r
-#define IFilterGraph_AddFilter(This,pFilter,pName)  \\r
-    ( (This)->lpVtbl -> AddFilter(This,pFilter,pName) )\r
-#define IFilterGraph_RemoveFilter(This,pFilter) \\r
-    ( (This)->lpVtbl -> RemoveFilter(This,pFilter) )\r
-#define IFilterGraph_EnumFilters(This,ppEnum)   \\r
-    ( (This)->lpVtbl -> EnumFilters(This,ppEnum) )\r
-#define IFilterGraph_FindFilterByName(This,pName,ppFilter)  \\r
-    ( (This)->lpVtbl -> FindFilterByName(This,pName,ppFilter) )\r
-#define IFilterGraph_ConnectDirect(This,ppinOut,ppinIn,pmt) \\r
-    ( (This)->lpVtbl -> ConnectDirect(This,ppinOut,ppinIn,pmt) )\r
-#define IFilterGraph_Reconnect(This,ppin)   \\r
-    ( (This)->lpVtbl -> Reconnect(This,ppin) )\r
-#define IFilterGraph_Disconnect(This,ppin)  \\r
-    ( (This)->lpVtbl -> Disconnect(This,ppin) )\r
-#define IFilterGraph_SetDefaultSyncSource(This) \\r
-    ( (This)->lpVtbl -> SetDefaultSyncSource(This) )\r
-#endif /* COBJMACROS */\r
-\r
-#ifdef COBJMACROS\r
-#define IMediaFilter_QueryInterface(This,riid,ppvObject)    \\r
-    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
-#define IMediaFilter_AddRef(This)   \\r
-    ( (This)->lpVtbl -> AddRef(This) )\r
-#define IMediaFilter_Release(This)  \\r
-    ( (This)->lpVtbl -> Release(This) )\r
-#define IMediaFilter_GetClassID(This,pClassID)  \\r
-    ( (This)->lpVtbl -> GetClassID(This,pClassID) )\r
-#define IMediaFilter_Stop(This) \\r
-    ( (This)->lpVtbl -> Stop(This) )\r
-#define IMediaFilter_Pause(This)    \\r
-    ( (This)->lpVtbl -> Pause(This) )\r
-#define IMediaFilter_Run(This,tStart)   \\r
-    ( (This)->lpVtbl -> Run(This,tStart) )\r
-#define IMediaFilter_GetState(This,dwMilliSecsTimeout,State)    \\r
-    ( (This)->lpVtbl -> GetState(This,dwMilliSecsTimeout,State) )\r
-#define IMediaFilter_SetSyncSource(This,pClock) \\r
-    ( (This)->lpVtbl -> SetSyncSource(This,pClock) )\r
-#define IMediaFilter_GetSyncSource(This,pClock) \\r
-    ( (This)->lpVtbl -> GetSyncSource(This,pClock) )\r
-#endif /* COBJMACROS */\r
-\r
-#ifdef COBJMACROS\r
-#define IBaseFilter_QueryInterface(This,riid,ppvObject) \\r
-    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
-#define IBaseFilter_AddRef(This)    \\r
-    ( (This)->lpVtbl -> AddRef(This) )\r
-#define IBaseFilter_Release(This)   \\r
-    ( (This)->lpVtbl -> Release(This) )\r
-#define IBaseFilter_GetClassID(This,pClassID)   \\r
-    ( (This)->lpVtbl -> GetClassID(This,pClassID) )\r
-#define IBaseFilter_Stop(This)  \\r
-    ( (This)->lpVtbl -> Stop(This) )\r
-#define IBaseFilter_Pause(This) \\r
-    ( (This)->lpVtbl -> Pause(This) )\r
-#define IBaseFilter_Run(This,tStart)    \\r
-    ( (This)->lpVtbl -> Run(This,tStart) )\r
-#define IBaseFilter_GetState(This,dwMilliSecsTimeout,State) \\r
-    ( (This)->lpVtbl -> GetState(This,dwMilliSecsTimeout,State) )\r
-#define IBaseFilter_SetSyncSource(This,pClock)  \\r
-    ( (This)->lpVtbl -> SetSyncSource(This,pClock) )\r
-#define IBaseFilter_GetSyncSource(This,pClock)  \\r
-    ( (This)->lpVtbl -> GetSyncSource(This,pClock) )\r
-#define IBaseFilter_EnumPins(This,ppEnum)   \\r
-    ( (This)->lpVtbl -> EnumPins(This,ppEnum) )\r
-#define IBaseFilter_FindPin(This,Id,ppPin)  \\r
-    ( (This)->lpVtbl -> FindPin(This,Id,ppPin) )\r
-#define IBaseFilter_QueryFilterInfo(This,pInfo) \\r
-    ( (This)->lpVtbl -> QueryFilterInfo(This,pInfo) )\r
-#define IBaseFilter_JoinFilterGraph(This,pGraph,pName)  \\r
-    ( (This)->lpVtbl -> JoinFilterGraph(This,pGraph,pName) )\r
-#define IBaseFilter_QueryVendorInfo(This,pVendorInfo)   \\r
-    ( (This)->lpVtbl -> QueryVendorInfo(This,pVendorInfo) )\r
-#endif /* COBJMACROS */\r
-\r
-#ifdef COBJMACROS\r
-#define IMediaSample_QueryInterface(This,riid,ppvObject)    \\r
-    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
-#define IMediaSample_AddRef(This)   \\r
-    ( (This)->lpVtbl -> AddRef(This) )\r
-#define IMediaSample_Release(This)  \\r
-    ( (This)->lpVtbl -> Release(This) )\r
-#define IMediaSample_GetPointer(This,ppBuffer)  \\r
-    ( (This)->lpVtbl -> GetPointer(This,ppBuffer) )\r
-#define IMediaSample_GetSize(This)  \\r
-        ( (This)->lpVtbl -> GetSize(This) )\r
-#define IMediaSample_GetTime(This,pTimeStart,pTimeEnd)  \\r
-    ( (This)->lpVtbl -> GetTime(This,pTimeStart,pTimeEnd) )\r
-#define IMediaSample_SetTime(This,pTimeStart,pTimeEnd)  \\r
-    ( (This)->lpVtbl -> SetTime(This,pTimeStart,pTimeEnd) )\r
-#define IMediaSample_IsSyncPoint(This)  \\r
-    ( (This)->lpVtbl -> IsSyncPoint(This) )\r
-#define IMediaSample_SetSyncPoint(This,bIsSyncPoint)    \\r
-    ( (This)->lpVtbl -> SetSyncPoint(This,bIsSyncPoint) )\r
-#define IMediaSample_IsPreroll(This)    \\r
-    ( (This)->lpVtbl -> IsPreroll(This) )\r
-#define IMediaSample_SetPreroll(This,bIsPreroll)    \\r
-    ( (This)->lpVtbl -> SetPreroll(This,bIsPreroll) )\r
-#define IMediaSample_GetActualDataLength(This)  \\r
-    ( (This)->lpVtbl -> GetActualDataLength(This) )\r
-#define IMediaSample_SetActualDataLength(This,length)   \\r
-    ( (This)->lpVtbl -> SetActualDataLength(This,length) )\r
-#define IMediaSample_GetMediaType(This,ppMediaType) \\r
-    ( (This)->lpVtbl -> GetMediaType(This,ppMediaType) )\r
-#define IMediaSample_SetMediaType(This,pMediaType)  \\r
-    ( (This)->lpVtbl -> SetMediaType(This,pMediaType) )\r
-#define IMediaSample_IsDiscontinuity(This)  \\r
-    ( (This)->lpVtbl -> IsDiscontinuity(This) )\r
-#define IMediaSample_SetDiscontinuity(This,bDiscontinuity)  \\r
-    ( (This)->lpVtbl -> SetDiscontinuity(This,bDiscontinuity) )\r
-#define IMediaSample_GetMediaTime(This,pTimeStart,pTimeEnd) \\r
-    ( (This)->lpVtbl -> GetMediaTime(This,pTimeStart,pTimeEnd) )\r
-#define IMediaSample_SetMediaTime(This,pTimeStart,pTimeEnd) \\r
-    ( (This)->lpVtbl -> SetMediaTime(This,pTimeStart,pTimeEnd) )\r
-#endif /* COBJMACROS */\r
-\r
-#ifdef COBJMACROS\r
-#define IEnumFilters_QueryInterface(This,riid,ppvObject)    \\r
-    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
-#define IEnumFilters_AddRef(This)   \\r
-    ( (This)->lpVtbl -> AddRef(This) )\r
-#define IEnumFilters_Release(This)  \\r
-    ( (This)->lpVtbl -> Release(This) )\r
-#define IEnumFilters_Next(This,cFilters,ppFilter,pcFetched) \\r
-    ( (This)->lpVtbl -> Next(This,cFilters,ppFilter,pcFetched) )\r
-#define IEnumFilters_Skip(This,cFilters)    \\r
-    ( (This)->lpVtbl -> Skip(This,cFilters) )\r
-#define IEnumFilters_Reset(This)    \\r
-    ( (This)->lpVtbl -> Reset(This) )\r
-#define IEnumFilters_Clone(This,ppEnum) \\r
-    ( (This)->lpVtbl -> Clone(This,ppEnum) )\r
-#endif /* COBJMACROS */\r
-\r
-#ifdef COBJMACROS\r
-#define IMemAllocator_QueryInterface(This,riid,ppvObject)   \\r
-    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
-#define IMemAllocator_AddRef(This)  \\r
-    ( (This)->lpVtbl -> AddRef(This) )\r
-#define IMemAllocator_Release(This) \\r
-    ( (This)->lpVtbl -> Release(This) )\r
-#define IMemAllocator_SetProperties(This,pRequest,pActual)  \\r
-    ( (This)->lpVtbl -> SetProperties(This,pRequest,pActual) )\r
-#define IMemAllocator_GetProperties(This,pProps)    \\r
-    ( (This)->lpVtbl -> GetProperties(This,pProps) )\r
-#define IMemAllocator_Commit(This)  \\r
-    ( (This)->lpVtbl -> Commit(This) )\r
-#define IMemAllocator_Decommit(This)    \\r
-    ( (This)->lpVtbl -> Decommit(This) )\r
-#define IMemAllocator_GetBuffer(This,ppBuffer,pStartTime,pEndTime,dwFlags)  \\r
-    ( (This)->lpVtbl -> GetBuffer(This,ppBuffer,pStartTime,pEndTime,dwFlags) )\r
-#define IMemAllocator_ReleaseBuffer(This,pBuffer)   \\r
-    ( (This)->lpVtbl -> ReleaseBuffer(This,pBuffer) )\r
-#endif /* COBJMACROS */\r
-\r
-#ifdef COBJMACROS\r
-#define IMemInputPin_QueryInterface(This,riid,ppvObject)    \\r
-    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
-#define IMemInputPin_AddRef(This)   \\r
-    ( (This)->lpVtbl -> AddRef(This) )\r
-#define IMemInputPin_Release(This)  \\r
-    ( (This)->lpVtbl -> Release(This) )\r
-#define IMemInputPin_GetAllocator(This,ppAllocator) \\r
-    ( (This)->lpVtbl -> GetAllocator(This,ppAllocator) )\r
-#define IMemInputPin_NotifyAllocator(This,pAllocator,bReadOnly) \\r
-    ( (This)->lpVtbl -> NotifyAllocator(This,pAllocator,bReadOnly) )\r
-#define IMemInputPin_GetAllocatorRequirements(This,pProps)  \\r
-    ( (This)->lpVtbl -> GetAllocatorRequirements(This,pProps) )\r
-#define IMemInputPin_Receive(This,pSample)  \\r
-    ( (This)->lpVtbl -> Receive(This,pSample) )\r
-#define IMemInputPin_ReceiveMultiple(This,pSamples,nSamples,nSamplesProcessed)  \\r
-    ( (This)->lpVtbl -> ReceiveMultiple(This,pSamples,nSamples,nSamplesProcessed) )\r
-#define IMemInputPin_ReceiveCanBlock(This)  \\r
-    ( (This)->lpVtbl -> ReceiveCanBlock(This) )\r
-#endif /* COBJMACROS */\r
-\r
-#ifdef COBJMACROS\r
-#define IGraphBuilder_QueryInterface(This,riid,ppvObject)   \\r
-    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
-#define IGraphBuilder_AddRef(This)  \\r
-    ( (This)->lpVtbl -> AddRef(This) )\r
-#define IGraphBuilder_Release(This) \\r
-    ( (This)->lpVtbl -> Release(This) )\r
-#define IGraphBuilder_AddFilter(This,pFilter,pName) \\r
-    ( (This)->lpVtbl -> AddFilter(This,pFilter,pName) )\r
-#define IGraphBuilder_RemoveFilter(This,pFilter)    \\r
-    ( (This)->lpVtbl -> RemoveFilter(This,pFilter) )\r
-#define IGraphBuilder_EnumFilters(This,ppEnum)  \\r
-    ( (This)->lpVtbl -> EnumFilters(This,ppEnum) )\r
-#define IGraphBuilder_FindFilterByName(This,pName,ppFilter) \\r
-    ( (This)->lpVtbl -> FindFilterByName(This,pName,ppFilter) )\r
-#define IGraphBuilder_ConnectDirect(This,ppinOut,ppinIn,pmt)    \\r
-    ( (This)->lpVtbl -> ConnectDirect(This,ppinOut,ppinIn,pmt) )\r
-#define IGraphBuilder_Reconnect(This,ppin)  \\r
-    ( (This)->lpVtbl -> Reconnect(This,ppin) )\r
-#define IGraphBuilder_Disconnect(This,ppin) \\r
-    ( (This)->lpVtbl -> Disconnect(This,ppin) )\r
-#define IGraphBuilder_SetDefaultSyncSource(This)    \\r
-    ( (This)->lpVtbl -> SetDefaultSyncSource(This) )\r
-#define IGraphBuilder_Connect(This,ppinOut,ppinIn)  \\r
-    ( (This)->lpVtbl -> Connect(This,ppinOut,ppinIn) )\r
-#define IGraphBuilder_Render(This,ppinOut)  \\r
-    ( (This)->lpVtbl -> Render(This,ppinOut) )\r
-#define IGraphBuilder_RenderFile(This,lpcwstrFile,lpcwstrPlayList)  \\r
-    ( (This)->lpVtbl -> RenderFile(This,lpcwstrFile,lpcwstrPlayList) )\r
-#define IGraphBuilder_AddSourceFilter(This,lpcwstrFileName,lpcwstrFilterName,ppFilter)  \\r
-    ( (This)->lpVtbl -> AddSourceFilter(This,lpcwstrFileName,lpcwstrFilterName,ppFilter) )\r
-#define IGraphBuilder_SetLogFile(This,hFile)    \\r
-    ( (This)->lpVtbl -> SetLogFile(This,hFile) )\r
-#define IGraphBuilder_Abort(This)   \\r
-    ( (This)->lpVtbl -> Abort(This) )\r
-#define IGraphBuilder_ShouldOperationContinue(This) \\r
-    ( (This)->lpVtbl -> ShouldOperationContinue(This) )\r
-#endif /* COBJMACROS */\r
-\r
-#ifdef COBJMACROS\r
-#define IEnumMediaTypes_QueryInterface(This,riid,ppvObject) \\r
-    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
-#define IEnumMediaTypes_AddRef(This)    \\r
-    ( (This)->lpVtbl -> AddRef(This) )\r
-#define IEnumMediaTypes_Release(This)   \\r
-    ( (This)->lpVtbl -> Release(This) )\r
-#define IEnumMediaTypes_Next(This,cMediaTypes,ppMediaTypes,pcFetched)   \\r
-    ( (This)->lpVtbl -> Next(This,cMediaTypes,ppMediaTypes,pcFetched) )\r
-#define IEnumMediaTypes_Skip(This,cMediaTypes)  \\r
-    ( (This)->lpVtbl -> Skip(This,cMediaTypes) )\r
-#define IEnumMediaTypes_Reset(This) \\r
-    ( (This)->lpVtbl -> Reset(This) )\r
-#define IEnumMediaTypes_Clone(This,ppEnum)  \\r
-    ( (This)->lpVtbl -> Clone(This,ppEnum) )\r
-#endif /* COBJMACROS */\r
-\r
-#ifdef COBJMACROS\r
-#define IMediaControl_QueryInterface(This,riid,ppvObject)   \\r
-    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
-#define IMediaControl_AddRef(This)  \\r
-    ( (This)->lpVtbl -> AddRef(This) )\r
-#define IMediaControl_Release(This) \\r
-    ( (This)->lpVtbl -> Release(This) )\r
-#define IMediaControl_GetTypeInfoCount(This,pctinfo)    \\r
-    ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) )\r
-#define IMediaControl_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \\r
-    ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) )\r
-#define IMediaControl_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)   \\r
-    ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) )\r
-#define IMediaControl_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \\r
-    ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) )\r
-#define IMediaControl_Run(This) \\r
-    ( (This)->lpVtbl -> Run(This) )\r
-#define IMediaControl_Pause(This)   \\r
-    ( (This)->lpVtbl -> Pause(This) )\r
-#define IMediaControl_Stop(This)    \\r
-    ( (This)->lpVtbl -> Stop(This) )\r
-#define IMediaControl_GetState(This,msTimeout,pfs)  \\r
-    ( (This)->lpVtbl -> GetState(This,msTimeout,pfs) )\r
-#define IMediaControl_RenderFile(This,strFilename)  \\r
-    ( (This)->lpVtbl -> RenderFile(This,strFilename) )\r
-#define IMediaControl_AddSourceFilter(This,strFilename,ppUnk)   \\r
-    ( (This)->lpVtbl -> AddSourceFilter(This,strFilename,ppUnk) )\r
-#define IMediaControl_get_FilterCollection(This,ppUnk)  \\r
-    ( (This)->lpVtbl -> get_FilterCollection(This,ppUnk) )\r
-#define IMediaControl_get_RegFilterCollection(This,ppUnk)   \\r
-    ( (This)->lpVtbl -> get_RegFilterCollection(This,ppUnk) )\r
-#define IMediaControl_StopWhenReady(This)   \\r
-    ( (This)->lpVtbl -> StopWhenReady(This) )\r
-#endif /* COBJMACROS */\r
-\r
-#ifdef COBJMACROS\r
-#define IAMVideoProcAmp_QueryInterface(This,riid,ppvObject) \\r
-    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
-#define IAMVideoProcAmp_AddRef(This)    \\r
-    ( (This)->lpVtbl -> AddRef(This) )\r
-#define IAMVideoProcAmp_Release(This)   \\r
-    ( (This)->lpVtbl -> Release(This) )\r
-#define IAMVideoProcAmp_GetRange(This,Property,pMin,pMax,pSteppingDelta,pDefault,pCapsFlags)    \\r
-    ( (This)->lpVtbl -> GetRange(This,Property,pMin,pMax,pSteppingDelta,pDefault,pCapsFlags) )\r
-#define IAMVideoProcAmp_Set(This,Property,lValue,Flags) \\r
-    ( (This)->lpVtbl -> Set(This,Property,lValue,Flags) )\r
-#define IAMVideoProcAmp_Get(This,Property,lValue,Flags) \\r
-    ( (This)->lpVtbl -> Get(This,Property,lValue,Flags) )\r
-#endif /* COBJMACROS */\r
-\r
-#ifdef COBJMACROS\r
-#define IFileSinkFilter_QueryInterface(This,riid,ppvObject) \\r
-    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
-#define IFileSinkFilter_AddRef(This)    \\r
-    ( (This)->lpVtbl -> AddRef(This) )\r
-#define IFileSinkFilter_Release(This)   \\r
-    ( (This)->lpVtbl -> Release(This) )\r
-#define IFileSinkFilter_SetFileName(This,pszFileName,pmt)   \\r
-    ( (This)->lpVtbl -> SetFileName(This,pszFileName,pmt) )\r
-#define IFileSinkFilter_GetCurFile(This,ppszFileName,pmt)   \\r
-    ( (This)->lpVtbl -> GetCurFile(This,ppszFileName,pmt) )\r
-#endif /* COBJMACROS */\r
-\r
-#ifdef COBJMACROS\r
-#define IAMCopyCaptureFileProgress_QueryInterface(This,riid,ppvObject)  \\r
-    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
-#define IAMCopyCaptureFileProgress_AddRef(This) \\r
-    ( (This)->lpVtbl -> AddRef(This) )\r
-#define IAMCopyCaptureFileProgress_Release(This)    \\r
-    ( (This)->lpVtbl -> Release(This) )\r
-#define IAMCopyCaptureFileProgress_Progress(This,iProgress) \\r
-    ( (This)->lpVtbl -> Progress(This,iProgress) )\r
-#endif /* COBJMACROS */\r
-\r
-\r
-#ifdef COBJMACROS\r
-#define ICaptureGraphBuilder2_QueryInterface(This,riid,ppvObject)   \\r
-    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )\r
-#define ICaptureGraphBuilder2_AddRef(This)  \\r
-    ( (This)->lpVtbl -> AddRef(This) )\r
-#define ICaptureGraphBuilder2_Release(This) \\r
-    ( (This)->lpVtbl -> Release(This) )\r
-#define ICaptureGraphBuilder2_SetFiltergraph(This,pfg)  \\r
-    ( (This)->lpVtbl -> SetFiltergraph(This,pfg) )\r
-#define ICaptureGraphBuilder2_GetFiltergraph(This,ppfg) \\r
-    ( (This)->lpVtbl -> GetFiltergraph(This,ppfg) )\r
-#define ICaptureGraphBuilder2_SetOutputFileName(This,pType,lpstrFile,ppf,ppSink)    \\r
-    ( (This)->lpVtbl -> SetOutputFileName(This,pType,lpstrFile,ppf,ppSink) )\r
-#define ICaptureGraphBuilder2_FindInterface(This,pCategory,pType,pf,riid,ppint) \\r
-    ( (This)->lpVtbl -> FindInterface(This,pCategory,pType,pf,riid,ppint) )\r
-#define ICaptureGraphBuilder2_RenderStream(This,pCategory,pType,pSource,pfCompressor,pfRenderer)    \\r
-    ( (This)->lpVtbl -> RenderStream(This,pCategory,pType,pSource,pfCompressor,pfRenderer) )\r
-#define ICaptureGraphBuilder2_ControlStream(This,pCategory,pType,pFilter,pstart,pstop,wStartCookie,wStopCookie) \\r
-    ( (This)->lpVtbl -> ControlStream(This,pCategory,pType,pFilter,pstart,pstop,wStartCookie,wStopCookie) )\r
-#define ICaptureGraphBuilder2_AllocCapFile(This,lpstr,dwlSize)  \\r
-    ( (This)->lpVtbl -> AllocCapFile(This,lpstr,dwlSize) )\r
-#define ICaptureGraphBuilder2_CopyCaptureFile(This,lpwstrOld,lpwstrNew,fAllowEscAbort,pCallback)    \\r
-    ( (This)->lpVtbl -> CopyCaptureFile(This,lpwstrOld,lpwstrNew,fAllowEscAbort,pCallback) )\r
-#define ICaptureGraphBuilder2_FindPin(This,pSource,pindir,pCategory,pType,fUnconnected,num,ppPin)   \\r
-    ( (This)->lpVtbl -> FindPin(This,pSource,pindir,pCategory,pType,fUnconnected,num,ppPin) )\r
-#endif /* COBJMACROS */\r
-\r
-#endif // _MARU_CAMERA_INTERFACE_H_\r
+/*
+ * Interface definition header for Windows host.
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * 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 _MARU_CAMERA_INTERFACE_H_
+#define _MARU_CAMERA_INTERFACE_H_
+
+extern int hax_enabled(void);
+
+static const WCHAR HWCPinName[] = L"HWCInputPin\0";
+static const WCHAR HWCFilterName[] = L"HWCFilter\0";
+
+/* Forward Declarations */
+FWD_DECL(IBaseFilter);
+FWD_DECL(IFilterGraph);
+
+/* defines */
+#define MAX_PIN_NAME     128
+#define MAX_FILTER_NAME  128
+
+#define DECLARE_INTERFACE2(i) \
+   _COM_interface i { CONST_VTABLE struct i##Vtbl *lpVtbl; }; \
+   typedef CONST_VTABLE struct i##Vtbl i##Vtbl; \
+   CONST_VTABLE struct i##Vtbl
+#define DECLARE_INTERFACE2_(i, b) DECLARE_INTERFACE2(i)
+
+typedef LONGLONG REFERENCE_TIME;
+typedef long OAFilterState;
+typedef DWORD_PTR HSEMAPHORE;
+typedef DWORD_PTR HEVENT;
+
+typedef enum _FilterState {
+  State_Stopped,
+  State_Paused,
+  State_Running
+} FILTER_STATE;
+
+typedef struct _FilterInfo {
+  WCHAR achName[MAX_FILTER_NAME];
+  IFilterGraph *pGraph;
+} FILTER_INFO;
+
+typedef enum _PinDirection {
+    PINDIR_INPUT    = 0,
+    PINDIR_OUTPUT   = (PINDIR_INPUT + 1)
+} PIN_DIRECTION;
+
+typedef struct _PinInfo {
+  IBaseFilter *pFilter;
+  PIN_DIRECTION dir;
+  WCHAR achName[MAX_PIN_NAME];
+} PIN_INFO;
+
+typedef struct _AllocatorProperties {
+  long cBuffers;
+  long cbBuffer;
+  long cbAlign;
+  long cbPrefix;
+} ALLOCATOR_PROPERTIES;
+
+typedef struct _AMMediaType {
+  GUID majortype;
+  GUID subtype;
+  BOOL bFixedSizeSamples;
+  BOOL bTemporalCompression;
+  ULONG lSampleSize;
+  GUID formattype;
+  IUnknown *pUnk;
+  ULONG cbFormat;
+  BYTE *pbFormat;
+} AM_MEDIA_TYPE;
+
+typedef enum tagVideoProcAmpFlags {
+    VideoProcAmp_Flags_Auto = 0x0001,
+    VideoProcAmp_Flags_Manual = 0x0002
+} VideoProcAmpFlags;
+
+typedef enum tagVideoProcAmpProperty {
+    VideoProcAmp_Brightness,
+    VideoProcAmp_Contrast,
+    VideoProcAmp_Hue,
+    VideoProcAmp_Saturation,
+    VideoProcAmp_Sharpness,
+    VideoProcAmp_Gamma,
+    VideoProcAmp_ColorEnable,
+    VideoProcAmp_WhiteBalance,
+    VideoProcAmp_BacklightCompensation,
+    VideoProcAmp_Gain
+} VideoProcAmpProperty;
+
+typedef struct tagVIDEOINFOHEADER {
+    RECT rcSource;
+    RECT rcTarget;
+    DWORD dwBitRate;
+    DWORD dwBitErrorRate;
+    REFERENCE_TIME AvgTimePerFrame;
+    BITMAPINFOHEADER bmiHeader;
+} VIDEOINFOHEADER;
+
+typedef struct _VIDEO_STREAM_CONFIG_CAPS {
+  GUID guid;
+  ULONG VideoStandard;
+  SIZE InputSize;
+  SIZE MinCroppingSize;
+  SIZE MaxCroppingSize;
+  int CropGranularityX;
+  int CropGranularityY;
+  int CropAlignX;
+  int CropAlignY;
+  SIZE MinOutputSize;
+  SIZE MaxOutputSize;
+  int OutputGranularityX;
+  int OutputGranularityY;
+  int StretchTapsX;
+  int StretchTapsY;
+  int ShrinkTapsX;
+  int ShrinkTapsY;
+  LONGLONG MinFrameInterval;
+  LONGLONG MaxFrameInterval;
+  LONG MinBitsPerSecond;
+  LONG MaxBitsPerSecond;
+} VIDEO_STREAM_CONFIG_CAPS;
+
+
+/* Interface & Class GUIDs */
+static const IID IID_IGrabCallback   = {0x4C337035,0xC89E,0x4B42,{0x9B,0x0C,0x36,0x74,0x44,0xDD,0x70,0xDD}};
+
+EXTERN_C const IID IID_IBaseFilter;
+EXTERN_C const IID IID_ICreateDevEnum;
+EXTERN_C const IID IID_IGraphBuilder;
+EXTERN_C const IID IID_IMediaSeeking;
+EXTERN_C const IID IID_IMediaEventSink;
+EXTERN_C const IID IID_IMemInputPin;
+EXTERN_C const IID IID_IEnumPins;
+EXTERN_C const IID IID_IMediaFilter;
+EXTERN_C const IID IID_IEnumMediaTypes;
+EXTERN_C const IID IID_IMemAllocator;
+EXTERN_C const IID IID_IPin;
+EXTERN_C const IID IID_ICaptureGraphBuilder2;
+EXTERN_C const IID IID_IFileSinkFilter;
+EXTERN_C const IID IID_IAMCopyCaptureFileProgress;
+EXTERN_C const IID IID_IEnumFilters;
+EXTERN_C const IID IID_IMediaSample;
+EXTERN_C const IID IID_IMediaControl;
+EXTERN_C const IID IID_IAMStreamConfig;
+EXTERN_C const IID IID_IAMVideoProcAmp;
+
+EXTERN_C const IID CLSID_CaptureGraphBuilder2;
+EXTERN_C const IID CLSID_VideoInputDeviceCategory;
+EXTERN_C const IID CLSID_AudioRender;
+EXTERN_C const IID CLSID_SystemDeviceEnum;
+EXTERN_C const IID CLSID_AudioRendererCategory;
+EXTERN_C const IID CLSID_FilterGraph;
+EXTERN_C const IID CLSID_InfTee;
+EXTERN_C const IID CLSID_VideoMixingRenderer9;
+EXTERN_C const IID CLSID_MemoryAllocator;
+
+
+/* other types GUIDs*/
+EXTERN_C const IID MEDIATYPE_Audio;
+EXTERN_C const IID MEDIATYPE_Video;
+EXTERN_C const IID MEDIATYPE_Stream;
+EXTERN_C const IID MEDIASUBTYPE_PCM;
+EXTERN_C const IID MEDIASUBTYPE_WAVE;
+EXTERN_C const IID MEDIASUBTYPE_Avi;
+EXTERN_C const IID MEDIASUBTYPE_RGB32;
+EXTERN_C const IID MEDIASUBTYPE_YV12;
+EXTERN_C const IID MEDIASUBTYPE_YUY2;
+EXTERN_C const IID MEDIASUBTYPE_I420;
+EXTERN_C const IID MEDIASUBTYPE_YUYV;
+EXTERN_C const IID FORMAT_WaveFormatEx;
+EXTERN_C const IID FORMAT_VideoInfo;
+EXTERN_C const IID FORMAT_VideoInfo2;
+EXTERN_C const IID PIN_CATEGORY_CAPTURE;
+EXTERN_C const IID PIN_CATEGORY_PREVIEW;
+
+
+#define MEDIATYPE_NULL       GUID_NULL
+#define MEDIASUBTYPE_NULL    GUID_NULL
+
+#define INTERFACE IGrabCallback
+DECLARE_INTERFACE_(IGrabCallback, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(Grab)(THIS_ ULONG,BYTE*) PURE;
+};
+#undef INTERFACE
+
+#ifdef COBJMACROS
+#define IGrabCallback_QueryInterface(T,a,b) (T)->lpVtbl->QueryInterface(T,a,b)
+#define IGrabCallback_AddRef(T) (T)->lpVtbl->AddRef(T)
+#define IGrabCallback_Release(T) (T)->lpVtbl->Release(T)
+#define IGrabCallback_Grab(T,a,b) (T)->lpVtbl->Grab(T,a,b)
+#endif /* COBJMACROS */
+
+#define INTERFACE IAMCopyCaptureFileProgress
+DECLARE_INTERFACE_(IAMCopyCaptureFileProgress, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(Progress)(THIS_ int) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IReferenceClock
+DECLARE_INTERFACE_(IReferenceClock, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(GetTime)(THIS_ REFERENCE_TIME *) PURE;
+    STDMETHOD(AdviseTime)(THIS_ REFERENCE_TIME, REFERENCE_TIME, HEVENT, DWORD_PTR *) PURE;
+    STDMETHOD(AdvisePeriodic)(THIS_ REFERENCE_TIME, REFERENCE_TIME, HSEMAPHORE, DWORD_PTR *) PURE;
+    STDMETHOD(Unadvise)(THIS_ DWORD_PTR) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IEnumFilters
+DECLARE_INTERFACE_(IEnumFilters, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(Next)(THIS_ ULONG, IBaseFilter **, ULONG *) PURE;
+    STDMETHOD(Skip)(THIS_ ULONG) PURE;
+    STDMETHOD(Reset)(THIS) PURE;
+    STDMETHOD(Clone)(THIS_ IEnumFilters **) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IEnumMediaTypes
+DECLARE_INTERFACE_(IEnumMediaTypes, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(Next)(THIS_ ULONG, AM_MEDIA_TYPE **, ULONG *) PURE;
+    STDMETHOD(Skip)(THIS_ ULONG) PURE;
+    STDMETHOD(Reset)(THIS) PURE;
+    STDMETHOD(Clone)(THIS_ IEnumMediaTypes **) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IPin
+DECLARE_INTERFACE_(IPin, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(Connect)(THIS_ IPin *, const AM_MEDIA_TYPE *) PURE;
+    STDMETHOD(ReceiveConnection)(THIS_ IPin *, const AM_MEDIA_TYPE *) PURE;
+    STDMETHOD(Disconnect)(THIS) PURE;
+    STDMETHOD(ConnectedTo)(THIS_ IPin **) PURE;
+    STDMETHOD(ConnectionMediaType)(THIS_ AM_MEDIA_TYPE *) PURE;
+    STDMETHOD(QueryPinInfo)(THIS_ PIN_INFO *) PURE;
+    STDMETHOD(QueryDirection)(THIS_ PIN_DIRECTION *) PURE;
+    STDMETHOD(QueryId)(THIS_ LPWSTR *) PURE;
+    STDMETHOD(QueryAccept)(THIS_ const AM_MEDIA_TYPE *) PURE;
+    STDMETHOD(EnumMediaTypes)(THIS_ IEnumMediaTypes **) PURE;
+    STDMETHOD(QueryInternalConnections)(THIS_ IPin **, ULONG *) PURE;
+    STDMETHOD(EndOfStream)(THIS) PURE;
+    STDMETHOD(BeginFlush)(THIS) PURE;
+    STDMETHOD(EndFlush)(THIS) PURE;
+    STDMETHOD(NewSegment)(THIS_ REFERENCE_TIME, REFERENCE_TIME, double) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IEnumPins
+DECLARE_INTERFACE_(IEnumPins, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(Next)(THIS_ ULONG, IPin **, ULONG *) PURE;
+    STDMETHOD(Skip)(THIS_ ULONG) PURE;
+    STDMETHOD(Reset)(THIS) PURE;
+    STDMETHOD(Clone)(THIS_ IEnumPins **) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IMediaFilter
+DECLARE_INTERFACE_(IMediaFilter, IPersist)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(GetClassID)(THIS_ CLSID*) PURE;
+    STDMETHOD(Stop)(THIS) PURE;
+    STDMETHOD(Pause)(THIS) PURE;
+    STDMETHOD(Run)(THIS_ REFERENCE_TIME) PURE;
+    STDMETHOD(GetState)(THIS_ DWORD, FILTER_STATE *) PURE;
+    STDMETHOD(SetSyncSource)(THIS_ IReferenceClock *) PURE;
+    STDMETHOD(GetSyncSource)(THIS_ IReferenceClock **) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IBaseFilter
+DECLARE_INTERFACE2_(IBaseFilter, IMediaFilter)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(GetClassID)(THIS_ CLSID*) PURE;
+    STDMETHOD(Stop)(THIS) PURE;
+    STDMETHOD(Pause)(THIS) PURE;
+    STDMETHOD(Run)(THIS_ REFERENCE_TIME) PURE;
+    STDMETHOD(GetState)(THIS_ DWORD, FILTER_STATE *) PURE;
+    STDMETHOD(SetSyncSource)(THIS_ IReferenceClock *) PURE;
+    STDMETHOD(GetSyncSource)(THIS_ IReferenceClock **) PURE;
+    STDMETHOD(EnumPins)(THIS_ IEnumPins **) PURE;
+    STDMETHOD(FindPin)(THIS_ LPCWSTR, IPin **) PURE;
+    STDMETHOD(QueryFilterInfo)(THIS_ FILTER_INFO *) PURE;
+    STDMETHOD(JoinFilterGraph)(THIS_ IFilterGraph *, LPCWSTR) PURE;
+    STDMETHOD(QueryVendorInfo)(THIS_ LPWSTR *) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IFilterGraph
+DECLARE_INTERFACE2_(IFilterGraph, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(AddFilter)(THIS_ IBaseFilter *, LPCWSTR) PURE;
+    STDMETHOD(RemoveFilter)(THIS_ IBaseFilter *) PURE;
+    STDMETHOD(EnumFilters)(THIS_ IEnumFilters **) PURE;
+    STDMETHOD(FindFilterByName)(THIS_ LPCWSTR, IBaseFilter **) PURE;
+    STDMETHOD(ConnectDirect)(THIS_ IPin *, IPin *, const AM_MEDIA_TYPE *) PURE;
+    STDMETHOD(Reconnect)(THIS_ IPin *) PURE;
+    STDMETHOD(Disconnect)(THIS_ IPin *) PURE;
+    STDMETHOD(SetDefaultSyncSource)(THIS) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IGraphBuilder
+DECLARE_INTERFACE_(IGraphBuilder ,IFilterGraph)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(AddFilter)(THIS_ IBaseFilter *, LPCWSTR) PURE;
+    STDMETHOD(RemoveFilter)(THIS_ IBaseFilter *) PURE;
+    STDMETHOD(EnumFilters)(THIS_ IEnumFilters **) PURE;
+    STDMETHOD(FindFilterByName)(THIS_ LPCWSTR, IBaseFilter **) PURE;
+    STDMETHOD(ConnectDirect)(THIS_ IPin *, IPin *, const AM_MEDIA_TYPE *) PURE;
+    STDMETHOD(Reconnect)(THIS_ IPin *) PURE;
+    STDMETHOD(Disconnect)(THIS_ IPin *) PURE;
+    STDMETHOD(SetDefaultSyncSource)(THIS) PURE;
+    STDMETHOD(Connect)(THIS_ IPin *, IPin *) PURE;
+    STDMETHOD(Render)(THIS_ IPin *) PURE;
+    STDMETHOD(RenderFile)(THIS_ LPCWSTR, LPCWSTR) PURE;
+    STDMETHOD(AddSourceFilter)(THIS_ LPCWSTR, LPCWSTR, IBaseFilter **) PURE;
+    STDMETHOD(SetLogFile)(THIS_ DWORD_PTR) PURE;
+    STDMETHOD(Abort)(THIS) PURE;
+    STDMETHOD(ShouldOperationContinue)(THIS) PURE;
+};
+#undef INTERFACE
+#define INTERFACE ICreateDevEnum
+DECLARE_INTERFACE_(ICreateDevEnum, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(CreateClassEnumerator)(THIS_ REFCLSID, IEnumMoniker **, DWORD) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IMediaSample
+DECLARE_INTERFACE_(IMediaSample, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(GetPointer)(THIS_ BYTE **) PURE;
+    STDMETHOD_(long, GetSize)(THIS) PURE;
+    STDMETHOD(GetTime)(THIS_ REFERENCE_TIME *, REFERENCE_TIME *) PURE;
+    STDMETHOD(SetTime)(THIS_ REFERENCE_TIME *, REFERENCE_TIME *) PURE;
+    STDMETHOD(IsSyncPoint)(THIS) PURE;
+    STDMETHOD(SetSyncPoint)(THIS_ BOOL) PURE;
+    STDMETHOD(IsPreroll)(THIS) PURE;
+    STDMETHOD(SetPreroll)(THIS_ BOOL) PURE;
+    STDMETHOD_(long, GetActualDataLength)(THIS) PURE;
+    STDMETHOD(SetActualDataLength)(THIS_ long) PURE;
+    STDMETHOD(GetMediaType)(THIS_ AM_MEDIA_TYPE **) PURE;
+    STDMETHOD(SetMediaType)(THIS_ AM_MEDIA_TYPE *) PURE;
+    STDMETHOD(IsDiscontinuity)(THIS) PURE;
+    STDMETHOD(SetDiscontinuity)(THIS_ BOOL) PURE;
+    STDMETHOD(GetMediaTime)(THIS_ LONGLONG *, LONGLONG *) PURE;
+    STDMETHOD(SetMediaTime)(THIS_ LONGLONG *, LONGLONG *) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IMemAllocator
+DECLARE_INTERFACE_(IMemAllocator, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(SetProperties)(THIS_ ALLOCATOR_PROPERTIES *, ALLOCATOR_PROPERTIES *) PURE;
+    STDMETHOD(GetProperties)(THIS_ ALLOCATOR_PROPERTIES *) PURE;
+    STDMETHOD(Commit)(THIS) PURE;
+    STDMETHOD(Decommit)(THIS) PURE;
+    STDMETHOD(GetBuffer)(THIS_ IMediaSample **, REFERENCE_TIME *, REFERENCE_TIME *, DWORD) PURE;
+    STDMETHOD(ReleaseBuffer)(THIS_ IMediaSample *) PURE;
+
+};
+#undef INTERFACE
+#define INTERFACE IMemInputPin
+DECLARE_INTERFACE_(IMemInputPin, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(GetAllocator)(THIS_ IMemAllocator **) PURE;
+    STDMETHOD(NotifyAllocator)(THIS_ IMemAllocator *, BOOL) PURE;
+    STDMETHOD(GetAllocatorRequirements)(THIS_ ALLOCATOR_PROPERTIES *) PURE;
+    STDMETHOD(Receive)(THIS_ IMediaSample *) PURE;
+    STDMETHOD(ReceiveMultiple)(THIS_ IMediaSample **, long, long *) PURE;
+    STDMETHOD(ReceiveCanBlock)(THIS) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IFileSinkFilter
+DECLARE_INTERFACE_(IFileSinkFilter, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(SetFileName)(THIS_ LPCOLESTR,const AM_MEDIA_TYPE *) PURE;
+    STDMETHOD(GetCurFile)(THIS_ LPOLESTR *,AM_MEDIA_TYPE*) PURE;
+};
+#undef INTERFACE
+#define INTERFACE ICaptureGraphBuilder2
+DECLARE_INTERFACE_(ICaptureGraphBuilder2, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(SetFiltergraph)(THIS_ IGraphBuilder*) PURE;
+    STDMETHOD(GetFiltergraph)(THIS_ IGraphBuilder**) PURE;
+    STDMETHOD(SetOutputFileName)(THIS_ const GUID*,LPCOLESTR,IBaseFilter**,IFileSinkFilter**) PURE;
+    STDMETHOD(FindInterface)(THIS_ const GUID*,const GUID*,IBaseFilter*,REFIID,void**) PURE;
+    STDMETHOD(RenderStream)(THIS_ const GUID*,const GUID*,IUnknown*,IBaseFilter*,IBaseFilter*) PURE;
+    STDMETHOD(ControlStream)(THIS_ const GUID*,const GUID*,IBaseFilter*,REFERENCE_TIME*,REFERENCE_TIME*,WORD,WORD) PURE;
+    STDMETHOD(AllocCapFile)(THIS_ LPCOLESTR,DWORDLONG) PURE;
+    STDMETHOD(CopyCaptureFile)(THIS_ LPOLESTR,LPOLESTR,int,IAMCopyCaptureFileProgress*) PURE;
+    STDMETHOD(FindPin)(THIS_ IUnknown*,PIN_DIRECTION,const GUID*,const GUID*,BOOL,int,IPin**) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IAMStreamConfig
+DECLARE_INTERFACE_(IAMStreamConfig, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(SetFormat)(THIS_ AM_MEDIA_TYPE*) PURE;
+    STDMETHOD(GetFormat)(THIS_ AM_MEDIA_TYPE**) PURE;
+    STDMETHOD(GetNumberOfCapabilities)(THIS_ int*,int*) PURE;
+    STDMETHOD(GetStreamCaps)(THIS_ int,AM_MEDIA_TYPE**,BYTE*) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IAMVideoProcAmp
+DECLARE_INTERFACE_(IAMVideoProcAmp, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(GetRange)(THIS_ long,long*,long*,long*,long*,long*) PURE;
+    STDMETHOD(Set)(THIS_ long,long,long) PURE;
+    STDMETHOD(Get)(THIS_ long,long*,long*) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IMediaControl
+DECLARE_INTERFACE_(IMediaControl, IDispatch)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(GetTypeInfoCount)(THIS_ UINT*);
+    STDMETHOD(GetTypeInfo)(THIS_ UINT,LCID,ITypeInfo**);
+    STDMETHOD(GetIDsOfNames)(THIS_ REFIID,LPOLESTR*,UINT,LCID,DISPID*);
+    STDMETHOD(Invoke)(THIS_ DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*);
+    STDMETHOD(Run)(THIS);
+    STDMETHOD(Pause)(THIS);
+    STDMETHOD(Stop)(THIS);
+    STDMETHOD(GetState)(THIS_ LONG, OAFilterState*);
+    STDMETHOD(RenderFile)(THIS_ BSTR);
+    STDMETHOD(AddSourceFilter)(THIS_ BSTR,IDispatch**);
+    STDMETHOD(get_FilterCollection)(THIS_ IDispatch**);
+    STDMETHOD(get_RegFilterCollection)(THIS_ IDispatch**);
+    STDMETHOD(StopWhenReady)(THIS);
+};
+#undef INTERFACE
+
+#ifdef COBJMACROS
+#define ICreateDevEnum_QueryInterface(This,riid,ppvObject)  \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define ICreateDevEnum_AddRef(This) \
+    ((This)->lpVtbl->AddRef(This))
+#define ICreateDevEnum_Release(This)    \
+    ((This)->lpVtbl->Release(This))
+#define ICreateDevEnum_CreateClassEnumerator(This,clsidDeviceClass,ppEnumMoniker,dwFlags)   \
+    ((This)->lpVtbl->CreateClassEnumerator(This,clsidDeviceClass,ppEnumMoniker,dwFlags))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IPin_QueryInterface(This,riid,ppvObject)    \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IPin_AddRef(This)   \
+    ((This)->lpVtbl->AddRef(This))
+#define IPin_Release(This)  \
+    ((This)->lpVtbl->Release(This))
+#define IPin_Connect(This,pReceivePin,pmt)  \
+    ((This)->lpVtbl->Connect(This,pReceivePin,pmt))
+#define IPin_ReceiveConnection(This,pConnector,pmt) \
+    ((This)->lpVtbl->ReceiveConnection(This,pConnector,pmt))
+#define IPin_Disconnect(This)   \
+    ((This)->lpVtbl->Disconnect(This))
+#define IPin_ConnectedTo(This,pPin) \
+    ((This)->lpVtbl->ConnectedTo(This,pPin))
+#define IPin_ConnectionMediaType(This,pmt)  \
+    ((This)->lpVtbl->ConnectionMediaType(This,pmt))
+#define IPin_QueryPinInfo(This,pInfo)   \
+    ((This)->lpVtbl->QueryPinInfo(This,pInfo))
+#define IPin_QueryDirection(This,pPinDir)   \
+    ((This)->lpVtbl->QueryDirection(This,pPinDir))
+#define IPin_QueryId(This,Id)   \
+    ((This)->lpVtbl->QueryId(This,Id))
+#define IPin_QueryAccept(This,pmt)  \
+    ((This)->lpVtbl->QueryAccept(This,pmt))
+#define IPin_EnumMediaTypes(This,ppEnum)    \
+    ((This)->lpVtbl->EnumMediaTypes(This,ppEnum))
+#define IPin_QueryInternalConnections(This,apPin,nPin)  \
+    ((This)->lpVtbl->QueryInternalConnections(This,apPin,nPin))
+#define IPin_EndOfStream(This)  \
+    ((This)->lpVtbl->EndOfStream(This))
+#define IPin_BeginFlush(This)   \
+    ((This)->lpVtbl->BeginFlush(This))
+#define IPin_EndFlush(This) \
+    ((This)->lpVtbl->EndFlush(This))
+#define IPin_NewSegment(This,tStart,tStop,dRate)    \
+    ((This)->lpVtbl->NewSegment(This,tStart,tStop,dRate))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IEnumPins_QueryInterface(This,riid,ppvObject)   \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IEnumPins_AddRef(This)  \
+    ((This)->lpVtbl->AddRef(This))
+#define IEnumPins_Release(This) \
+    ((This)->lpVtbl->Release(This))
+#define IEnumPins_Next(This,cPins,ppPins,pcFetched) \
+    ((This)->lpVtbl->Next(This,cPins,ppPins,pcFetched))
+#define IEnumPins_Skip(This,cPins)  \
+    ((This)->lpVtbl->Skip(This,cPins))
+#define IEnumPins_Reset(This)   \
+    ((This)->lpVtbl->Reset(This))
+#define IEnumPins_Clone(This,ppEnum)    \
+    ((This)->lpVtbl->Clone(This,ppEnum))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IAMStreamConfig_QueryInterface(This,riid,ppvObject) \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IAMStreamConfig_AddRef(This)    \
+    ((This)->lpVtbl->AddRef(This))
+#define IAMStreamConfig_Release(This)   \
+    ((This)->lpVtbl->Release(This))
+#define IAMStreamConfig_SetFormat(This,pmt) \
+    ((This)->lpVtbl->SetFormat(This,pmt))
+#define IAMStreamConfig_GetFormat(This,ppmt)    \
+    ((This)->lpVtbl->GetFormat(This,ppmt))
+#define IAMStreamConfig_GetNumberOfCapabilities(This,piCount,piSize)    \
+    ((This)->lpVtbl->GetNumberOfCapabilities(This,piCount,piSize))
+#define IAMStreamConfig_GetStreamCaps(This,iIndex,ppmt,pSCC)    \
+    ((This)->lpVtbl->GetStreamCaps(This,iIndex,ppmt,pSCC))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IFilterGraph_QueryInterface(This,riid,ppvObject)    \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IFilterGraph_AddRef(This)   \
+    ((This)->lpVtbl->AddRef(This))
+#define IFilterGraph_Release(This)  \
+    ((This)->lpVtbl->Release(This))
+#define IFilterGraph_AddFilter(This,pFilter,pName)  \
+    ((This)->lpVtbl->AddFilter(This,pFilter,pName))
+#define IFilterGraph_RemoveFilter(This,pFilter) \
+    ((This)->lpVtbl->RemoveFilter(This,pFilter))
+#define IFilterGraph_EnumFilters(This,ppEnum)   \
+    ((This)->lpVtbl->EnumFilters(This,ppEnum))
+#define IFilterGraph_FindFilterByName(This,pName,ppFilter)  \
+    ((This)->lpVtbl->FindFilterByName(This,pName,ppFilter))
+#define IFilterGraph_ConnectDirect(This,ppinOut,ppinIn,pmt) \
+    ((This)->lpVtbl->ConnectDirect(This,ppinOut,ppinIn,pmt))
+#define IFilterGraph_Reconnect(This,ppin)   \
+    ((This)->lpVtbl->Reconnect(This,ppin))
+#define IFilterGraph_Disconnect(This,ppin)  \
+    ((This)->lpVtbl->Disconnect(This,ppin))
+#define IFilterGraph_SetDefaultSyncSource(This) \
+    ((This)->lpVtbl->SetDefaultSyncSource(This))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IMediaFilter_QueryInterface(This,riid,ppvObject)    \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IMediaFilter_AddRef(This)   \
+    ((This)->lpVtbl->AddRef(This))
+#define IMediaFilter_Release(This)  \
+    ((This)->lpVtbl->Release(This))
+#define IMediaFilter_GetClassID(This,pClassID)  \
+    ((This)->lpVtbl->GetClassID(This,pClassID))
+#define IMediaFilter_Stop(This) \
+    ((This)->lpVtbl->Stop(This))
+#define IMediaFilter_Pause(This)    \
+    ((This)->lpVtbl->Pause(This))
+#define IMediaFilter_Run(This,tStart)   \
+    ((This)->lpVtbl->Run(This,tStart))
+#define IMediaFilter_GetState(This,dwMilliSecsTimeout,State)    \
+    ((This)->lpVtbl->GetState(This,dwMilliSecsTimeout,State))
+#define IMediaFilter_SetSyncSource(This,pClock) \
+    ((This)->lpVtbl->SetSyncSource(This,pClock))
+#define IMediaFilter_GetSyncSource(This,pClock) \
+    ((This)->lpVtbl->GetSyncSource(This,pClock))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IBaseFilter_QueryInterface(This,riid,ppvObject) \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IBaseFilter_AddRef(This)    \
+    ((This)->lpVtbl->AddRef(This))
+#define IBaseFilter_Release(This)   \
+    ((This)->lpVtbl->Release(This))
+#define IBaseFilter_GetClassID(This,pClassID)   \
+    ((This)->lpVtbl->GetClassID(This,pClassID))
+#define IBaseFilter_Stop(This)  \
+    ((This)->lpVtbl->Stop(This))
+#define IBaseFilter_Pause(This) \
+    ((This)->lpVtbl->Pause(This))
+#define IBaseFilter_Run(This,tStart)    \
+    ((This)->lpVtbl->Run(This,tStart))
+#define IBaseFilter_GetState(This,dwMilliSecsTimeout,State) \
+    ((This)->lpVtbl->GetState(This,dwMilliSecsTimeout,State))
+#define IBaseFilter_SetSyncSource(This,pClock)  \
+    ((This)->lpVtbl->SetSyncSource(This,pClock))
+#define IBaseFilter_GetSyncSource(This,pClock)  \
+    ((This)->lpVtbl->GetSyncSource(This,pClock))
+#define IBaseFilter_EnumPins(This,ppEnum)   \
+    ((This)->lpVtbl->EnumPins(This,ppEnum))
+#define IBaseFilter_FindPin(This,Id,ppPin)  \
+    ((This)->lpVtbl->FindPin(This,Id,ppPin))
+#define IBaseFilter_QueryFilterInfo(This,pInfo) \
+    ((This)->lpVtbl->QueryFilterInfo(This,pInfo))
+#define IBaseFilter_JoinFilterGraph(This,pGraph,pName)  \
+    ((This)->lpVtbl->JoinFilterGraph(This,pGraph,pName))
+#define IBaseFilter_QueryVendorInfo(This,pVendorInfo)   \
+    ((This)->lpVtbl->QueryVendorInfo(This,pVendorInfo))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IMediaSample_QueryInterface(This,riid,ppvObject)    \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IMediaSample_AddRef(This)   \
+    ((This)->lpVtbl->AddRef(This))
+#define IMediaSample_Release(This)  \
+    ((This)->lpVtbl->Release(This))
+#define IMediaSample_GetPointer(This,ppBuffer)  \
+    ((This)->lpVtbl->GetPointer(This,ppBuffer))
+#define IMediaSample_GetSize(This)  \
+        ((This)->lpVtbl->GetSize(This))
+#define IMediaSample_GetTime(This,pTimeStart,pTimeEnd)  \
+    ((This)->lpVtbl->GetTime(This,pTimeStart,pTimeEnd))
+#define IMediaSample_SetTime(This,pTimeStart,pTimeEnd)  \
+    ((This)->lpVtbl->SetTime(This,pTimeStart,pTimeEnd))
+#define IMediaSample_IsSyncPoint(This)  \
+    ((This)->lpVtbl->IsSyncPoint(This))
+#define IMediaSample_SetSyncPoint(This,bIsSyncPoint)    \
+    ((This)->lpVtbl->SetSyncPoint(This,bIsSyncPoint))
+#define IMediaSample_IsPreroll(This)    \
+    ((This)->lpVtbl->IsPreroll(This))
+#define IMediaSample_SetPreroll(This,bIsPreroll)    \
+    ((This)->lpVtbl->SetPreroll(This,bIsPreroll))
+#define IMediaSample_GetActualDataLength(This)  \
+    ((This)->lpVtbl->GetActualDataLength(This))
+#define IMediaSample_SetActualDataLength(This,length)   \
+    ((This)->lpVtbl->SetActualDataLength(This,length))
+#define IMediaSample_GetMediaType(This,ppMediaType) \
+    ((This)->lpVtbl->GetMediaType(This,ppMediaType))
+#define IMediaSample_SetMediaType(This,pMediaType)  \
+    ((This)->lpVtbl->SetMediaType(This,pMediaType))
+#define IMediaSample_IsDiscontinuity(This)  \
+    ((This)->lpVtbl->IsDiscontinuity(This))
+#define IMediaSample_SetDiscontinuity(This,bDiscontinuity)  \
+    ((This)->lpVtbl->SetDiscontinuity(This,bDiscontinuity))
+#define IMediaSample_GetMediaTime(This,pTimeStart,pTimeEnd) \
+    ((This)->lpVtbl->GetMediaTime(This,pTimeStart,pTimeEnd))
+#define IMediaSample_SetMediaTime(This,pTimeStart,pTimeEnd) \
+    ((This)->lpVtbl->SetMediaTime(This,pTimeStart,pTimeEnd))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IEnumFilters_QueryInterface(This,riid,ppvObject)    \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IEnumFilters_AddRef(This)   \
+    ((This)->lpVtbl->AddRef(This))
+#define IEnumFilters_Release(This)  \
+    ((This)->lpVtbl->Release(This))
+#define IEnumFilters_Next(This,cFilters,ppFilter,pcFetched) \
+    ((This)->lpVtbl->Next(This,cFilters,ppFilter,pcFetched))
+#define IEnumFilters_Skip(This,cFilters)    \
+    ((This)->lpVtbl->Skip(This,cFilters))
+#define IEnumFilters_Reset(This)    \
+    ((This)->lpVtbl->Reset(This))
+#define IEnumFilters_Clone(This,ppEnum) \
+    ((This)->lpVtbl->Clone(This,ppEnum))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IMemAllocator_QueryInterface(This,riid,ppvObject)   \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IMemAllocator_AddRef(This)  \
+    ((This)->lpVtbl->AddRef(This))
+#define IMemAllocator_Release(This) \
+    ((This)->lpVtbl->Release(This))
+#define IMemAllocator_SetProperties(This,pRequest,pActual)  \
+    ((This)->lpVtbl->SetProperties(This,pRequest,pActual))
+#define IMemAllocator_GetProperties(This,pProps)    \
+    ((This)->lpVtbl->GetProperties(This,pProps))
+#define IMemAllocator_Commit(This)  \
+    ((This)->lpVtbl->Commit(This))
+#define IMemAllocator_Decommit(This)    \
+    ((This)->lpVtbl->Decommit(This))
+#define IMemAllocator_GetBuffer(This,ppBuffer,pStartTime,pEndTime,dwFlags)  \
+    ((This)->lpVtbl->GetBuffer(This,ppBuffer,pStartTime,pEndTime,dwFlags))
+#define IMemAllocator_ReleaseBuffer(This,pBuffer)   \
+    ((This)->lpVtbl->ReleaseBuffer(This,pBuffer))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IMemInputPin_QueryInterface(This,riid,ppvObject)    \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IMemInputPin_AddRef(This)   \
+    ((This)->lpVtbl->AddRef(This))
+#define IMemInputPin_Release(This)  \
+    ((This)->lpVtbl->Release(This))
+#define IMemInputPin_GetAllocator(This,ppAllocator) \
+    ((This)->lpVtbl->GetAllocator(This,ppAllocator))
+#define IMemInputPin_NotifyAllocator(This,pAllocator,bReadOnly) \
+    ((This)->lpVtbl->NotifyAllocator(This,pAllocator,bReadOnly))
+#define IMemInputPin_GetAllocatorRequirements(This,pProps)  \
+    ((This)->lpVtbl->GetAllocatorRequirements(This,pProps))
+#define IMemInputPin_Receive(This,pSample)  \
+    ((This)->lpVtbl->Receive(This,pSample))
+#define IMemInputPin_ReceiveMultiple(This,pSamples,nSamples,nSamplesProcessed)  \
+    ((This)->lpVtbl->ReceiveMultiple(This,pSamples,nSamples,nSamplesProcessed))
+#define IMemInputPin_ReceiveCanBlock(This)  \
+    ((This)->lpVtbl->ReceiveCanBlock(This))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IGraphBuilder_QueryInterface(This,riid,ppvObject)   \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IGraphBuilder_AddRef(This)  \
+    ((This)->lpVtbl->AddRef(This))
+#define IGraphBuilder_Release(This) \
+    ((This)->lpVtbl->Release(This))
+#define IGraphBuilder_AddFilter(This,pFilter,pName) \
+    ((This)->lpVtbl->AddFilter(This,pFilter,pName))
+#define IGraphBuilder_RemoveFilter(This,pFilter)    \
+    ((This)->lpVtbl->RemoveFilter(This,pFilter))
+#define IGraphBuilder_EnumFilters(This,ppEnum)  \
+    ((This)->lpVtbl->EnumFilters(This,ppEnum))
+#define IGraphBuilder_FindFilterByName(This,pName,ppFilter) \
+    ((This)->lpVtbl->FindFilterByName(This,pName,ppFilter))
+#define IGraphBuilder_ConnectDirect(This,ppinOut,ppinIn,pmt)    \
+    ((This)->lpVtbl->ConnectDirect(This,ppinOut,ppinIn,pmt))
+#define IGraphBuilder_Reconnect(This,ppin)  \
+    ((This)->lpVtbl->Reconnect(This,ppin))
+#define IGraphBuilder_Disconnect(This,ppin) \
+    ((This)->lpVtbl->Disconnect(This,ppin))
+#define IGraphBuilder_SetDefaultSyncSource(This)    \
+    ((This)->lpVtbl->SetDefaultSyncSource(This))
+#define IGraphBuilder_Connect(This,ppinOut,ppinIn)  \
+    ((This)->lpVtbl->Connect(This,ppinOut,ppinIn))
+#define IGraphBuilder_Render(This,ppinOut)  \
+    ((This)->lpVtbl->Render(This,ppinOut))
+#define IGraphBuilder_RenderFile(This,lpcwstrFile,lpcwstrPlayList)  \
+    ((This)->lpVtbl->RenderFile(This,lpcwstrFile,lpcwstrPlayList))
+#define IGraphBuilder_AddSourceFilter(This,lpcwstrFileName,lpcwstrFilterName,ppFilter)  \
+    ((This)->lpVtbl->AddSourceFilter(This,lpcwstrFileName,lpcwstrFilterName,ppFilter))
+#define IGraphBuilder_SetLogFile(This,hFile)    \
+    ((This)->lpVtbl->SetLogFile(This,hFile))
+#define IGraphBuilder_Abort(This)   \
+    ((This)->lpVtbl->Abort(This))
+#define IGraphBuilder_ShouldOperationContinue(This) \
+    ((This)->lpVtbl->ShouldOperationContinue(This))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IEnumMediaTypes_QueryInterface(This,riid,ppvObject) \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IEnumMediaTypes_AddRef(This)    \
+    ((This)->lpVtbl->AddRef(This))
+#define IEnumMediaTypes_Release(This)   \
+    ((This)->lpVtbl->Release(This))
+#define IEnumMediaTypes_Next(This,cMediaTypes,ppMediaTypes,pcFetched)   \
+    ((This)->lpVtbl->Next(This,cMediaTypes,ppMediaTypes,pcFetched))
+#define IEnumMediaTypes_Skip(This,cMediaTypes)  \
+    ((This)->lpVtbl->Skip(This,cMediaTypes))
+#define IEnumMediaTypes_Reset(This) \
+    ((This)->lpVtbl->Reset(This))
+#define IEnumMediaTypes_Clone(This,ppEnum)  \
+    ((This)->lpVtbl->Clone(This,ppEnum))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IMediaControl_QueryInterface(This,riid,ppvObject)   \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IMediaControl_AddRef(This)  \
+    ((This)->lpVtbl->AddRef(This))
+#define IMediaControl_Release(This) \
+    ((This)->lpVtbl->Release(This))
+#define IMediaControl_GetTypeInfoCount(This,pctinfo)    \
+    ((This)->lpVtbl->GetTypeInfoCount(This,pctinfo))
+#define IMediaControl_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+    ((This)->lpVtbl->GetTypeInfo(This,iTInfo,lcid,ppTInfo))
+#define IMediaControl_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)   \
+    ((This)->lpVtbl->GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId))
+#define IMediaControl_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+    ((This)->lpVtbl->Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr))
+#define IMediaControl_Run(This) \
+    ((This)->lpVtbl->Run(This))
+#define IMediaControl_Pause(This)   \
+    ((This)->lpVtbl->Pause(This))
+#define IMediaControl_Stop(This)    \
+    ((This)->lpVtbl->Stop(This))
+#define IMediaControl_GetState(This,msTimeout,pfs)  \
+    ((This)->lpVtbl->GetState(This,msTimeout,pfs))
+#define IMediaControl_RenderFile(This,strFilename)  \
+    ((This)->lpVtbl->RenderFile(This,strFilename))
+#define IMediaControl_AddSourceFilter(This,strFilename,ppUnk)   \
+    ((This)->lpVtbl->AddSourceFilter(This,strFilename,ppUnk))
+#define IMediaControl_get_FilterCollection(This,ppUnk)  \
+    ((This)->lpVtbl->get_FilterCollection(This,ppUnk))
+#define IMediaControl_get_RegFilterCollection(This,ppUnk)   \
+    ((This)->lpVtbl->get_RegFilterCollection(This,ppUnk))
+#define IMediaControl_StopWhenReady(This)   \
+    ((This)->lpVtbl->StopWhenReady(This))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IAMVideoProcAmp_QueryInterface(This,riid,ppvObject) \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IAMVideoProcAmp_AddRef(This)    \
+    ((This)->lpVtbl->AddRef(This))
+#define IAMVideoProcAmp_Release(This)   \
+    ((This)->lpVtbl->Release(This))
+#define IAMVideoProcAmp_GetRange(This,Property,pMin,pMax,pSteppingDelta,pDefault,pCapsFlags)    \
+    ((This)->lpVtbl->GetRange(This,Property,pMin,pMax,pSteppingDelta,pDefault,pCapsFlags))
+#define IAMVideoProcAmp_Set(This,Property,lValue,Flags) \
+    ((This)->lpVtbl->Set(This,Property,lValue,Flags))
+#define IAMVideoProcAmp_Get(This,Property,lValue,Flags) \
+    ((This)->lpVtbl->Get(This,Property,lValue,Flags))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IFileSinkFilter_QueryInterface(This,riid,ppvObject) \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IFileSinkFilter_AddRef(This)    \
+    ((This)->lpVtbl->AddRef(This))
+#define IFileSinkFilter_Release(This)   \
+    ((This)->lpVtbl->Release(This))
+#define IFileSinkFilter_SetFileName(This,pszFileName,pmt)   \
+    ((This)->lpVtbl->SetFileName(This,pszFileName,pmt))
+#define IFileSinkFilter_GetCurFile(This,ppszFileName,pmt)   \
+    ((This)->lpVtbl->GetCurFile(This,ppszFileName,pmt))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IAMCopyCaptureFileProgress_QueryInterface(This,riid,ppvObject)  \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IAMCopyCaptureFileProgress_AddRef(This) \
+    ((This)->lpVtbl->AddRef(This))
+#define IAMCopyCaptureFileProgress_Release(This)    \
+    ((This)->lpVtbl->Release(This))
+#define IAMCopyCaptureFileProgress_Progress(This,iProgress) \
+    ((This)->lpVtbl->Progress(This,iProgress))
+#endif /* COBJMACROS */
+
+
+#ifdef COBJMACROS
+#define ICaptureGraphBuilder2_QueryInterface(This,riid,ppvObject)   \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define ICaptureGraphBuilder2_AddRef(This)  \
+    ((This)->lpVtbl->AddRef(This))
+#define ICaptureGraphBuilder2_Release(This) \
+    ((This)->lpVtbl->Release(This))
+#define ICaptureGraphBuilder2_SetFiltergraph(This,pfg)  \
+    ((This)->lpVtbl->SetFiltergraph(This,pfg))
+#define ICaptureGraphBuilder2_GetFiltergraph(This,ppfg) \
+    ((This)->lpVtbl->GetFiltergraph(This,ppfg))
+#define ICaptureGraphBuilder2_SetOutputFileName(This,pType,lpstrFile,ppf,ppSink)    \
+    ((This)->lpVtbl->SetOutputFileName(This,pType,lpstrFile,ppf,ppSink))
+#define ICaptureGraphBuilder2_FindInterface(This,pCategory,pType,pf,riid,ppint) \
+    ((This)->lpVtbl->FindInterface(This,pCategory,pType,pf,riid,ppint))
+#define ICaptureGraphBuilder2_RenderStream(This,pCategory,pType,pSource,pfCompressor,pfRenderer)    \
+    ((This)->lpVtbl->RenderStream(This,pCategory,pType,pSource,pfCompressor,pfRenderer))
+#define ICaptureGraphBuilder2_ControlStream(This,pCategory,pType,pFilter,pstart,pstop,wStartCookie,wStopCookie) \
+    ((This)->lpVtbl->ControlStream(This,pCategory,pType,pFilter,pstart,pstop,wStartCookie,wStopCookie))
+#define ICaptureGraphBuilder2_AllocCapFile(This,lpstr,dwlSize)  \
+    ((This)->lpVtbl->AllocCapFile(This,lpstr,dwlSize))
+#define ICaptureGraphBuilder2_CopyCaptureFile(This,lpwstrOld,lpwstrNew,fAllowEscAbort,pCallback)    \
+    ((This)->lpVtbl->CopyCaptureFile(This,lpwstrOld,lpwstrNew,fAllowEscAbort,pCallback))
+#define ICaptureGraphBuilder2_FindPin(This,pSource,pindir,pCategory,pType,fUnconnected,num,ppPin)   \
+    ((This)->lpVtbl->FindPin(This,pSource,pindir,pCategory,pType,fUnconnected,num,ppPin))
+#endif /* COBJMACROS */
+
+#endif /* _MARU_CAMERA_INTERFACE_H_ */
index 312f86a..f2a0445 100644 (file)
-/*\r
- * Implementation of MARU Virtual Camera device by PCI bus on Windows.\r
- *\r
- * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Contact:\r
- * JinHyung Jo <jinhyung.jo@samsung.com>\r
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
- *\r
- * Contributors:\r
- * - S-Core Co., Ltd\r
- *\r
- */\r
-\r
-\r
-#include "qemu-common.h"\r
-#include "maru_camera_common.h"\r
-#include "tizen/src/debug_ch.h"\r
-\r
-#define CINTERFACE\r
-#define COBJMACROS\r
-#include "ocidl.h"\r
-#include "errors.h"      /* for VFW_E_XXXX */\r
-#include "mmsystem.h"    /* for MAKEFOURCC macro */\r
-#include "maru_camera_win32_interface.h"\r
-\r
-MULTI_DEBUG_CHANNEL(tizen, camera_win32);\r
-\r
-extern int hax_enabled(void);\r
-\r
-/*\r
- * COM Interface implementations\r
- *\r
- */\r
-\r
-#define SAFE_RELEASE(x) \\r
-    do { \\r
-        if (x) { \\r
-            (x)->lpVtbl->Release(x); \\r
-            x = NULL; \\r
-        } \\r
-    } while (0)\r
-\r
-typedef HRESULT (STDAPICALLTYPE *CallbackFn)(ULONG dwSize, BYTE *pBuffer);\r
-\r
-/*\r
- * HWCGrabCallback\r
- */\r
-\r
-typedef struct HWCGrabCallback {\r
-    IGrabCallback IGrabCallback_iface;\r
-    long m_cRef;\r
-    CallbackFn m_pCallback;\r
-    STDMETHODIMP (*SetCallback)(IGrabCallback *iface, CallbackFn pCallbackFn);\r
-} HWCGrabCallback;\r
-\r
-static inline HWCGrabCallback *impl_from_IGrabCallback(IGrabCallback *iface)\r
-{\r
-    return CONTAINING_RECORD(iface, HWCGrabCallback, IGrabCallback_iface);\r
-}\r
-\r
-static STDMETHODIMP HWCGrabCallback_QueryInterface(IGrabCallback *iface,\r
-                                                   REFIID riid, void **ppv)\r
-{\r
-    if (IsEqualIID(riid, &IID_IUnknown)) {\r
-        *ppv = (IUnknown *)iface;\r
-    } else if (IsEqualIID(riid, &IID_IGrabCallback)) {\r
-        *ppv = (IGrabCallback *)iface;\r
-    } else {\r
-        *ppv = NULL;\r
-        return E_NOINTERFACE;\r
-    }\r
-\r
-    IGrabCallback_AddRef(iface);\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP_(ULONG) HWCGrabCallback_AddRef(IGrabCallback *iface)\r
-{\r
-    HWCGrabCallback *This = impl_from_IGrabCallback(iface);\r
-\r
-    return InterlockedIncrement(&This->m_cRef);\r
-}\r
-\r
-static STDMETHODIMP_(ULONG) HWCGrabCallback_Release(IGrabCallback *iface)\r
-{\r
-    HWCGrabCallback *This = impl_from_IGrabCallback(iface);\r
-\r
-    if (InterlockedDecrement(&This->m_cRef) == 0) {\r
-        This->m_pCallback = NULL;\r
-        g_free((void *)This);\r
-        This = NULL;\r
-        return 0;\r
-    }\r
-\r
-    return This->m_cRef;\r
-}\r
-\r
-static STDMETHODIMP HWCGrabCallback_Grab(IGrabCallback *iface,\r
-                                         ULONG dwSize, BYTE *pBuffer)\r
-{\r
-    HWCGrabCallback *This = impl_from_IGrabCallback(iface);\r
-\r
-    if (This->m_pCallback) {\r
-        HRESULT hr = This->m_pCallback(dwSize, pBuffer);\r
-        if (FAILED(hr)) {\r
-            return E_FAIL;\r
-        } else {\r
-            return S_OK;\r
-        }\r
-    }\r
-\r
-    return E_FAIL;\r
-}\r
-\r
-static STDMETHODIMP HWCGrabCallback_SetCallback(IGrabCallback *iface,\r
-                                                CallbackFn pCallbackFn)\r
-{\r
-    HWCGrabCallback *This = impl_from_IGrabCallback(iface);\r
-\r
-    This->m_pCallback = pCallbackFn;\r
-    return S_OK;\r
-}\r
-\r
-static IGrabCallbackVtbl HWCGrabCallback_Vtbl = {\r
-        HWCGrabCallback_QueryInterface,\r
-        HWCGrabCallback_AddRef,\r
-        HWCGrabCallback_Release,\r
-        HWCGrabCallback_Grab\r
-};\r
-\r
-static STDMETHODIMP HWCGrabCallback_Construct(IGrabCallback **ppv)\r
-{\r
-    HWCGrabCallback *This =\r
-            (HWCGrabCallback *)g_malloc0(sizeof(HWCGrabCallback));\r
-\r
-    if (!This) {\r
-        ERR("failed to HWCGrabCallback_Construct, E_OUTOFMEMORY\n");\r
-        return E_OUTOFMEMORY;\r
-    }\r
-\r
-    This->IGrabCallback_iface.lpVtbl = &HWCGrabCallback_Vtbl;\r
-    This->m_cRef = 1;\r
-    This->m_pCallback = NULL;\r
-    This->SetCallback = HWCGrabCallback_SetCallback;\r
-    *ppv = &This->IGrabCallback_iface;\r
-    return S_OK;\r
-}\r
-\r
-/*\r
- * HWCPin\r
- */\r
-\r
-typedef struct HWCInPin {\r
-    IPin IPin_iface;\r
-    IMemInputPin IMemInputPin_iface;\r
-    IBaseFilter *m_pCFilter;\r
-    IPin *m_pConnectedPin;\r
-    IGrabCallback *m_pCallback;\r
-    IMemAllocator *m_pAllocator;\r
-    BOOL m_bReadOnly;\r
-    long m_cRef;\r
-    STDMETHODIMP (*SetGrabCallbackIF)(IPin *iface, IGrabCallback *pCaptureCB);\r
-} HWCInPin;\r
-\r
-static inline HWCInPin *impl_from_IPin(IPin *iface)\r
-{\r
-    return CONTAINING_RECORD(iface, HWCInPin, IPin_iface);\r
-}\r
-\r
-static inline HWCInPin *impl_from_IMemInputPin(IMemInputPin *iface)\r
-{\r
-    return CONTAINING_RECORD(iface, HWCInPin, IMemInputPin_iface);\r
-}\r
-\r
-static STDMETHODIMP HWCPin_QueryInterface(IPin *iface, REFIID riid, void **ppv)\r
-{\r
-    HWCInPin *This = impl_from_IPin(iface);\r
-\r
-    if (IsEqualIID(riid, &IID_IUnknown)) {\r
-        *ppv = (IUnknown *)(&This->IPin_iface);\r
-        IPin_AddRef((IPin *)*ppv);\r
-    } else if (IsEqualIID(riid, &IID_IPin)) {\r
-        *ppv = (IPin *)(&This->IPin_iface);\r
-        IPin_AddRef((IPin *)*ppv);\r
-    } else if (IsEqualIID(riid, &IID_IMemInputPin)) {\r
-        *ppv = (IMemInputPin *)(&This->IMemInputPin_iface);\r
-        IPin_AddRef((IMemInputPin *)*ppv);\r
-    } else {\r
-        *ppv = NULL;\r
-        return E_NOINTERFACE;\r
-    }\r
-\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP_(ULONG) HWCPin_AddRef(IPin *iface)\r
-{\r
-    HWCInPin *This = impl_from_IPin(iface);\r
-\r
-    return InterlockedIncrement(&This->m_cRef);\r
-}\r
-\r
-static STDMETHODIMP_(ULONG) HWCPin_Release(IPin *iface)\r
-{\r
-    HWCInPin *This = impl_from_IPin(iface);\r
-\r
-    if (InterlockedDecrement(&This->m_cRef) == 0) {\r
-        if (This->m_pCallback) {\r
-            SAFE_RELEASE(This->m_pCallback);\r
-        }\r
-        if (This->m_pConnectedPin) {\r
-            SAFE_RELEASE(This->m_pConnectedPin);\r
-        }\r
-        if (This->m_pAllocator) {\r
-            IMemAllocator_Decommit(This->m_pAllocator);\r
-            SAFE_RELEASE(This->m_pAllocator);\r
-        }\r
-        g_free((void *)This);\r
-        This = NULL;\r
-        return 0;\r
-    }\r
-    return This->m_cRef;\r
-}\r
-\r
-static STDMETHODIMP HWCPin_Connect(IPin *iface,\r
-                                   IPin *pReceivePin,\r
-                                   const AM_MEDIA_TYPE *pmt)\r
-{\r
-    HWCInPin *This = impl_from_IPin(iface);\r
-\r
-    if (!pReceivePin) {\r
-        return E_POINTER;\r
-    }\r
-\r
-    if (This->m_pConnectedPin) {\r
-        return VFW_E_ALREADY_CONNECTED;\r
-    }\r
-\r
-    if (!pmt) {\r
-        return S_OK;\r
-    }\r
-    return S_FALSE;\r
-}\r
-\r
-static STDMETHODIMP HWCPin_ReceiveConnection(IPin *iface, IPin *pConnector,\r
-                                             const AM_MEDIA_TYPE *pmt)\r
-{\r
-    PIN_DIRECTION pd;\r
-    FILTER_STATE fs;\r
-    HWCInPin *This = impl_from_IPin(iface);\r
-\r
-    if (pConnector == NULL || pmt == NULL) {\r
-        return E_POINTER;\r
-    }\r
-\r
-    if (This->m_pConnectedPin) {\r
-        return VFW_E_ALREADY_CONNECTED;\r
-    }\r
-    IBaseFilter_GetState(This->m_pCFilter, 0, &fs);\r
-    if (fs != State_Stopped) {\r
-        return VFW_E_NOT_STOPPED;\r
-    }\r
-    IPin_QueryDirection(pConnector, &pd);\r
-    if (pd == PINDIR_INPUT) {\r
-        return VFW_E_INVALID_DIRECTION;\r
-    }\r
-\r
-    This->m_pConnectedPin = pConnector;\r
-    IPin_AddRef(This->m_pConnectedPin);\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCPin_Disconnect(IPin *iface)\r
-{\r
-    HWCInPin *This = impl_from_IPin(iface);\r
-\r
-    HRESULT hr;\r
-    FILTER_STATE fs;\r
-    IBaseFilter_GetState(This->m_pCFilter, 0, &fs);\r
-    if (fs != State_Stopped) {\r
-        return VFW_E_NOT_STOPPED;\r
-    }\r
-    if (This->m_pConnectedPin == NULL) {\r
-        hr = S_FALSE;\r
-    } else {\r
-        if (This->m_pAllocator) {\r
-            hr = IMemAllocator_Decommit(This->m_pAllocator);\r
-            if (FAILED(hr)) {\r
-                return hr;\r
-            }\r
-            SAFE_RELEASE(This->m_pAllocator);\r
-        }\r
-        SAFE_RELEASE(This->m_pConnectedPin);\r
-        hr = S_OK;\r
-    }\r
-    return hr;\r
-}\r
-\r
-static STDMETHODIMP HWCPin_ConnectedTo(IPin *iface, IPin **ppPin)\r
-{\r
-    HWCInPin *This = impl_from_IPin(iface);\r
-\r
-    if (ppPin == NULL) {\r
-        return E_POINTER;\r
-    }\r
-\r
-    if (This->m_pConnectedPin == NULL) {\r
-        *ppPin = NULL;\r
-        return VFW_E_NOT_CONNECTED;\r
-    } else {\r
-        *ppPin = This->m_pConnectedPin;\r
-        IPin_AddRef(This->m_pConnectedPin);\r
-    }\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCPin_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *pmt)\r
-{\r
-    if (pmt == NULL) {\r
-        return E_POINTER;\r
-    }\r
-    return VFW_E_NOT_CONNECTED;\r
-}\r
-\r
-static STDMETHODIMP HWCPin_QueryPinInfo(IPin *iface, PIN_INFO *pInfo)\r
-{\r
-    HWCInPin *This = impl_from_IPin(iface);\r
-\r
-    if (pInfo == NULL) {\r
-        return E_POINTER;\r
-    }\r
-\r
-    pInfo->pFilter = This->m_pCFilter;\r
-    if (This->m_pCFilter) {\r
-        IBaseFilter_AddRef(This->m_pCFilter);\r
-    }\r
-    memcpy((void *)pInfo->achName, (void *)HWCPinName, sizeof(HWCPinName));\r
-    pInfo->dir = PINDIR_INPUT;\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCPin_QueryDirection(IPin *iface, PIN_DIRECTION *pPinDir)\r
-{\r
-    if (pPinDir == NULL) {\r
-        return E_POINTER;\r
-    }\r
-    *pPinDir = PINDIR_INPUT;\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCPin_QueryId(IPin *iface, LPWSTR *Id)\r
-{\r
-    PVOID pId;\r
-    if (Id == NULL) {\r
-        return E_POINTER;\r
-    }\r
-    pId = CoTaskMemAlloc(sizeof(HWCPinName));\r
-    memcpy((void *)pId, (void *)HWCPinName, sizeof(HWCPinName));\r
-    *Id = (LPWSTR)pId;\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCPin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt)\r
-{\r
-    if (pmt == NULL) {\r
-        return E_POINTER;\r
-    }\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCPin_EnumMediaTypes(IPin *iface,\r
-                                          IEnumMediaTypes **ppEnum)\r
-{\r
-    if (ppEnum == NULL) {\r
-            return E_POINTER;\r
-    }\r
-    return E_NOTIMPL;\r
-}\r
-\r
-static STDMETHODIMP HWCPin_QueryInternalConnections(IPin *iface,\r
-                                                    IPin **ppPin,\r
-                                                    ULONG *nPin)\r
-{\r
-    return E_NOTIMPL;\r
-}\r
-\r
-static STDMETHODIMP HWCPin_EndOfStream(IPin *iface)\r
-{\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCPin_BeginFlush(IPin *iface)\r
-{\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCPin_EndFlush(IPin *iface)\r
-{\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCPin_NewSegment(IPin *iface, REFERENCE_TIME tStart,\r
-                                      REFERENCE_TIME tStop, double dRate)\r
-{\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCMemInputPin_QueryInterface(IMemInputPin *iface,\r
-                                                  REFIID riid, void **ppv)\r
-{\r
-    HWCInPin *This = impl_from_IMemInputPin(iface);\r
-\r
-    if (IsEqualIID(riid, &IID_IUnknown)) {\r
-        *ppv = (IUnknown *)(&This->IMemInputPin_iface);\r
-        IPin_AddRef((IPin *)*ppv);\r
-    } else if (IsEqualIID(riid, &IID_IPin)) {\r
-        *ppv = (IPin *)(&This->IPin_iface);\r
-        IPin_AddRef((IPin *)*ppv);\r
-    } else if (IsEqualIID(riid, &IID_IMemInputPin)) {\r
-        *ppv = (IMemInputPin *)(&This->IMemInputPin_iface);\r
-        IPin_AddRef((IMemInputPin *)*ppv);\r
-    } else {\r
-        *ppv = NULL;\r
-        return E_NOINTERFACE;\r
-    }\r
-\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP_(ULONG) HWCMemInputPin_AddRef(IMemInputPin *iface)\r
-{\r
-    HWCInPin *This = impl_from_IMemInputPin(iface);\r
-\r
-    return InterlockedIncrement(&This->m_cRef);\r
-}\r
-\r
-static STDMETHODIMP_(ULONG) HWCMemInputPin_Release(IMemInputPin *iface)\r
-{\r
-    HWCInPin *This = impl_from_IMemInputPin(iface);\r
-\r
-    if (InterlockedDecrement(&This->m_cRef) == 0) {\r
-        if (This->m_pCallback) {\r
-            SAFE_RELEASE(This->m_pCallback);\r
-        }\r
-        if (This->m_pConnectedPin) {\r
-            SAFE_RELEASE(This->m_pConnectedPin);\r
-        }\r
-        if (This->m_pAllocator) {\r
-            IMemAllocator_Decommit(This->m_pAllocator);\r
-            SAFE_RELEASE(This->m_pAllocator);\r
-        }\r
-        g_free((void *)This);\r
-        This = NULL;\r
-        return 0;\r
-    }\r
-    return This->m_cRef;\r
-}\r
-\r
-static STDMETHODIMP HWCMemInputPin_GetAllocator(IMemInputPin *iface,\r
-                                                IMemAllocator **ppAllocator)\r
-{\r
-    HWCInPin *This = impl_from_IMemInputPin(iface);\r
-\r
-    if (ppAllocator == NULL) {\r
-        return E_POINTER;\r
-    }\r
-\r
-    if (This->m_pAllocator == NULL) {\r
-        HRESULT hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL,\r
-                                        CLSCTX_INPROC_SERVER,\r
-                                        &IID_IMemAllocator,\r
-                                        (void **)&(This->m_pAllocator));\r
-        if (FAILED(hr)) {\r
-            ERR("Failed to CoCreateInstance for retrieving MemoryAllocator\n");\r
-            return hr;\r
-        }\r
-    }\r
-    ASSERT(This->m_pAllocator != NULL);\r
-    *ppAllocator = This->m_pAllocator;\r
-    IMemAllocator_AddRef(This->m_pAllocator);\r
-\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCMemInputPin_NotifyAllocator(IMemInputPin *iface,\r
-                                                   IMemAllocator *pAllocator,\r
-                                                   BOOL bReadOnly)\r
-{\r
-    HWCInPin *This = impl_from_IMemInputPin(iface);\r
-\r
-    if (pAllocator == NULL) {\r
-        return E_POINTER;\r
-    }\r
-\r
-    IMemAllocator *pOldAllocator = This->m_pAllocator;\r
-    IMemAllocator_AddRef(pAllocator);\r
-    This->m_pAllocator = pAllocator;\r
-\r
-    if (pOldAllocator != NULL) {\r
-        SAFE_RELEASE(pOldAllocator);\r
-    }\r
-\r
-    This->m_bReadOnly = bReadOnly;\r
-\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCMemInputPin_GetAllocatorRequirements(\r
-                                   IMemInputPin *iface,\r
-                                   ALLOCATOR_PROPERTIES *pProps)\r
-{\r
-    return E_NOTIMPL;\r
-}\r
-\r
-static STDMETHODIMP HWCMemInputPin_Receive(IMemInputPin *iface,\r
-                                           IMediaSample *pSample)\r
-{\r
-    HWCInPin *This = impl_from_IMemInputPin(iface);\r
-\r
-    if (pSample == NULL) {\r
-        ERR("pSample is NULL\n");\r
-        return E_POINTER;\r
-    }\r
-    if (This->m_pCallback != NULL) {\r
-        HRESULT hr;\r
-        BYTE *pBuffer = NULL;\r
-        DWORD dwSize = 0;\r
-        dwSize = IMediaSample_GetSize(pSample);\r
-        hr = IMediaSample_GetPointer(pSample, &pBuffer);\r
-        if (FAILED(hr)) {\r
-            ERR("Receive function : "\r
-                "failed to IMediaSample_GetPointer, 0x%ld\n", hr);\r
-            return hr;\r
-        }\r
-        hr = IGrabCallback_Grab(This->m_pCallback, dwSize, pBuffer);\r
-        if (FAILED(hr)) {\r
-            ERR("Receive function : failed to IGrabCallback_Grab, 0x%ld\n",\r
-                hr);\r
-            return hr;\r
-        }\r
-    }\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCMemInputPin_ReceiveMultiple(IMemInputPin *iface,\r
-                                                   IMediaSample **pSamples,\r
-                                                   long nSamples,\r
-                                                   long *nSamplesProcessed)\r
-{\r
-    HRESULT hr = S_OK;\r
-\r
-    if (pSamples == NULL) {\r
-        return E_POINTER;\r
-    }\r
-\r
-    *nSamplesProcessed = 0;\r
-\r
-    while (nSamples-- > 0) {\r
-        hr = IMemInputPin_Receive(iface, pSamples[*nSamplesProcessed]);\r
-        if (hr != S_OK) {\r
-            break;\r
-        }\r
-        (*nSamplesProcessed)++;\r
-    }\r
-    return hr;\r
-}\r
-\r
-static STDMETHODIMP HWCMemInputPin_ReceiveCanBlock(IMemInputPin *iface)\r
-{\r
-    return S_FALSE;\r
-}\r
-\r
-static STDMETHODIMP HWCPin_SetCallback(IPin *iface, IGrabCallback *pCaptureCB)\r
-{\r
-    HWCInPin *This = impl_from_IPin(iface);\r
-\r
-    if (pCaptureCB == NULL) {\r
-        SAFE_RELEASE(This->m_pCallback);\r
-    } else {\r
-        This->m_pCallback = pCaptureCB;\r
-        IGrabCallback_AddRef(This->m_pCallback);\r
-    }\r
-\r
-    return S_OK;\r
-}\r
-\r
-\r
-static IPinVtbl HWCPin_Vtbl = {\r
-    HWCPin_QueryInterface,\r
-    HWCPin_AddRef,\r
-    HWCPin_Release,\r
-    HWCPin_Connect,\r
-    HWCPin_ReceiveConnection,\r
-    HWCPin_Disconnect,\r
-    HWCPin_ConnectedTo,\r
-    HWCPin_ConnectionMediaType,\r
-    HWCPin_QueryPinInfo,\r
-    HWCPin_QueryDirection,\r
-    HWCPin_QueryId,\r
-    HWCPin_QueryAccept,\r
-    HWCPin_EnumMediaTypes,\r
-    HWCPin_QueryInternalConnections,\r
-    HWCPin_EndOfStream,\r
-    HWCPin_BeginFlush,\r
-    HWCPin_EndFlush,\r
-    HWCPin_NewSegment\r
-};\r
-\r
-static IMemInputPinVtbl HWCMemInputPin_Vtbl = {\r
-    HWCMemInputPin_QueryInterface,\r
-    HWCMemInputPin_AddRef,\r
-    HWCMemInputPin_Release,\r
-    HWCMemInputPin_GetAllocator,\r
-    HWCMemInputPin_NotifyAllocator,\r
-    HWCMemInputPin_GetAllocatorRequirements,\r
-    HWCMemInputPin_Receive,\r
-    HWCMemInputPin_ReceiveMultiple,\r
-    HWCMemInputPin_ReceiveCanBlock\r
-};\r
-\r
-static STDMETHODIMP HWCInPin_Construct(IBaseFilter *pFilter, IPin **ppv)\r
-{\r
-    HWCInPin *This = (HWCInPin *)g_malloc0(sizeof(HWCInPin));\r
-\r
-    if (!This) {\r
-        ERR("failed to HWCInPin_Construct, E_OUTOFMEMORY\n");\r
-        return E_OUTOFMEMORY;\r
-    }\r
-\r
-    This->IPin_iface.lpVtbl = &HWCPin_Vtbl;\r
-    This->IMemInputPin_iface.lpVtbl = &HWCMemInputPin_Vtbl;\r
-    This->m_bReadOnly = FALSE;\r
-    This->m_pCFilter = pFilter;\r
-    This->m_pConnectedPin = NULL;\r
-    This->m_pCallback = NULL;\r
-    This->m_pAllocator = NULL;\r
-    This->m_cRef = 1;\r
-    This->SetGrabCallbackIF = HWCPin_SetCallback;\r
-    *ppv = &This->IPin_iface;\r
-\r
-    return S_OK;\r
-}\r
-\r
-/*\r
- * HWCEnumPins\r
- */\r
-\r
-typedef struct HWCEnumPins {\r
-    IEnumPins IEnumPins_iface;\r
-    IBaseFilter *m_pFilter;\r
-    int m_nPos;\r
-    long m_cRef;\r
-} HWCEnumPins;\r
-\r
-static inline HWCEnumPins *impl_from_IEnumPins(IEnumPins *iface)\r
-{\r
-    return CONTAINING_RECORD(iface, HWCEnumPins, IEnumPins_iface);\r
-}\r
-\r
-static STDMETHODIMP HWCEnumPins_QueryInterface(IEnumPins *iface,\r
-                                               REFIID riid, void **ppv)\r
-{\r
-    if (ppv == NULL) {\r
-        return E_POINTER;\r
-    }\r
-\r
-    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumPins)) {\r
-        *ppv = iface;\r
-    } else {\r
-        *ppv = NULL;\r
-        return E_NOINTERFACE;\r
-    }\r
-\r
-    IEnumPins_AddRef(iface);\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP_(ULONG) HWCEnumPins_AddRef(IEnumPins *iface)\r
-{\r
-    HWCEnumPins *This = impl_from_IEnumPins(iface);\r
-\r
-    return InterlockedIncrement(&This->m_cRef);\r
-}\r
-\r
-static STDMETHODIMP_(ULONG) HWCEnumPins_Release(IEnumPins *iface)\r
-{\r
-    HWCEnumPins *This = impl_from_IEnumPins(iface);\r
-\r
-    if (InterlockedDecrement(&This->m_cRef) == 0) {\r
-        if (This->m_pFilter) {\r
-            SAFE_RELEASE(This->m_pFilter);\r
-        }\r
-        This->m_nPos = 0;\r
-        g_free((void *)This);\r
-        This = NULL;\r
-        return 0;\r
-    }\r
-    return This->m_cRef;\r
-}\r
-\r
-static STDMETHODIMP HWCEnumPins_Next(IEnumPins *iface, ULONG cPins,\r
-                                     IPin **ppPins, ULONG *pcFetched)\r
-{\r
-    ULONG fetched;\r
-    HWCEnumPins *This = impl_from_IEnumPins(iface);\r
-\r
-    if (ppPins == NULL) {\r
-        return E_POINTER;\r
-    }\r
-\r
-    if (This->m_nPos < 1 && cPins > 0) {\r
-        IPin *pPin;\r
-        IBaseFilter_FindPin(This->m_pFilter, HWCPinName, &pPin);\r
-        *ppPins = pPin;\r
-        fetched = 1;\r
-        This->m_nPos++;\r
-    } else {\r
-        fetched = 0;\r
-    }\r
-\r
-    if (pcFetched != NULL) {\r
-        *pcFetched = fetched;\r
-    }\r
-\r
-    return (fetched == cPins) ? S_OK : S_FALSE;\r
-}\r
-\r
-static STDMETHODIMP HWCEnumPins_Skip(IEnumPins *iface, ULONG cPins)\r
-{\r
-    HWCEnumPins *This = impl_from_IEnumPins(iface);\r
-    This->m_nPos += cPins;\r
-    return (This->m_nPos >= 1) ? S_FALSE : S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCEnumPins_Reset(IEnumPins *iface)\r
-{\r
-    HWCEnumPins *This = impl_from_IEnumPins(iface);\r
-    This->m_nPos = 0;\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCEnumPins_Construct(IBaseFilter *pFilter,\r
-                                          int nPos, IEnumPins **ppv);\r
-\r
-static STDMETHODIMP HWCEnumPins_Clone(IEnumPins *iface, IEnumPins **ppEnum)\r
-{\r
-    HWCEnumPins *This = impl_from_IEnumPins(iface);\r
-\r
-    if (ppEnum == NULL) {\r
-        return E_POINTER;\r
-    }\r
-\r
-    HWCEnumPins_Construct(This->m_pFilter, This->m_nPos, ppEnum);\r
-    if (*ppEnum == NULL) {\r
-        ERR("failed to HWCEnumPins_Construct in clone, E_OUTOFMEMORY\n");\r
-        return E_OUTOFMEMORY;\r
-    }\r
-\r
-    return S_OK;\r
-}\r
-\r
-static IEnumPinsVtbl HWCEnumPins_Vtbl = {\r
-    HWCEnumPins_QueryInterface,\r
-    HWCEnumPins_AddRef,\r
-    HWCEnumPins_Release,\r
-    HWCEnumPins_Next,\r
-    HWCEnumPins_Skip,\r
-    HWCEnumPins_Reset,\r
-    HWCEnumPins_Clone\r
-};\r
-\r
-\r
-static STDMETHODIMP HWCEnumPins_Construct(IBaseFilter *pFilter,\r
-                                          int nPos, IEnumPins **ppv)\r
-{\r
-    HWCEnumPins *This = (HWCEnumPins *)g_malloc0(sizeof(HWCEnumPins));\r
-\r
-    if (!This) {\r
-        ERR("failed to HWCEnumPins_Construct, E_OUTOFMEMORY\n");\r
-        return E_OUTOFMEMORY;\r
-    }\r
-\r
-    This->IEnumPins_iface.lpVtbl = &HWCEnumPins_Vtbl;\r
-    This->m_pFilter = pFilter;\r
-    if (This->m_pFilter) {\r
-        IBaseFilter_AddRef(This->m_pFilter);\r
-    }\r
-    This->m_cRef = 1;\r
-    This->m_nPos = nPos;\r
-    *ppv = &This->IEnumPins_iface;\r
-\r
-    return S_OK;\r
-}\r
-\r
-/*\r
- * HWCFilter\r
- */\r
-\r
-typedef struct HWCFilter {\r
-    IBaseFilter IBaseFilter_iface;\r
-    IPin *m_pPin;\r
-    IFilterGraph *m_pFilterGraph;\r
-    FILTER_STATE m_state;\r
-    long m_cRef;\r
-} HWCFilter;\r
-\r
-static inline HWCFilter *impl_from_IBaseFilter(IBaseFilter *iface)\r
-{\r
-    return CONTAINING_RECORD(iface, HWCFilter, IBaseFilter_iface);\r
-}\r
-\r
-static STDMETHODIMP HWCFilter_QueryInterface(IBaseFilter *iface,\r
-                                             REFIID riid, void **ppv)\r
-{\r
-    if (IsEqualIID(riid, &IID_IUnknown)) {\r
-        *ppv = (IUnknown *)iface;\r
-    } else if (IsEqualIID(riid, &IID_IPersist)) {\r
-        *ppv = (IPersist *)iface;\r
-    } else if (IsEqualIID(riid, &IID_IMediaFilter)) {\r
-        *ppv = (IMediaFilter *)iface;\r
-    } else if (IsEqualIID(riid, &IID_IBaseFilter)) {\r
-        *ppv = (IBaseFilter *)iface;\r
-    } else {\r
-        *ppv = NULL;\r
-        return E_NOINTERFACE;\r
-    }\r
-\r
-    IBaseFilter_AddRef(iface);\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP_(ULONG) HWCFilter_AddRef(IBaseFilter *iface)\r
-{\r
-    HWCFilter *This = impl_from_IBaseFilter(iface);\r
-\r
-    return InterlockedIncrement(&This->m_cRef);\r
-}\r
-\r
-static STDMETHODIMP_(ULONG) HWCFilter_Release(IBaseFilter *iface)\r
-{\r
-    HWCFilter *This = impl_from_IBaseFilter(iface);\r
-\r
-    if (InterlockedDecrement(&This->m_cRef) == 0) {\r
-        if (This->m_pPin) {\r
-            SAFE_RELEASE(This->m_pPin);\r
-        }\r
-        g_free((void *)This);\r
-        This = NULL;\r
-        return 0;\r
-    }\r
-    return This->m_cRef;\r
-}\r
-\r
-static STDMETHODIMP HWCFilter_GetClassID(IBaseFilter *iface, CLSID *pClsID)\r
-{\r
-    if (pClsID == NULL) {\r
-        return E_POINTER;\r
-    }\r
-    return E_NOTIMPL;\r
-}\r
-\r
-static STDMETHODIMP HWCFilter_GetState(IBaseFilter *iface, DWORD dwMSecs,\r
-                                       FILTER_STATE *State)\r
-{\r
-    HWCFilter *This = impl_from_IBaseFilter(iface);\r
-    *State = This->m_state;\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCFilter_SetSyncSource(IBaseFilter *iface,\r
-                                            IReferenceClock *pClock)\r
-{\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCFilter_GetSyncSource(IBaseFilter *iface,\r
-                                            IReferenceClock **pClock)\r
-{\r
-    *pClock = NULL;\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCFilter_Stop(IBaseFilter *iface)\r
-{\r
-    HWCFilter *This = impl_from_IBaseFilter(iface);\r
-\r
-    IPin_EndFlush(This->m_pPin);\r
-    This->m_state = State_Stopped;\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCFilter_Pause(IBaseFilter *iface)\r
-{\r
-    HWCFilter *This = impl_from_IBaseFilter(iface);\r
-    This->m_state = State_Paused;\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCFilter_Run(IBaseFilter *iface, REFERENCE_TIME tStart)\r
-{\r
-    HWCFilter *This = impl_from_IBaseFilter(iface);\r
-\r
-    if (This->m_state == State_Stopped) {\r
-        HRESULT hr;\r
-        hr = IBaseFilter_Pause(iface);\r
-        if (FAILED(hr)) {\r
-            ERR("HWCFilter_Run : Failed to IBaseFilter_Pause, ret=0xld%\n", hr);\r
-            return hr;\r
-        }\r
-    }\r
-\r
-    This->m_state = State_Running;\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCFilter_EnumPins(IBaseFilter *iface, IEnumPins **ppEnum)\r
-{\r
-    if (ppEnum == NULL) {\r
-        return E_POINTER;\r
-    }\r
-\r
-    HWCEnumPins_Construct(iface, 0, ppEnum);\r
-    return *ppEnum == NULL ? E_OUTOFMEMORY : S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCFilter_FindPin(IBaseFilter *iface, LPCWSTR Id,\r
-                                      IPin **ppPin)\r
-{\r
-    HWCFilter *This = impl_from_IBaseFilter(iface);\r
-\r
-    if (ppPin == NULL) {\r
-        return E_POINTER;\r
-    }\r
-\r
-    if (memcmp((void *)Id, (void *)HWCPinName, sizeof(HWCPinName))) {\r
-        return VFW_E_NOT_FOUND;\r
-    }\r
-\r
-    if (!This->m_pPin) {\r
-        HWCInPin_Construct(iface, &This->m_pPin);\r
-    }\r
-    *ppPin = This->m_pPin;\r
-\r
-    IPin_AddRef(This->m_pPin);\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCFilter_QueryFilterInfo(IBaseFilter *iface,\r
-                                              FILTER_INFO *pInfo)\r
-{\r
-    HWCFilter *This = impl_from_IBaseFilter(iface);\r
-\r
-    if (pInfo == NULL) {\r
-        return E_POINTER;\r
-    }\r
-\r
-    memcpy((void *)pInfo->achName,\r
-           (void *)HWCFilterName,\r
-           sizeof(HWCFilterName));\r
-    pInfo->pGraph = This->m_pFilterGraph;\r
-    if (This->m_pFilterGraph) {\r
-        IFilterGraph_AddRef(This->m_pFilterGraph);\r
-    }\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCFilter_JoinFilterGraph(IBaseFilter *iface,\r
-                                              IFilterGraph *pGraph,\r
-                                              LPCWSTR pName)\r
-{\r
-    HWCFilter *This = impl_from_IBaseFilter(iface);\r
-\r
-    This->m_pFilterGraph = pGraph;\r
-    return S_OK;\r
-}\r
-\r
-static STDMETHODIMP HWCFilter_QueryVendorInfo(IBaseFilter *iface,\r
-                                              LPWSTR *pVendorInfo)\r
-{\r
-    return E_NOTIMPL;\r
-}\r
-\r
-static IBaseFilterVtbl HWCFilter_Vtbl = {\r
-    HWCFilter_QueryInterface,\r
-    HWCFilter_AddRef,\r
-    HWCFilter_Release,\r
-    HWCFilter_GetClassID,\r
-    HWCFilter_Stop,\r
-    HWCFilter_Pause,\r
-    HWCFilter_Run,\r
-    HWCFilter_GetState,\r
-    HWCFilter_SetSyncSource,\r
-    HWCFilter_GetSyncSource,\r
-    HWCFilter_EnumPins,\r
-    HWCFilter_FindPin,\r
-    HWCFilter_QueryFilterInfo,\r
-    HWCFilter_JoinFilterGraph,\r
-    HWCFilter_QueryVendorInfo\r
-};\r
-\r
-static STDMETHODIMP HWCFilter_Construct(IBaseFilter **ppv)\r
-{\r
-    HWCFilter *This = (HWCFilter *)g_malloc0(sizeof(HWCFilter));\r
-\r
-    if (!This) {\r
-        ERR("failed to HWCFilter_Construct, E_OUTOFMEMORY\n");\r
-        return E_OUTOFMEMORY;\r
-    }\r
-\r
-    This->IBaseFilter_iface.lpVtbl = &HWCFilter_Vtbl;\r
-    This->m_pFilterGraph = NULL;\r
-    This->m_state = State_Stopped;\r
-    This->m_cRef = 1;\r
-    HWCInPin_Construct(&This->IBaseFilter_iface, &This->m_pPin);\r
-    *ppv = &This->IBaseFilter_iface;\r
-\r
-    return S_OK;\r
-}\r
-\r
-/**********************************************************\r
- *\r
- * Virtual device implementations\r
- *\r
- **********************************************************/\r
-\r
-\r
-/*\r
- * Declaration global variables for Win32 COM Interfaces\r
- */\r
-IGraphBuilder *g_pGB ;\r
-ICaptureGraphBuilder2 *g_pCGB;\r
-IMediaControl *g_pMediaControl;\r
-\r
-IPin *g_pOutputPin;\r
-IPin *g_pInputPin;\r
-IBaseFilter *g_pDstFilter;\r
-IBaseFilter *g_pSrcFilter;\r
-\r
-IGrabCallback *g_pCallback;\r
-\r
-/* V4L2 defines copy from videodev2.h */\r
-#define V4L2_CTRL_FLAG_SLIDER       0x0020\r
-\r
-#define V4L2_CTRL_CLASS_USER        0x00980000\r
-#define V4L2_CID_BASE               (V4L2_CTRL_CLASS_USER | 0x900)\r
-#define V4L2_CID_BRIGHTNESS         (V4L2_CID_BASE+0)\r
-#define V4L2_CID_CONTRAST           (V4L2_CID_BASE+1)\r
-#define V4L2_CID_SATURATION         (V4L2_CID_BASE+2)\r
-#define V4L2_CID_SHARPNESS          (V4L2_CID_BASE+27)\r
-\r
-#define V4L2_PIX_FMT_YUYV    MAKEFOURCC('Y', 'U', 'Y', 'V') /* 16  YUV 4:2:2 */\r
-#define V4L2_PIX_FMT_YUV420  MAKEFOURCC('Y', 'U', '1', '2') /* 12  YUV 4:2:0 */\r
-#define V4L2_PIX_FMT_YVU420  MAKEFOURCC('Y', 'V', '1', '2') /* 12  YVU 4:2:0 */\r
-#define V4L2_PIX_FMT_RGB24   MAKEFOURCC('R', 'G', 'B', '3') /* 24  RGB-8-8-8 */\r
-\r
-typedef struct tagMaruCamConvertPixfmt {\r
-    uint32_t fmt;   /* fourcc */\r
-    uint32_t bpp;   /* bits per pixel, 0 for compressed formats */\r
-    uint32_t needs_conversion;\r
-} MaruCamConvertPixfmt;\r
-\r
-static MaruCamConvertPixfmt supported_dst_pixfmts[] = {\r
-        { V4L2_PIX_FMT_YUYV, 16, 0 },\r
-        { V4L2_PIX_FMT_YUV420, 12, 0 },\r
-        { V4L2_PIX_FMT_YVU420, 12, 0 },\r
-};\r
-\r
-typedef struct tagMaruCamConvertFrameInfo {\r
-    uint32_t width;\r
-    uint32_t height;\r
-} MaruCamConvertFrameInfo;\r
-\r
-static MaruCamConvertFrameInfo supported_dst_frames[] = {\r
-        { 640, 480 },\r
-        { 352, 288 },\r
-        { 320, 240 },\r
-        { 176, 144 },\r
-        { 160, 120 },\r
-};\r
-\r
-#define MARUCAM_CTRL_VALUE_MAX      20\r
-#define MARUCAM_CTRL_VALUE_MIN      1\r
-#define MARUCAM_CTRL_VALUE_MID      10\r
-#define MARUCAM_CTRL_VALUE_STEP     1\r
-\r
-struct marucam_qctrl {\r
-    uint32_t id;\r
-    uint32_t hit;\r
-    long min;\r
-    long max;\r
-    long step;\r
-    long init_val;\r
-};\r
-\r
-static struct marucam_qctrl qctrl_tbl[] = {\r
-    { V4L2_CID_BRIGHTNESS, 0, },\r
-    { V4L2_CID_CONTRAST, 0, },\r
-    { V4L2_CID_SATURATION, 0, },\r
-    { V4L2_CID_SHARPNESS, 0, },\r
-};\r
-\r
-static MaruCamState *g_state;\r
-\r
-static uint32_t ready_count;\r
-static uint32_t cur_fmt_idx;\r
-static uint32_t cur_frame_idx;\r
-static void *grab_buf;\r
-static uint32_t g_dwSrcFmt;\r
-\r
-\r
-/*\r
- * Helper functions - converting image formats, converting values\r
- */\r
-\r
-static uint32_t get_bytesperline(uint32_t pixfmt, uint32_t width)\r
-{\r
-    uint32_t bytesperline;\r
-\r
-    switch (pixfmt) {\r
-    case V4L2_PIX_FMT_YUV420:\r
-    case V4L2_PIX_FMT_YVU420:\r
-        bytesperline = (width * 12) >> 3;\r
-        break;\r
-    case V4L2_PIX_FMT_YUYV:\r
-    default:\r
-        bytesperline = width * 2;\r
-        break;\r
-    }\r
-\r
-    return bytesperline;\r
-}\r
-\r
-static uint32_t get_sizeimage(uint32_t pixfmt, uint32_t width, uint32_t height)\r
-{\r
-    return get_bytesperline(pixfmt, width) * height;\r
-}\r
-\r
-void yuyv_to_yuv420(const unsigned char *src, unsigned char *dest,\r
-        uint32_t width, uint32_t height, uint32_t yvu);\r
-void rgb24_to_yuv420(const unsigned char *src, unsigned char *dest,\r
-        uint32_t width, uint32_t height, uint32_t yvu);\r
-void rgb24_to_yuyv(unsigned char *src, unsigned char *dest,\r
-        uint32_t width, uint32_t height);\r
-void yuv420_to_yvu420(unsigned char *src, unsigned char *dest,\r
-        uint32_t width, uint32_t height);\r
-void yuv420_to_yuyv(unsigned char *src, unsigned char *dest,\r
-        uint32_t width, uint32_t height);\r
-\r
-static long value_convert_from_guest(long min, long max, long value)\r
-{\r
-    double rate = 0.0;\r
-    long dist = 0, ret = 0;\r
-\r
-    dist = max - min;\r
-\r
-    if (dist < MARUCAM_CTRL_VALUE_MAX) {\r
-        rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;\r
-        ret = min + (int32_t)(value / rate);\r
-    } else {\r
-        rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;\r
-        ret = min + (int32_t)(rate * value);\r
-    }\r
-    return ret;\r
-}\r
-\r
-static long value_convert_to_guest(long min, long max, long value)\r
-{\r
-    double rate  = 0.0;\r
-    long dist = 0, ret = 0;\r
-\r
-    dist = max - min;\r
-\r
-    if (dist < MARUCAM_CTRL_VALUE_MAX) {\r
-        rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;\r
-        ret = (int32_t)((double)(value - min) * rate);\r
-    } else {\r
-        rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;\r
-        ret = (int32_t)((double)(value - min) / rate);\r
-    }\r
-\r
-    return ret;\r
-}\r
-\r
-/*\r
- * Callback function for grab frames\r
- */\r
-static STDMETHODIMP marucam_device_callbackfn(ULONG dwSize, BYTE *pBuffer)\r
-{\r
-    void *tmp_buf;\r
-    uint32_t width, height, fmt, imgsize;\r
-\r
-    width = supported_dst_frames[cur_frame_idx].width;\r
-    height = supported_dst_frames[cur_frame_idx].height;\r
-    fmt = supported_dst_pixfmts[cur_fmt_idx].fmt;\r
-    imgsize = get_sizeimage(fmt, width, height);\r
-\r
-    if (imgsize > (uint32_t)dwSize) {\r
-        ERR("Image size is mismatched\n");\r
-        return E_FAIL;\r
-    }\r
-\r
-    switch (g_dwSrcFmt) {\r
-    case V4L2_PIX_FMT_YUYV:\r
-        switch (fmt) {\r
-        case V4L2_PIX_FMT_YUV420:\r
-            yuyv_to_yuv420(pBuffer, grab_buf, width, height, 0);\r
-            break;\r
-        case V4L2_PIX_FMT_YVU420:\r
-            yuyv_to_yuv420(pBuffer, grab_buf, width, height, 1);\r
-            break;\r
-        case V4L2_PIX_FMT_YUYV:\r
-            memcpy(grab_buf, (void *)pBuffer, (size_t)dwSize);\r
-            break;\r
-        default:\r
-            ERR("Invalid pixel format\n");\r
-            return E_FAIL;\r
-        }\r
-        break;\r
-    case V4L2_PIX_FMT_RGB24:\r
-        switch (fmt) {\r
-        case V4L2_PIX_FMT_YUV420:\r
-            rgb24_to_yuv420(pBuffer, grab_buf, width, height, 0);\r
-            break;\r
-        case V4L2_PIX_FMT_YVU420:\r
-            rgb24_to_yuv420(pBuffer, grab_buf, width, height, 1);\r
-            break;\r
-        case V4L2_PIX_FMT_YUYV:\r
-            rgb24_to_yuyv(pBuffer, grab_buf, width, height);\r
-            break;\r
-        default:\r
-            ERR("Invalid pixel format\n");\r
-            return E_FAIL;\r
-        }\r
-        break;\r
-    case V4L2_PIX_FMT_YUV420:\r
-        switch (fmt) {\r
-        case V4L2_PIX_FMT_YUV420:\r
-            memcpy(grab_buf, (void *)pBuffer, (size_t)dwSize);\r
-            break;\r
-        case V4L2_PIX_FMT_YVU420:\r
-            yuv420_to_yvu420(pBuffer, grab_buf, width, height);\r
-            break;\r
-        case V4L2_PIX_FMT_YUYV:\r
-            yuv420_to_yuyv(pBuffer, grab_buf, width, height);\r
-            break;\r
-        default:\r
-            ERR("Invalid pixel format\n");\r
-            return E_FAIL;\r
-        }\r
-        break;\r
-    default:\r
-        ERR("Invalid pixel format\n");\r
-        return E_FAIL;\r
-    }\r
-\r
-    qemu_mutex_lock(&g_state->thread_mutex);\r
-    if (g_state->streamon) {\r
-        if (ready_count < MARUCAM_SKIPFRAMES) {\r
-            /* skip a frame cause first some frame are distorted */\r
-            ++ready_count;\r
-            TRACE("skip %d frame\n", ready_count);\r
-            qemu_mutex_unlock(&g_state->thread_mutex);\r
-            return S_OK;\r
-        }\r
-        if (g_state->req_frame == 0) {\r
-            TRACE("there is no request\n");\r
-            qemu_mutex_unlock(&g_state->thread_mutex);\r
-            return S_OK;\r
-        }\r
-        tmp_buf = g_state->vaddr + g_state->buf_size * (g_state->req_frame - 1);\r
-        memcpy(tmp_buf, grab_buf, g_state->buf_size);\r
-        g_state->req_frame = 0; /* clear request */\r
-        g_state->isr |= 0x01;   /* set a flag of rasing a interrupt */\r
-        qemu_bh_schedule(g_state->tx_bh);\r
-    }\r
-    qemu_mutex_unlock(&g_state->thread_mutex);\r
-    return S_OK;\r
-}\r
-\r
-/*\r
- * Internal functions for manipulate interfaces\r
- */\r
-\r
-static STDMETHODIMP_(void) CloseInterfaces(void)\r
-{\r
-    if (g_pMediaControl) {\r
-        g_pMediaControl->lpVtbl->Stop(g_pMediaControl);\r
-    }\r
-\r
-    if (g_pOutputPin) {\r
-        g_pOutputPin->lpVtbl->Disconnect(g_pOutputPin);\r
-    }\r
-\r
-    SAFE_RELEASE(g_pGB);\r
-    SAFE_RELEASE(g_pCGB);\r
-    SAFE_RELEASE(g_pMediaControl);\r
-    SAFE_RELEASE(g_pOutputPin);\r
-    SAFE_RELEASE(g_pInputPin);\r
-    SAFE_RELEASE(g_pDstFilter);\r
-    SAFE_RELEASE(g_pSrcFilter);\r
-    SAFE_RELEASE(g_pCallback);\r
-}\r
-\r
-static STDMETHODIMP_(void) DeleteMediaType(AM_MEDIA_TYPE *pmt)\r
-{\r
-    if (pmt == NULL) {\r
-        return;\r
-    }\r
-\r
-    if (pmt->cbFormat != 0) {\r
-        CoTaskMemFree((PVOID)pmt->pbFormat);\r
-        pmt->cbFormat = 0;\r
-        pmt->pbFormat = NULL;\r
-    }\r
-    if (pmt->pUnk != NULL) {\r
-        pmt->pUnk->lpVtbl->Release(pmt->pUnk);\r
-        pmt->pUnk = NULL;\r
-    }\r
-\r
-    CoTaskMemFree((PVOID)pmt);\r
-}\r
-\r
-static STDMETHODIMP GetPin(IBaseFilter *pFilter,\r
-                           PIN_DIRECTION PinDir, IPin **ppPin)\r
-{\r
-    HRESULT hr;\r
-    IEnumPins *pEnum = NULL;\r
-    IPin *pPin = NULL;\r
-\r
-    if (ppPin == NULL) {\r
-        return E_POINTER;\r
-    }\r
-\r
-    hr = pFilter->lpVtbl->EnumPins(pFilter, &pEnum);\r
-    if (FAILED(hr)) {\r
-        return hr;\r
-    }\r
-\r
-    while (pEnum->lpVtbl->Next(pEnum, 1, &pPin, 0) == S_OK) {\r
-        PIN_DIRECTION PinDirThis;\r
-        hr = pPin->lpVtbl->QueryDirection(pPin, &PinDirThis);\r
-        if (FAILED(hr)) {\r
-            SAFE_RELEASE(pPin);\r
-            SAFE_RELEASE(pEnum);\r
-            return hr;\r
-        }\r
-        if (PinDir == PinDirThis) {\r
-            *ppPin = pPin;\r
-            SAFE_RELEASE(pEnum);\r
-            return S_OK;\r
-        }\r
-        SAFE_RELEASE(pPin);\r
-    }\r
-\r
-    SAFE_RELEASE(pEnum);\r
-    return S_FALSE;\r
-}\r
-\r
-static STDMETHODIMP GraphBuilder_Init(void)\r
-{\r
-    HRESULT hr;\r
-\r
-    hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC,\r
-                          &IID_IGraphBuilder, (void **)&g_pGB);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to create instance of GraphBuilder, 0x%x\n", hr);\r
-        return hr;\r
-    }\r
-\r
-    hr = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,\r
-                          &IID_ICaptureGraphBuilder2, (void **)&g_pCGB);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to create instance of CaptureGraphBuilder2, 0x%x\n", hr);\r
-        return hr;\r
-    }\r
-\r
-    hr = g_pCGB->lpVtbl->SetFiltergraph(g_pCGB, g_pGB);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to SetFiltergraph, 0x%x\n", hr);\r
-        return hr;\r
-    }\r
-\r
-    hr = g_pGB->lpVtbl->QueryInterface(g_pGB, &IID_IMediaControl,\r
-                                       (void **)&g_pMediaControl);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to QueryInterface for IMediaControl, 0x%x\n", hr);\r
-        return hr;\r
-    }\r
-\r
-    hr = HWCGrabCallback_Construct(&g_pCallback);\r
-    if (g_pCallback == NULL) {\r
-        hr = E_OUTOFMEMORY;\r
-    }\r
-\r
-    hr = ((HWCGrabCallback *)g_pCallback)->SetCallback(g_pCallback,\r
-                            (CallbackFn)marucam_device_callbackfn);\r
-\r
-    return hr;\r
-}\r
-\r
-static STDMETHODIMP BindSourceFilter(void)\r
-{\r
-    HRESULT hr;\r
-    ICreateDevEnum *pCreateDevEnum = NULL;\r
-    IEnumMoniker *pEnumMK = NULL;\r
-    IMoniker *pMoniKer;\r
-\r
-    hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,\r
-                          &IID_ICreateDevEnum,\r
-                          (void **)&pCreateDevEnum);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to create instance of CreateDevEnum, 0x%x\n", hr);\r
-        return hr;\r
-    }\r
-\r
-    hr = pCreateDevEnum->lpVtbl->CreateClassEnumerator(pCreateDevEnum,\r
-                                      &CLSID_VideoInputDeviceCategory,\r
-                                      &pEnumMK, 0);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to get VideoInputDeviceCategory, 0x%x\n", hr);\r
-        SAFE_RELEASE(pCreateDevEnum);\r
-        return hr;\r
-    }\r
-\r
-    if (!pEnumMK) {\r
-        ERR("ClassEnumerator moniker is NULL\n");\r
-        SAFE_RELEASE(pCreateDevEnum);\r
-        return E_FAIL;\r
-    }\r
-    pEnumMK->lpVtbl->Reset(pEnumMK);\r
-\r
-    hr = pEnumMK->lpVtbl->Next(pEnumMK, 1, &pMoniKer, NULL);\r
-    if (hr == S_FALSE) {\r
-        hr = E_FAIL;\r
-    }\r
-    if (SUCCEEDED(hr)) {\r
-        IPropertyBag *pBag = NULL;\r
-        hr = pMoniKer->lpVtbl->BindToStorage(pMoniKer, 0, 0,\r
-                                             &IID_IPropertyBag,\r
-                                             (void **)&pBag);\r
-        if (SUCCEEDED(hr)) {\r
-            VARIANT var;\r
-            var.vt = VT_BSTR;\r
-            hr = pBag->lpVtbl->Read(pBag, L"FriendlyName", &var, NULL);\r
-            if (hr == NOERROR) {\r
-                hr = pMoniKer->lpVtbl->BindToObject(pMoniKer, NULL, NULL,\r
-                                                    &IID_IBaseFilter,\r
-                                                    (void **)&g_pSrcFilter);\r
-                if (FAILED(hr)) {\r
-                    ERR("Counldn't bind moniker to filter object!!\n");\r
-                } else {\r
-                    g_pSrcFilter->lpVtbl->AddRef(g_pSrcFilter);\r
-                }\r
-                SysFreeString(var.bstrVal);\r
-            }\r
-            SAFE_RELEASE(pBag);\r
-        }\r
-        SAFE_RELEASE(pMoniKer);\r
-    }\r
-\r
-    if (SUCCEEDED(hr)) {\r
-        hr = g_pGB->lpVtbl->AddFilter(g_pGB, g_pSrcFilter, L"Video Capture");\r
-        if (hr != S_OK && hr != S_FALSE) {\r
-            ERR("Counldn't add Video Capture filter to our graph!\n");\r
-            SAFE_RELEASE(g_pSrcFilter);\r
-        }\r
-    }\r
-    SAFE_RELEASE(pEnumMK);\r
-    SAFE_RELEASE(pCreateDevEnum);\r
-\r
-    return hr;\r
-}\r
-\r
-static STDMETHODIMP BindTargetFilter(void)\r
-{\r
-    HRESULT hr;\r
-    hr = HWCFilter_Construct(&g_pDstFilter);\r
-\r
-    if (SUCCEEDED(hr) && g_pDstFilter) {\r
-        hr = g_pGB->lpVtbl->AddFilter(g_pGB, g_pDstFilter, L"HWCFilter");\r
-        if (FAILED(hr)) {\r
-            ERR("Counldn't add HWCFilterr to our graph!\n");\r
-            SAFE_RELEASE(g_pDstFilter);\r
-        }\r
-    }\r
-    return hr;\r
-}\r
-\r
-static STDMETHODIMP ConnectFilters(void)\r
-{\r
-    HRESULT hr;\r
-\r
-    hr = GetPin(g_pSrcFilter, PINDIR_OUTPUT , &g_pOutputPin);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to get output pin. 0x%x\n", hr);\r
-        return hr;\r
-    }\r
-\r
-    hr = GetPin(g_pDstFilter, PINDIR_INPUT , &g_pInputPin);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to get input pin. 0x%x\n", hr);\r
-        return hr;\r
-    }\r
-\r
-    hr = g_pGB->lpVtbl->Connect(g_pGB, g_pOutputPin, g_pInputPin);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to connect pins. 0x%x\n", hr);\r
-    }\r
-    return hr;\r
-}\r
-\r
-static STDMETHODIMP DisconnectPins(void)\r
-{\r
-    HRESULT hr;\r
-\r
-    hr = g_pGB->lpVtbl->Disconnect(g_pGB, g_pOutputPin);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to disconnect output pin. 0x%x\n", hr);\r
-        return hr;\r
-    }\r
-\r
-    hr = g_pGB->lpVtbl->Disconnect(g_pGB, g_pInputPin);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to disconnect input pin. 0x%x\n", hr);\r
-    }\r
-\r
-    return hr;\r
-}\r
-\r
-static STDMETHODIMP RemoveFilters(void)\r
-{\r
-    HRESULT hr;\r
-\r
-    hr = g_pGB->lpVtbl->RemoveFilter(g_pGB, g_pSrcFilter);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to remove source filer. 0x%x\n", hr);\r
-        return hr;\r
-    }\r
-\r
-    hr = g_pGB->lpVtbl->RemoveFilter(g_pGB, g_pDstFilter);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to remove destination filer. 0x%x\n", hr);\r
-    }\r
-\r
-    return hr;\r
-}\r
-\r
-/* default fps is 15 */\r
-#define MARUCAM_DEFAULT_FRAMEINTERVAL    666666\r
-\r
-static STDMETHODIMP SetFormat(uint32_t dwWidth, uint32_t dwHeight,\r
-                              uint32_t dwDstFmt, uint32_t *dwSrcFmt)\r
-{\r
-    HRESULT hr;\r
-    IAMStreamConfig *pSConfig;\r
-    int iCount = 0, iSize = 0;\r
-    DWORD dwYUY2 = MAKEFOURCC('Y', 'U', 'Y', '2');\r
-    DWORD dwI420 = MAKEFOURCC('I', '4', '2', '0');\r
-\r
-    if (dwSrcFmt == NULL) {\r
-        ERR("invalid the source format pointer\n");\r
-        return E_FAIL;\r
-    }\r
-\r
-    hr = g_pCGB->lpVtbl->FindInterface(g_pCGB, &PIN_CATEGORY_CAPTURE, 0,\r
-                                       g_pSrcFilter, &IID_IAMStreamConfig,\r
-                                       (void **)&pSConfig);\r
-    if (FAILED(hr)) {\r
-        ERR("failed to FindInterface method\n");\r
-        return hr;\r
-    }\r
-\r
-    hr = pSConfig->lpVtbl->GetNumberOfCapabilities(pSConfig, &iCount, &iSize);\r
-    if (FAILED(hr)) {\r
-        ERR("failed to GetNumberOfCapabilities method\n");\r
-        SAFE_RELEASE(pSConfig);\r
-        return hr;\r
-    }\r
-\r
-    if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS)) {\r
-        int iFormat = 0;\r
-        for (iFormat = 0; iFormat < iCount; iFormat++) {\r
-            VIDEO_STREAM_CONFIG_CAPS scc;\r
-            AM_MEDIA_TYPE *pmtConfig;\r
-\r
-            hr = pSConfig->lpVtbl->GetStreamCaps(pSConfig, iFormat,\r
-                                                 &pmtConfig, (BYTE *)&scc);\r
-            if (hr == S_OK) {\r
-                if (IsEqualIID(&pmtConfig->formattype, &FORMAT_VideoInfo)) {\r
-                    VIDEOINFOHEADER *pvi =\r
-                                         (VIDEOINFOHEADER *)pmtConfig->pbFormat;\r
-                    if ((pvi->bmiHeader.biWidth == (LONG)dwWidth) &&\r
-                        (pvi->bmiHeader.biHeight == (LONG)dwHeight)) {\r
-                        if (pvi->bmiHeader.biCompression == dwYUY2) {\r
-                            *dwSrcFmt = V4L2_PIX_FMT_YUYV;\r
-                        } else if ((pvi->bmiHeader.biCompression == BI_RGB) &&\r
-                                (pvi->bmiHeader.biBitCount == 24)) {\r
-                            *dwSrcFmt = V4L2_PIX_FMT_RGB24;\r
-                        } else if (pvi->bmiHeader.biCompression == dwI420) {\r
-                            *dwSrcFmt = V4L2_PIX_FMT_YUV420;\r
-                        } else { /* not support format */\r
-                            DeleteMediaType(pmtConfig);\r
-                            continue;\r
-                        }\r
-                        /* use minimum FPS(maximum frameinterval)\r
-                           with non-VT system  */\r
-#ifdef CONFIG_HAX\r
-                        if (!hax_enabled()) {\r
-                            pvi->AvgTimePerFrame =\r
-                                    (REFERENCE_TIME)scc.MaxFrameInterval;\r
-                        } else {\r
-                            pvi->AvgTimePerFrame =\r
-                                (REFERENCE_TIME)MARUCAM_DEFAULT_FRAMEINTERVAL;\r
-                        }\r
-#else\r
-                        pvi->AvgTimePerFrame =\r
-                                (REFERENCE_TIME)scc.MaxFrameInterval;\r
-#endif\r
-                        hr = pSConfig->lpVtbl->SetFormat(pSConfig, pmtConfig);\r
-                        DeleteMediaType(pmtConfig);\r
-                        break;\r
-                    }\r
-                }\r
-                DeleteMediaType(pmtConfig);\r
-            }\r
-        }\r
-        if (iFormat >= iCount) {\r
-            ERR("Failed to Set format. "\r
-                "Maybe connected webcam does not support the (%ldx%ld) "\r
-                "resolution or image formats(YUY2, RGB24, I420).\n",\r
-                dwWidth, dwHeight);\r
-            hr = E_FAIL;\r
-        }\r
-    }\r
-    SAFE_RELEASE(pSConfig);\r
-    return hr;\r
-}\r
-\r
-static STDMETHODIMP QueryVideoProcAmp(long nProperty, long *pMin, long *pMax,\r
-                                      long *pStep, long *pDefault)\r
-{\r
-    HRESULT hr;\r
-    long Flags;\r
-    IAMVideoProcAmp *pProcAmp = NULL;\r
-\r
-    hr = g_pSrcFilter->lpVtbl->QueryInterface(g_pSrcFilter,\r
-                                              &IID_IAMVideoProcAmp,\r
-                                              (void **)&pProcAmp);\r
-    if (FAILED(hr)) {\r
-        return hr;\r
-    }\r
-\r
-    hr = pProcAmp->lpVtbl->GetRange(pProcAmp, nProperty, pMin, pMax,\r
-                                    pStep, pDefault, &Flags);\r
-\r
-    SAFE_RELEASE(pProcAmp);\r
-    return hr;\r
-}\r
-\r
-static STDMETHODIMP GetVideoProcAmp(long nProperty, long *pValue)\r
-{\r
-    HRESULT hr;\r
-    long Flags;\r
-    IAMVideoProcAmp *pProcAmp = NULL;\r
-\r
-    hr = g_pSrcFilter->lpVtbl->QueryInterface(g_pSrcFilter,\r
-                                              &IID_IAMVideoProcAmp,\r
-                                              (void **)&pProcAmp);\r
-    if (FAILED(hr)) {\r
-        return hr;\r
-    }\r
-\r
-    hr = pProcAmp->lpVtbl->Get(pProcAmp, nProperty, pValue, &Flags);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to get property for video\n");\r
-    }\r
-\r
-    SAFE_RELEASE(pProcAmp);\r
-    return hr;\r
-}\r
-\r
-static STDMETHODIMP SetVideoProcAmp(long nProperty, long value)\r
-{\r
-    HRESULT hr;\r
-\r
-    IAMVideoProcAmp *pProcAmp = NULL;\r
-    hr = g_pSrcFilter->lpVtbl->QueryInterface(g_pSrcFilter,\r
-                                              &IID_IAMVideoProcAmp,\r
-                                              (void **)&pProcAmp);\r
-    if (FAILED(hr)) {\r
-        return hr;\r
-    }\r
-\r
-    hr = pProcAmp->lpVtbl->Set(pProcAmp, nProperty, value,\r
-                               VideoProcAmp_Flags_Manual);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to set property for video\n");\r
-    }\r
-    SAFE_RELEASE(pProcAmp);\r
-    return hr;\r
-}\r
-\r
-static char *__wchar_to_char(const WCHAR *pwstr)\r
-{\r
-    char *pstr = NULL;\r
-    int len = 0;\r
-\r
-    len = wcslen(pwstr) + 1;\r
-    pstr = (char *)g_malloc0(sizeof(char) * len);\r
-    wcstombs(pstr, pwstr, len + 1);\r
-\r
-    return pstr;\r
-}\r
-\r
-int marucam_device_check(int log_flag)\r
-{\r
-    struct timeval t1, t2;\r
-    int ret = 0;\r
-    char *device_name = NULL;\r
-    HRESULT hr = E_FAIL;\r
-    ICreateDevEnum *pCreateDevEnum = NULL;\r
-    IGraphBuilder *pGB = NULL;\r
-    ICaptureGraphBuilder2 *pCGB = NULL;\r
-    IBaseFilter *pSrcFilter = NULL;\r
-    IEnumMoniker *pEnumMK = NULL;\r
-    IMoniker *pMoniKer = NULL;\r
-    IAMStreamConfig *pSConfig = NULL;\r
-    int iCount = 0, iSize = 0;\r
-\r
-    gettimeofday(&t1, NULL);\r
-    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);\r
-    if (FAILED(hr)) {\r
-        fprintf(stdout, "[Webcam] failed to CoInitailizeEx\n");\r
-        gettimeofday(&t2, NULL);\r
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",\r
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-        return ret;\r
-    }\r
-\r
-    hr = CoCreateInstance(&CLSID_FilterGraph, NULL,\r
-                          CLSCTX_INPROC,\r
-                          &IID_IGraphBuilder,\r
-                          (void **)&pGB);\r
-    if (FAILED(hr)) {\r
-        fprintf(stdout, "[Webcam] Failed to create GraphBuilder, 0x%x\n", hr);\r
-        CoUninitialize();\r
-        gettimeofday(&t2, NULL);\r
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",\r
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-        return ret;\r
-    }\r
-\r
-    hr = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL,\r
-                          CLSCTX_INPROC,\r
-                          &IID_ICaptureGraphBuilder2,\r
-                          (void **)&pCGB);\r
-    if (FAILED(hr)) {\r
-        fprintf(stdout,\r
-        "[Webcam] Failed to create CaptureGraphBuilder2, 0x%x\n", hr);\r
-        SAFE_RELEASE(pGB);\r
-        CoUninitialize();\r
-        gettimeofday(&t2, NULL);\r
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",\r
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-        return ret;\r
-    }\r
-\r
-    hr = pCGB->lpVtbl->SetFiltergraph(pCGB, pGB);\r
-    if (FAILED(hr)) {\r
-        fprintf(stdout, "[Webcam] Failed to SetFiltergraph, 0x%x\n", hr);\r
-        SAFE_RELEASE(pCGB);\r
-        SAFE_RELEASE(pGB);\r
-        CoUninitialize();\r
-        gettimeofday(&t2, NULL);\r
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",\r
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-        return ret;\r
-    }\r
-\r
-    hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL,\r
-                          CLSCTX_INPROC,\r
-                          &IID_ICreateDevEnum,\r
-                          (void **)&pCreateDevEnum);\r
-    if (FAILED(hr)) {\r
-        fprintf(stdout,\r
-            "[Webcam] failed to create instance of CLSID_SystemDeviceEnum\n");\r
-        SAFE_RELEASE(pCGB);\r
-        SAFE_RELEASE(pGB);\r
-        CoUninitialize();\r
-        gettimeofday(&t2, NULL);\r
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",\r
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-        return ret;\r
-    }\r
-\r
-    hr = pCreateDevEnum->lpVtbl->CreateClassEnumerator(pCreateDevEnum,\r
-                                  &CLSID_VideoInputDeviceCategory, &pEnumMK, 0);\r
-    if (FAILED(hr)) {\r
-        fprintf(stdout, "[Webcam] failed to create class enumerator\n");\r
-        SAFE_RELEASE(pCreateDevEnum);\r
-        SAFE_RELEASE(pCGB);\r
-        SAFE_RELEASE(pGB);\r
-        CoUninitialize();\r
-        gettimeofday(&t2, NULL);\r
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",\r
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-        return ret;\r
-    }\r
-\r
-    if (!pEnumMK) {\r
-        fprintf(stdout, "[Webcam] class enumerator is NULL!!\n");\r
-        SAFE_RELEASE(pCreateDevEnum);\r
-        SAFE_RELEASE(pCGB);\r
-        SAFE_RELEASE(pGB);\r
-        CoUninitialize();\r
-        gettimeofday(&t2, NULL);\r
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",\r
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-        return ret;\r
-    }\r
-    pEnumMK->lpVtbl->Reset(pEnumMK);\r
-\r
-    hr = pEnumMK->lpVtbl->Next(pEnumMK, 1, &pMoniKer, NULL);\r
-    if (FAILED(hr) || (hr == S_FALSE)) {\r
-        fprintf(stdout, "[Webcam] enum moniker returns a invalid value.\n");\r
-        SAFE_RELEASE(pEnumMK);\r
-        SAFE_RELEASE(pCreateDevEnum);\r
-        SAFE_RELEASE(pCGB);\r
-        SAFE_RELEASE(pGB);\r
-        CoUninitialize();\r
-        gettimeofday(&t2, NULL);\r
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",\r
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-        return ret;\r
-    }\r
-\r
-    IPropertyBag *pBag = NULL;\r
-    hr = pMoniKer->lpVtbl->BindToStorage(pMoniKer, 0, 0,\r
-                                         &IID_IPropertyBag,\r
-                                         (void **)&pBag);\r
-    if (FAILED(hr)) {\r
-        fprintf(stdout, "[Webcam] failed to bind to storage.\n");\r
-        SAFE_RELEASE(pEnumMK);\r
-        SAFE_RELEASE(pCreateDevEnum);\r
-        SAFE_RELEASE(pCGB);\r
-        SAFE_RELEASE(pGB);\r
-        CoUninitialize();\r
-        gettimeofday(&t2, NULL);\r
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",\r
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-        return ret;\r
-    } else {\r
-        VARIANT var;\r
-        var.vt = VT_BSTR;\r
-        hr = pBag->lpVtbl->Read(pBag, L"FriendlyName", &var, NULL);\r
-        if (hr == S_OK) {\r
-            ret = 1;\r
-            if (!log_flag) {\r
-                SysFreeString(var.bstrVal);\r
-                SAFE_RELEASE(pBag);\r
-                SAFE_RELEASE(pMoniKer);\r
-                SAFE_RELEASE(pEnumMK);\r
-                SAFE_RELEASE(pCreateDevEnum);\r
-                SAFE_RELEASE(pCGB);\r
-                SAFE_RELEASE(pGB);\r
-                CoUninitialize();\r
-                gettimeofday(&t2, NULL);\r
-                fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",\r
-                                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-                return ret;\r
-            }\r
-            device_name = __wchar_to_char(var.bstrVal);\r
-            fprintf(stdout, "[Webcam] Device name : %s\n", device_name);\r
-            g_free(device_name);\r
-            hr = pMoniKer->lpVtbl->BindToObject(pMoniKer, NULL, NULL,\r
-                                                &IID_IBaseFilter,\r
-                                                (void **)&pSrcFilter);\r
-            if (FAILED(hr)) {\r
-                fprintf(stdout,\r
-                   "[Webcam] Counldn't bind moniker to filter object!!\n");\r
-                SysFreeString(var.bstrVal);\r
-                SAFE_RELEASE(pBag);\r
-                SAFE_RELEASE(pMoniKer);\r
-                SAFE_RELEASE(pEnumMK);\r
-                SAFE_RELEASE(pCreateDevEnum);\r
-                SAFE_RELEASE(pCGB);\r
-                SAFE_RELEASE(pGB);\r
-                CoUninitialize();\r
-                gettimeofday(&t2, NULL);\r
-                fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",\r
-                                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-                return ret;\r
-            } else {\r
-                pSrcFilter->lpVtbl->AddRef(pSrcFilter);\r
-            }\r
-            SysFreeString(var.bstrVal);\r
-        }\r
-        SAFE_RELEASE(pBag);\r
-    }\r
-    SAFE_RELEASE(pMoniKer);\r
-\r
-    hr = pGB->lpVtbl->AddFilter(pGB, pSrcFilter, L"Video Capture");\r
-    if (hr != S_OK && hr != S_FALSE) {\r
-        fprintf(stdout,\r
-                "[Webcam] Counldn't add Video Capture filter to our graph!\n");\r
-        SAFE_RELEASE(pSrcFilter);\r
-        SAFE_RELEASE(pEnumMK);\r
-        SAFE_RELEASE(pCreateDevEnum);\r
-        SAFE_RELEASE(pCGB);\r
-        SAFE_RELEASE(pGB);\r
-        CoUninitialize();\r
-        gettimeofday(&t2, NULL);\r
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",\r
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-        return ret;\r
-    }\r
-\r
-    hr = pCGB->lpVtbl->FindInterface(pCGB, &PIN_CATEGORY_CAPTURE, 0,\r
-                                       pSrcFilter, &IID_IAMStreamConfig,\r
-                                       (void **)&pSConfig);\r
-    if (FAILED(hr)) {\r
-        fprintf(stdout, "[Webcam] failed to FindInterface method\n");\r
-        SAFE_RELEASE(pSrcFilter);\r
-        SAFE_RELEASE(pEnumMK);\r
-        SAFE_RELEASE(pCreateDevEnum);\r
-        SAFE_RELEASE(pCGB);\r
-        SAFE_RELEASE(pGB);\r
-        CoUninitialize();\r
-        gettimeofday(&t2, NULL);\r
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",\r
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-        return ret;\r
-    }\r
-\r
-    hr = pSConfig->lpVtbl->GetNumberOfCapabilities(pSConfig, &iCount, &iSize);\r
-    if (FAILED(hr)) {\r
-        fprintf(stdout, "[Webcam] failed to GetNumberOfCapabilities method\n");\r
-        SAFE_RELEASE(pSConfig);\r
-        SAFE_RELEASE(pSrcFilter);\r
-        SAFE_RELEASE(pEnumMK);\r
-        SAFE_RELEASE(pCreateDevEnum);\r
-        SAFE_RELEASE(pCGB);\r
-        SAFE_RELEASE(pGB);\r
-        CoUninitialize();\r
-        gettimeofday(&t2, NULL);\r
-        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",\r
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-        return ret;\r
-    }\r
-\r
-    if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS)) {\r
-        int iFormat = 0;\r
-        for (iFormat = 0; iFormat < iCount; iFormat++) {\r
-            VIDEO_STREAM_CONFIG_CAPS scc;\r
-            AM_MEDIA_TYPE *pmtConfig;\r
-\r
-            hr = pSConfig->lpVtbl->GetStreamCaps(pSConfig, iFormat, &pmtConfig,\r
-                                                 (BYTE *)&scc);\r
-            if (hr == S_OK) {\r
-                if (IsEqualIID(&pmtConfig->formattype, &FORMAT_VideoInfo)) {\r
-                    VIDEOINFOHEADER *pvi =\r
-                                         (VIDEOINFOHEADER *)pmtConfig->pbFormat;\r
-                    if (pvi->bmiHeader.biCompression == BI_RGB) {\r
-                        fprintf(stdout, "[Webcam] RGB BitCount: %d, %ux%u\n",\r
-                                pvi->bmiHeader.biBitCount,\r
-                                pvi->bmiHeader.biWidth,\r
-                                pvi->bmiHeader.biHeight);\r
-                    } else {\r
-                        fprintf(stdout,\r
-                                "[Webcam] PixelFormat: %c%c%c%c, %ux%u\n",\r
-                                (char)(pvi->bmiHeader.biCompression),\r
-                                (char)(pvi->bmiHeader.biCompression >> 8),\r
-                                (char)(pvi->bmiHeader.biCompression >> 16),\r
-                                (char)(pvi->bmiHeader.biCompression >> 24),\r
-                                pvi->bmiHeader.biWidth,\r
-                                pvi->bmiHeader.biHeight);\r
-                    }\r
-                }\r
-                DeleteMediaType(pmtConfig);\r
-            }\r
-        }\r
-    }\r
-\r
-    hr = pGB->lpVtbl->RemoveFilter(pGB, pSrcFilter);\r
-    if (FAILED(hr)) {\r
-        fprintf(stdout, "[Webcam] Failed to remove source filer. 0x%x\n", hr);\r
-    }\r
-\r
-    SAFE_RELEASE(pSConfig);\r
-    SAFE_RELEASE(pSrcFilter);\r
-    SAFE_RELEASE(pCGB);\r
-    SAFE_RELEASE(pGB);\r
-    SAFE_RELEASE(pEnumMK);\r
-    SAFE_RELEASE(pCreateDevEnum);\r
-    CoUninitialize();\r
-    gettimeofday(&t2, NULL);\r
-    fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",\r
-                    t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);\r
-\r
-    return ret;\r
-}\r
-\r
-/* MARUCAM_CMD_INIT */\r
-void marucam_device_init(MaruCamState *state)\r
-{\r
-    g_state = state;\r
-}\r
-\r
-void marucam_device_exit(MaruCamState *state)\r
-{\r
-}\r
-\r
-/* MARUCAM_CMD_OPEN */\r
-void marucam_device_open(MaruCamState *state)\r
-{\r
-    HRESULT hr;\r
-    uint32_t dwHeight, dwWidth, dwDstFmt;\r
-    MaruCamParam *param = state->param;\r
-    param->top = 0;\r
-\r
-    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);\r
-    if (FAILED(hr)) {\r
-        ERR("CoInitailizeEx\n");\r
-        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-\r
-    hr = GraphBuilder_Init();\r
-    if (FAILED(hr)) {\r
-        ERR("GraphBuilder_Init\n");\r
-        DisconnectPins();\r
-        RemoveFilters();\r
-        CloseInterfaces();\r
-        CoUninitialize();\r
-        param->errCode = EINVAL;\r
-        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);\r
-        return;\r
-    }\r
-\r
-    hr = BindSourceFilter();\r
-    if (FAILED(hr)) {\r
-        ERR("BindSourceFilter\n");\r
-        DisconnectPins();\r
-        RemoveFilters();\r
-        CloseInterfaces();\r
-        CoUninitialize();\r
-        param->errCode = EINVAL;\r
-        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);\r
-        return;\r
-    }\r
-\r
-    hr = BindTargetFilter();\r
-    if (FAILED(hr)) {\r
-        ERR("BindTargetFilter\n");\r
-        DisconnectPins();\r
-        RemoveFilters();\r
-        CloseInterfaces();\r
-        CoUninitialize();\r
-        param->errCode = EINVAL;\r
-        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);\r
-        return;\r
-    }\r
-\r
-    hr = ConnectFilters();\r
-    if (FAILED(hr)) {\r
-        ERR("ConnectFilters\n");\r
-        DisconnectPins();\r
-        RemoveFilters();\r
-        CloseInterfaces();\r
-        CoUninitialize();\r
-        param->errCode = EINVAL;\r
-        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);\r
-        return;\r
-    }\r
-\r
-    cur_frame_idx = 0;\r
-    cur_fmt_idx = 0;\r
-\r
-    dwHeight = supported_dst_frames[cur_frame_idx].height;\r
-    dwWidth = supported_dst_frames[cur_frame_idx].width;\r
-    dwDstFmt = supported_dst_pixfmts[cur_fmt_idx].fmt;\r
-    hr = SetFormat(dwWidth, dwHeight, dwDstFmt, &g_dwSrcFmt);\r
-    if (hr != S_OK) {\r
-        ERR("failed to Set default values\n");\r
-        DisconnectPins();\r
-        RemoveFilters();\r
-        CloseInterfaces();\r
-        CoUninitialize();\r
-        param->errCode = EINVAL;\r
-        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);\r
-        return;\r
-    }\r
-\r
-    INFO("Opened\n");\r
-    return;\r
-}\r
-\r
-/* MARUCAM_CMD_CLOSE */\r
-void marucam_device_close(MaruCamState *state)\r
-{\r
-    MaruCamParam *param = state->param;\r
-    param->top = 0;\r
-\r
-    DisconnectPins();\r
-    RemoveFilters();\r
-    CloseInterfaces();\r
-    CoUninitialize();\r
-    INFO("Closed\n");\r
-}\r
-\r
-/* MARUCAM_CMD_START_PREVIEW */\r
-void marucam_device_start_preview(MaruCamState *state)\r
-{\r
-    HRESULT hr;\r
-    uint32_t pixfmt, width, height;\r
-    MaruCamParam *param = state->param;\r
-    param->top = 0;\r
-\r
-    ready_count = 0;\r
-    width = supported_dst_frames[cur_frame_idx].width;\r
-    height = supported_dst_frames[cur_frame_idx].height;\r
-    pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;\r
-    state->buf_size = get_sizeimage(pixfmt, width, height);\r
-\r
-    INFO("Pixfmt(%c%c%c%c), W:H(%d:%d), buf size(%u)\n",\r
-         (char)(pixfmt), (char)(pixfmt >> 8),\r
-         (char)(pixfmt >> 16), (char)(pixfmt >> 24),\r
-         width, height, state->buf_size);\r
-    INFO("Starting preview\n");\r
-\r
-    assert(g_pCallback != NULL);\r
-    hr = ((HWCInPin *)g_pInputPin)->SetGrabCallbackIF(g_pInputPin,\r
-                                                       g_pCallback);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to set IGrabCallback interface.\n");\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-\r
-    if (grab_buf) {\r
-        g_free(grab_buf);\r
-        grab_buf = NULL;\r
-    }\r
-    grab_buf = (void *)g_malloc0(state->buf_size);\r
-    if (grab_buf == NULL) {\r
-        param->errCode = ENOMEM;\r
-        return;\r
-    }\r
-\r
-    hr = g_pMediaControl->lpVtbl->Run(g_pMediaControl);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to run media control. hr=0x%x\n", hr);\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-\r
-    qemu_mutex_lock(&state->thread_mutex);\r
-    state->streamon = 1;\r
-    qemu_mutex_unlock(&state->thread_mutex);\r
-\r
-    INFO("Streaming on ......\n");\r
-}\r
-\r
-/* MARUCAM_CMD_STOP_PREVIEW */\r
-void marucam_device_stop_preview(MaruCamState *state)\r
-{\r
-    HRESULT hr;\r
-    MaruCamParam *param = state->param;\r
-    param->top = 0;\r
-\r
-    INFO("...... Streaming off\n");\r
-    qemu_mutex_lock(&state->thread_mutex);\r
-    state->streamon = 0;\r
-    qemu_mutex_unlock(&state->thread_mutex);\r
-\r
-    hr = ((HWCInPin *)g_pInputPin)->SetGrabCallbackIF(g_pInputPin, NULL);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to set IGrabCallback interface.\n");\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-\r
-    hr = g_pMediaControl->lpVtbl->Stop(g_pMediaControl);\r
-    if (FAILED(hr)) {\r
-        ERR("Failed to stop media control.\n");\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-\r
-    if (grab_buf) {\r
-        g_free(grab_buf);\r
-        grab_buf = NULL;\r
-    }\r
-    state->buf_size = 0;\r
-\r
-    INFO("Stopping preview\n");\r
-}\r
-\r
-/* MARUCAM_CMD_S_PARAM */\r
-void marucam_device_s_param(MaruCamState *state)\r
-{\r
-    MaruCamParam *param = state->param;\r
-\r
-    /* We use default FPS of the webcam */\r
-    param->top = 0;\r
-}\r
-\r
-/* MARUCAM_CMD_G_PARAM */\r
-void marucam_device_g_param(MaruCamState *state)\r
-{\r
-    MaruCamParam *param = state->param;\r
-\r
-    /* We use default FPS of the webcam\r
-     * return a fixed value on guest ini file (1/30).\r
-     */\r
-    param->top = 0;\r
-    param->stack[0] = 0x1000; /* V4L2_CAP_TIMEPERFRAME */\r
-    param->stack[1] = 1; /* numerator */\r
-    param->stack[2] = 30; /* denominator */\r
-}\r
-\r
-/* MARUCAM_CMD_S_FMT */\r
-void marucam_device_s_fmt(MaruCamState *state)\r
-{\r
-    uint32_t width, height, pixfmt, pidx, fidx;\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-    width = param->stack[0];\r
-    height = param->stack[1];\r
-    pixfmt = param->stack[2];\r
-\r
-    for (fidx = 0; fidx < ARRAY_SIZE(supported_dst_frames); fidx++) {\r
-        if ((supported_dst_frames[fidx].width == width) &&\r
-                (supported_dst_frames[fidx].height == height)) {\r
-            break;\r
-        }\r
-    }\r
-    if (fidx == ARRAY_SIZE(supported_dst_frames)) {\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-    for (pidx = 0; pidx < ARRAY_SIZE(supported_dst_pixfmts); pidx++) {\r
-        if (supported_dst_pixfmts[pidx].fmt == pixfmt) {\r
-            break;\r
-        }\r
-    }\r
-    if (pidx == ARRAY_SIZE(supported_dst_pixfmts)) {\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-\r
-    if ((supported_dst_frames[cur_frame_idx].width != width) &&\r
-            (supported_dst_frames[cur_frame_idx].height != height)) {\r
-        HRESULT hr = SetFormat(width, height, pixfmt, &g_dwSrcFmt);\r
-        if (FAILED(hr)) {\r
-            param->errCode = EINVAL;\r
-            return;\r
-        }\r
-    }\r
-\r
-    cur_frame_idx = fidx;\r
-    cur_fmt_idx = pidx;\r
-\r
-    pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;\r
-    width = supported_dst_frames[cur_frame_idx].width;\r
-    height = supported_dst_frames[cur_frame_idx].height;\r
-\r
-    param->stack[0] = width;\r
-    param->stack[1] = height;\r
-    param->stack[2] = 1; /* V4L2_FIELD_NONE */\r
-    param->stack[3] = pixfmt;\r
-    param->stack[4] = get_bytesperline(pixfmt, width);\r
-    param->stack[5] = get_sizeimage(pixfmt, width, height);\r
-    param->stack[6] = 0;\r
-    param->stack[7] = 0;\r
-\r
-    TRACE("Set format...\n");\r
-}\r
-\r
-/* MARUCAM_CMD_G_FMT */\r
-void marucam_device_g_fmt(MaruCamState *state)\r
-{\r
-    uint32_t width, height, pixfmt;\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-    pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;\r
-    width = supported_dst_frames[cur_frame_idx].width;\r
-    height = supported_dst_frames[cur_frame_idx].height;\r
-\r
-    param->stack[0] = width;\r
-    param->stack[1] = height;\r
-    param->stack[2] = 1; /* V4L2_FIELD_NONE */\r
-    param->stack[3] = pixfmt;\r
-    param->stack[4] = get_bytesperline(pixfmt, width);\r
-    param->stack[5] = get_sizeimage(pixfmt, width, height);\r
-    param->stack[6] = 0;\r
-    param->stack[7] = 0;\r
-\r
-    TRACE("Get format...\n");\r
-}\r
-\r
-void marucam_device_try_fmt(MaruCamState *state)\r
-{\r
-    uint32_t width, height, pixfmt, i;\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-    width = param->stack[0];\r
-    height = param->stack[1];\r
-    pixfmt = param->stack[2];\r
-\r
-    for (i = 0; i < ARRAY_SIZE(supported_dst_frames); i++) {\r
-        if ((supported_dst_frames[i].width == width) &&\r
-                (supported_dst_frames[i].height == height)) {\r
-            break;\r
-        }\r
-    }\r
-    if (i == ARRAY_SIZE(supported_dst_frames)) {\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-    for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) {\r
-        if (supported_dst_pixfmts[i].fmt == pixfmt) {\r
-            break;\r
-        }\r
-    }\r
-    if (i == ARRAY_SIZE(supported_dst_pixfmts)) {\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-\r
-    param->stack[0] = width;\r
-    param->stack[1] = height;\r
-    param->stack[2] = 1; /* V4L2_FIELD_NONE */\r
-    param->stack[3] = pixfmt;\r
-    param->stack[4] = get_bytesperline(pixfmt, width);\r
-    param->stack[5] = get_sizeimage(pixfmt, width, height);\r
-    param->stack[6] = 0;\r
-    param->stack[7] = 0;\r
-}\r
-\r
-void marucam_device_enum_fmt(MaruCamState *state)\r
-{\r
-    uint32_t index;\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-    index = param->stack[0];\r
-\r
-    if (index >= ARRAY_SIZE(supported_dst_pixfmts)) {\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-    param->stack[1] = 0; /* flags = NONE */\r
-    param->stack[2] = supported_dst_pixfmts[index].fmt; /* pixelformat */\r
-    /* set description */\r
-    switch (supported_dst_pixfmts[index].fmt) {\r
-    case V4L2_PIX_FMT_YUYV:\r
-        memcpy(&param->stack[3], "YUYV", 32);\r
-        break;\r
-    case V4L2_PIX_FMT_YUV420:\r
-        memcpy(&param->stack[3], "YU12", 32);\r
-        break;\r
-    case V4L2_PIX_FMT_YVU420:\r
-        memcpy(&param->stack[3], "YV12", 32);\r
-        break;\r
-    default:\r
-        ERR("Invalid pixel format\n");\r
-        param->errCode = EINVAL;\r
-        break;\r
-    }\r
-}\r
-\r
-void marucam_device_qctrl(MaruCamState *state)\r
-{\r
-    HRESULT hr;\r
-    uint32_t id, i;\r
-    long property, min, max, step, def_val, set_val;\r
-    char name[32] = {0,};\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-    id = param->stack[0];\r
-\r
-    switch (id) {\r
-    case V4L2_CID_BRIGHTNESS:\r
-        TRACE("V4L2_CID_BRIGHTNESS\n");\r
-        property = VideoProcAmp_Brightness;\r
-        memcpy((void *)name, (void *)"brightness", 32);\r
-        i = 0;\r
-        break;\r
-    case V4L2_CID_CONTRAST:\r
-        TRACE("V4L2_CID_CONTRAST\n");\r
-        property = VideoProcAmp_Contrast;\r
-        memcpy((void *)name, (void *)"contrast", 32);\r
-        i = 1;\r
-        break;\r
-    case V4L2_CID_SATURATION:\r
-        TRACE("V4L2_CID_SATURATION\n");\r
-        property = VideoProcAmp_Saturation;\r
-        memcpy((void *)name, (void *)"saturation", 32);\r
-        i = 2;\r
-        break;\r
-    case V4L2_CID_SHARPNESS:\r
-        TRACE("V4L2_CID_SHARPNESS\n");\r
-        property = VideoProcAmp_Sharpness;\r
-        memcpy((void *)name, (void *)"sharpness", 32);\r
-        i = 3;\r
-        break;\r
-    default:\r
-        ERR("Invalid control ID\n");\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-    hr = QueryVideoProcAmp(property, &min, &max, &step, &def_val);\r
-    if (FAILED(hr)) {\r
-        param->errCode = EINVAL;\r
-        ERR("failed to query video controls [HRESULT : 0x%x]\n", hr);\r
-        return;\r
-    } else {\r
-        qctrl_tbl[i].hit = 1;\r
-        qctrl_tbl[i].min = min;\r
-        qctrl_tbl[i].max = max;\r
-        qctrl_tbl[i].step = step;\r
-        qctrl_tbl[i].init_val = def_val;\r
-\r
-        if ((qctrl_tbl[i].min + qctrl_tbl[i].max) == 0) {\r
-            set_val = 0;\r
-        } else {\r
-            set_val = (qctrl_tbl[i].min + qctrl_tbl[i].max) / 2;\r
-        }\r
-        hr = SetVideoProcAmp(property, set_val);\r
-        if (FAILED(hr)) {\r
-            param->errCode = EINVAL;\r
-            ERR("failed to set video control value, [HRESULT : 0x%x]\n", hr);\r
-            return;\r
-        }\r
-    }\r
-\r
-    param->stack[0] = id;\r
-    param->stack[1] = MARUCAM_CTRL_VALUE_MIN;  /* minimum */\r
-    param->stack[2] = MARUCAM_CTRL_VALUE_MAX;  /* maximum */\r
-    param->stack[3] = MARUCAM_CTRL_VALUE_STEP; /*  step   */\r
-    param->stack[4] = MARUCAM_CTRL_VALUE_MID;  /* default_value */\r
-    param->stack[5] = V4L2_CTRL_FLAG_SLIDER;\r
-    /* name field setting */\r
-    memcpy(&param->stack[6], (void *)name, sizeof(name)/sizeof(name[0]));\r
-}\r
-\r
-void marucam_device_s_ctrl(MaruCamState *state)\r
-{\r
-    HRESULT hr;\r
-    uint32_t i;\r
-    long property, set_val;\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-\r
-    switch (param->stack[0]) {\r
-    case V4L2_CID_BRIGHTNESS:\r
-        i = 0;\r
-        property = VideoProcAmp_Brightness;\r
-        break;\r
-    case V4L2_CID_CONTRAST:\r
-        i = 1;\r
-        property = VideoProcAmp_Contrast;\r
-        break;\r
-    case V4L2_CID_SATURATION:\r
-        i = 2;\r
-        property = VideoProcAmp_Saturation;\r
-        break;\r
-    case V4L2_CID_SHARPNESS:\r
-        i = 3;\r
-        property = VideoProcAmp_Sharpness;\r
-        break;\r
-    default:\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-    set_val = value_convert_from_guest(qctrl_tbl[i].min,\r
-            qctrl_tbl[i].max, (long)param->stack[1]);\r
-    hr = SetVideoProcAmp(property, set_val);\r
-    if (FAILED(hr)) {\r
-        param->errCode = EINVAL;\r
-        ERR("failed to set video control value, [HRESULT : 0x%x]\n", hr);\r
-        return;\r
-    }\r
-}\r
-\r
-void marucam_device_g_ctrl(MaruCamState *state)\r
-{\r
-    HRESULT hr;\r
-    uint32_t i;\r
-    long property, get_val;\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-    switch (param->stack[0]) {\r
-    case V4L2_CID_BRIGHTNESS:\r
-        i = 0;\r
-        property = VideoProcAmp_Brightness;\r
-        break;\r
-    case V4L2_CID_CONTRAST:\r
-        i = 1;\r
-        property = VideoProcAmp_Contrast;\r
-        break;\r
-    case V4L2_CID_SATURATION:\r
-        i = 2;\r
-        property = VideoProcAmp_Saturation;\r
-        break;\r
-    case V4L2_CID_SHARPNESS:\r
-        i = 3;\r
-        property = VideoProcAmp_Sharpness;\r
-        break;\r
-    default:\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-\r
-    hr = GetVideoProcAmp(property, &get_val);\r
-    if (FAILED(hr)) {\r
-        param->errCode = EINVAL;\r
-        ERR("failed to get video control value!!!, [HRESULT : 0x%x]\n", hr);\r
-        return;\r
-    }\r
-    param->stack[0] = (uint32_t)value_convert_to_guest(qctrl_tbl[i].min,\r
-                qctrl_tbl[i].max, get_val);\r
-}\r
-\r
-void marucam_device_enum_fsizes(MaruCamState *state)\r
-{\r
-    uint32_t index, pixfmt, i;\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-    index = param->stack[0];\r
-    pixfmt = param->stack[1];\r
-\r
-    if (index >= ARRAY_SIZE(supported_dst_frames)) {\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-    for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) {\r
-        if (supported_dst_pixfmts[i].fmt == pixfmt) {\r
-            break;\r
-        }\r
-    }\r
-\r
-    if (i == ARRAY_SIZE(supported_dst_pixfmts)) {\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-\r
-    param->stack[0] = supported_dst_frames[index].width;\r
-    param->stack[1] = supported_dst_frames[index].height;\r
-}\r
-\r
-void marucam_device_enum_fintv(MaruCamState *state)\r
-{\r
-    MaruCamParam *param = state->param;\r
-\r
-    param->top = 0;\r
-\r
-    /* switch by index(param->stack[0]) */\r
-    switch (param->stack[0]) {\r
-    case 0:\r
-        param->stack[1] = 30; /* denominator */\r
-        break;\r
-    default:\r
-        param->errCode = EINVAL;\r
-        return;\r
-    }\r
-    param->stack[0] = 1; /* numerator */\r
-}\r
-\r
-void yuyv_to_yuv420(const unsigned char *src, unsigned char *dest,\r
-        uint32_t width, uint32_t height, uint32_t yvu)\r
-{\r
-    uint32_t i, j;\r
-    const unsigned char *src1;\r
-    unsigned char *udest, *vdest;\r
-\r
-    /* copy the Y values */\r
-    src1 = src;\r
-    for (i = 0; i < height; i++) {\r
-        for (j = 0; j < width; j += 2) {\r
-            *dest++ = src1[0];\r
-            *dest++ = src1[2];\r
-            src1 += 4;\r
-        }\r
-    }\r
-\r
-    /* copy the U and V values */\r
-    src++;              /* point to V */\r
-    src1 = src + width * 2;     /* next line */\r
-    if (yvu) {\r
-        vdest = dest;\r
-        udest = dest + width * height / 4;\r
-    } else {\r
-        udest = dest;\r
-        vdest = dest + width * height / 4;\r
-    }\r
-    for (i = 0; i < height; i += 2) {\r
-        for (j = 0; j < width; j += 2) {\r
-            *udest++ = ((int) src[0] + src1[0]) / 2;    /* U */\r
-            *vdest++ = ((int) src[2] + src1[2]) / 2;    /* V */\r
-            src += 4;\r
-            src1 += 4;\r
-        }\r
-        src = src1;\r
-        src1 += width * 2;\r
-    }\r
-}\r
-\r
-#define RGB2Y(r, g, b, y)   \\r
-    (y) = ((8453 * (r) + 16594 * (g) + 3223 * (b) + 524288) >> 15)\r
-\r
-#define RGB2UV(r, g, b, u, v)   \\r
-    do {    \\r
-        (u) = ((-4878 * (r) - 9578 * (g) + 14456 * (b) + 4210688) >> 15);   \\r
-        (v) = ((14456 * (r) - 12105 * (g) - 2351 * (b) + 4210688) >> 15);   \\r
-    } while (0)\r
-\r
-#define CLIP(color) \\r
-    (unsigned char)(((color) > 0xFF) ? 0xff : (((color) < 0) ? 0 : (color)))\r
-\r
-void rgb24_to_yuv420(const unsigned char *src, unsigned char *dest,\r
-                     uint32_t width, uint32_t height, uint32_t yvu)\r
-{\r
-    uint32_t x, y;\r
-    unsigned char *udest, *vdest;\r
-    uint32_t bytesperline = width * 3;\r
-\r
-    /* Y */\r
-    for (y = 0; y < height; y++) {\r
-        for (x = 0; x < width; x++) {\r
-            RGB2Y(src[2], src[1], src[0], *dest++);\r
-            src += 3;\r
-        }\r
-        src += bytesperline - 3 * width;\r
-    }\r
-    src -= height * bytesperline;\r
-\r
-    /* U + V */\r
-    if (yvu) {\r
-        vdest = dest;\r
-        udest = dest + width * height / 4;\r
-    } else {\r
-        udest = dest;\r
-        vdest = dest + width * height / 4;\r
-    }\r
-\r
-    for (y = 0; y < height / 2; y++) {\r
-        for (x = 0; x < width / 2; x++) {\r
-            uint32_t avg_src[3];\r
-\r
-            avg_src[0] = (src[0] + src[3] + src[bytesperline] +\r
-                    src[bytesperline + 3]) / 4;\r
-            avg_src[1] = (src[1] + src[4] + src[bytesperline + 1] +\r
-                    src[bytesperline + 4]) / 4;\r
-            avg_src[2] = (src[2] + src[5] + src[bytesperline + 2] +\r
-                    src[bytesperline + 5]) / 4;\r
-            RGB2UV(avg_src[2], avg_src[1], avg_src[0], *udest++, *vdest++);\r
-            src += 6;\r
-        }\r
-        src += 2 * bytesperline - 3 * width;\r
-    }\r
-}\r
-\r
-void rgb24_to_yuyv(unsigned char *src, unsigned char *dest,\r
-                   uint32_t width, uint32_t height)\r
-{\r
-    uint32_t i = 0;\r
-\r
-    for (i = 0; i < (width * height * 3); i = i + 6) {\r
-        /* y */\r
-        *dest++ = CLIP(0.299 * (src[i + 2] - 128) +\r
-                    0.587 * (src[i + 1] - 128) +\r
-                    0.114 * (src[i] - 128) + 128);\r
-        /* u */\r
-        *dest++ = CLIP(((-0.147 * (src[i + 2] - 128) -\r
-                    0.289 * (src[i + 1] - 128) +\r
-                    0.436 * (src[i] - 128) + 128) +\r
-                    (-0.147 * (src[i + 5] - 128) -\r
-                    0.289 * (src[i + 4] - 128) +\r
-                    0.436 * (src[i + 3] - 128) + 128)) / 2);\r
-        /* y1 */\r
-        *dest++ = CLIP(0.299 * (src[i + 5] - 128) +\r
-                    0.587 * (src[i + 4] - 128) +\r
-                    0.114 * (src[i + 3] - 128) + 128);\r
-        /* v */\r
-        *dest++ = CLIP(((0.615 * (src[i + 2] - 128) -\r
-                    0.515 * (src[i + 1] - 128) -\r
-                    0.100 * (src[i] - 128) + 128) +\r
-                    (0.615 * (src[i + 5] - 128) -\r
-                    0.515 * (src[i + 4] - 128) -\r
-                    0.100 * (src[i + 3] - 128) + 128)) / 2);\r
-    }\r
-}\r
-\r
-void yuv420_to_yvu420(unsigned char *src, unsigned char *dest,\r
-                      uint32_t width, uint32_t height)\r
-{\r
-    unsigned char *psrc_y, *pdst_y;\r
-    unsigned char *psrc_u, *pdst_u;\r
-    unsigned char *psrc_v, *pdst_v;\r
-\r
-    psrc_y = src;\r
-    psrc_u = psrc_y + (width * height);\r
-    psrc_v = psrc_u + (width * height / 4);\r
-\r
-    pdst_y = dest;\r
-    pdst_v = pdst_y + (width * height);\r
-    pdst_u = pdst_v + (width * height / 4);\r
-\r
-    memcpy(pdst_y, psrc_y, width * height);\r
-    memcpy(pdst_v, psrc_v, width * height / 4);\r
-    memcpy(pdst_u, psrc_u, width * height / 4);\r
-}\r
-\r
-void yuv420_to_yuyv(unsigned char *src, unsigned char *dest,\r
-                    uint32_t width, uint32_t height)\r
-{\r
-    unsigned char *py;\r
-    unsigned char *pu;\r
-    unsigned char *pv;\r
-\r
-    uint32_t linesize = width * 2;\r
-    uint32_t uvlinesize = width / 2;\r
-    uint32_t offset = 0;\r
-    uint32_t offset1 = 0;\r
-    uint32_t offsety = 0;\r
-    uint32_t offsety1 = 0;\r
-    uint32_t offsetuv = 0;\r
-    uint32_t h = 0;\r
-    uint32_t w = 0;\r
-    uint32_t wy = 0;\r
-    uint32_t huv = 0;\r
-    uint32_t wuv = 0;\r
-\r
-    py = src;\r
-    pu = py + (width * height);\r
-    pv = pu + (width * height / 4);\r
-\r
-    for (h = 0; h < height; h += 2) {\r
-        wy = 0;\r
-        wuv = 0;\r
-        offset = h * linesize;\r
-        offset1 = (h + 1) * linesize;\r
-        offsety = h * width;\r
-        offsety1 = (h + 1) * width;\r
-        offsetuv = huv * uvlinesize;\r
-\r
-        for (w = 0; w < linesize; w += 4) {\r
-            /* y00 */\r
-            dest[w + offset] = py[wy + offsety];\r
-            /* u0 */\r
-            dest[(w + 1) + offset] = pu[wuv + offsetuv];\r
-            /* y01 */\r
-            dest[(w + 2) + offset] = py[(wy + 1) + offsety];\r
-            /* v0 */\r
-            dest[(w + 3) + offset] = pv[wuv + offsetuv];\r
-\r
-            /* y10 */\r
-            dest[w + offset1] = py[wy + offsety1];\r
-            /* u0 */\r
-            dest[(w + 1) + offset1] = pu[wuv + offsetuv];\r
-            /* y11 */\r
-            dest[(w + 2) + offset1] = py[(wy + 1) + offsety1];\r
-            /* v0 */\r
-            dest[(w + 3) + offset1] = pv[wuv + offsetuv];\r
-\r
-            wuv++;\r
-            wy += 2;\r
-        }\r
-        huv++;\r
-    }\r
-}\r
+/*
+ * Implementation of MARU Virtual Camera device by PCI bus on Windows.
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * 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 "qemu-common.h"
+#include "maru_camera_common.h"
+#include "tizen/src/debug_ch.h"
+
+#define CINTERFACE
+#define COBJMACROS
+#include "ocidl.h"
+#include "errors.h"      /* for VFW_E_XXXX */
+#include "mmsystem.h"    /* for MAKEFOURCC macro */
+#include "maru_camera_win32_interface.h"
+
+MULTI_DEBUG_CHANNEL(tizen, camera_win32);
+
+/*
+ * COM Interface implementations
+ *
+ */
+
+#define SAFE_RELEASE(x) \
+    do { \
+        if (x) { \
+            (x)->lpVtbl->Release(x); \
+            x = NULL; \
+        } \
+    } while (0)
+
+typedef HRESULT (STDAPICALLTYPE *CallbackFn)(ULONG dwSize, BYTE *pBuffer);
+
+/*
+ * HWCGrabCallback
+ */
+
+typedef struct HWCGrabCallback {
+    IGrabCallback IGrabCallback_iface;
+    long m_cRef;
+    CallbackFn m_pCallback;
+    STDMETHODIMP (*SetCallback)(IGrabCallback *iface, CallbackFn pCallbackFn);
+} HWCGrabCallback;
+
+static inline HWCGrabCallback *impl_from_IGrabCallback(IGrabCallback *iface)
+{
+    return CONTAINING_RECORD(iface, HWCGrabCallback, IGrabCallback_iface);
+}
+
+static STDMETHODIMP HWCGrabCallback_QueryInterface(IGrabCallback *iface,
+                                                   REFIID riid, void **ppv)
+{
+    if (IsEqualIID(riid, &IID_IUnknown)) {
+        *ppv = (IUnknown *)iface;
+    } else if (IsEqualIID(riid, &IID_IGrabCallback)) {
+        *ppv = (IGrabCallback *)iface;
+    } else {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IGrabCallback_AddRef(iface);
+    return S_OK;
+}
+
+static STDMETHODIMP_(ULONG) HWCGrabCallback_AddRef(IGrabCallback *iface)
+{
+    HWCGrabCallback *This = impl_from_IGrabCallback(iface);
+
+    return InterlockedIncrement(&This->m_cRef);
+}
+
+static STDMETHODIMP_(ULONG) HWCGrabCallback_Release(IGrabCallback *iface)
+{
+    HWCGrabCallback *This = impl_from_IGrabCallback(iface);
+
+    if (InterlockedDecrement(&This->m_cRef) == 0) {
+        This->m_pCallback = NULL;
+        g_free((void *)This);
+        This = NULL;
+        return 0;
+    }
+
+    return This->m_cRef;
+}
+
+static STDMETHODIMP HWCGrabCallback_Grab(IGrabCallback *iface,
+                                         ULONG dwSize, BYTE *pBuffer)
+{
+    HWCGrabCallback *This = impl_from_IGrabCallback(iface);
+
+    if (This->m_pCallback) {
+        HRESULT hr = This->m_pCallback(dwSize, pBuffer);
+        if (FAILED(hr)) {
+            return E_FAIL;
+        } else {
+            return S_OK;
+        }
+    }
+
+    return E_FAIL;
+}
+
+static STDMETHODIMP HWCGrabCallback_SetCallback(IGrabCallback *iface,
+                                                CallbackFn pCallbackFn)
+{
+    HWCGrabCallback *This = impl_from_IGrabCallback(iface);
+
+    This->m_pCallback = pCallbackFn;
+    return S_OK;
+}
+
+static IGrabCallbackVtbl HWCGrabCallback_Vtbl = {
+        HWCGrabCallback_QueryInterface,
+        HWCGrabCallback_AddRef,
+        HWCGrabCallback_Release,
+        HWCGrabCallback_Grab
+};
+
+static STDMETHODIMP HWCGrabCallback_Construct(IGrabCallback **ppv)
+{
+    HWCGrabCallback *This =
+            (HWCGrabCallback *)g_malloc0(sizeof(HWCGrabCallback));
+
+    if (!This) {
+        ERR("failed to HWCGrabCallback_Construct, E_OUTOFMEMORY\n");
+        return E_OUTOFMEMORY;
+    }
+
+    This->IGrabCallback_iface.lpVtbl = &HWCGrabCallback_Vtbl;
+    This->m_cRef = 1;
+    This->m_pCallback = NULL;
+    This->SetCallback = HWCGrabCallback_SetCallback;
+    *ppv = &This->IGrabCallback_iface;
+    return S_OK;
+}
+
+/*
+ * HWCPin
+ */
+
+typedef struct HWCInPin {
+    IPin IPin_iface;
+    IMemInputPin IMemInputPin_iface;
+    IBaseFilter *m_pCFilter;
+    IPin *m_pConnectedPin;
+    IGrabCallback *m_pCallback;
+    IMemAllocator *m_pAllocator;
+    BOOL m_bReadOnly;
+    long m_cRef;
+    STDMETHODIMP (*SetGrabCallbackIF)(IPin *iface, IGrabCallback *pCaptureCB);
+} HWCInPin;
+
+static inline HWCInPin *impl_from_IPin(IPin *iface)
+{
+    return CONTAINING_RECORD(iface, HWCInPin, IPin_iface);
+}
+
+static inline HWCInPin *impl_from_IMemInputPin(IMemInputPin *iface)
+{
+    return CONTAINING_RECORD(iface, HWCInPin, IMemInputPin_iface);
+}
+
+static STDMETHODIMP HWCPin_QueryInterface(IPin *iface, REFIID riid, void **ppv)
+{
+    HWCInPin *This = impl_from_IPin(iface);
+
+    if (IsEqualIID(riid, &IID_IUnknown)) {
+        *ppv = (IUnknown *)(&This->IPin_iface);
+        IPin_AddRef((IPin *)*ppv);
+    } else if (IsEqualIID(riid, &IID_IPin)) {
+        *ppv = (IPin *)(&This->IPin_iface);
+        IPin_AddRef((IPin *)*ppv);
+    } else if (IsEqualIID(riid, &IID_IMemInputPin)) {
+        *ppv = (IMemInputPin *)(&This->IMemInputPin_iface);
+        IPin_AddRef((IMemInputPin *)*ppv);
+    } else {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    return S_OK;
+}
+
+static STDMETHODIMP_(ULONG) HWCPin_AddRef(IPin *iface)
+{
+    HWCInPin *This = impl_from_IPin(iface);
+
+    return InterlockedIncrement(&This->m_cRef);
+}
+
+static STDMETHODIMP_(ULONG) HWCPin_Release(IPin *iface)
+{
+    HWCInPin *This = impl_from_IPin(iface);
+
+    if (InterlockedDecrement(&This->m_cRef) == 0) {
+        if (This->m_pCallback) {
+            SAFE_RELEASE(This->m_pCallback);
+        }
+        if (This->m_pConnectedPin) {
+            SAFE_RELEASE(This->m_pConnectedPin);
+        }
+        if (This->m_pAllocator) {
+            IMemAllocator_Decommit(This->m_pAllocator);
+            SAFE_RELEASE(This->m_pAllocator);
+        }
+        g_free((void *)This);
+        This = NULL;
+        return 0;
+    }
+    return This->m_cRef;
+}
+
+static STDMETHODIMP HWCPin_Connect(IPin *iface,
+                                   IPin *pReceivePin,
+                                   const AM_MEDIA_TYPE *pmt)
+{
+    HWCInPin *This = impl_from_IPin(iface);
+
+    if (!pReceivePin) {
+        return E_POINTER;
+    }
+
+    if (This->m_pConnectedPin) {
+        return VFW_E_ALREADY_CONNECTED;
+    }
+
+    if (!pmt) {
+        return S_OK;
+    }
+    return S_FALSE;
+}
+
+static STDMETHODIMP HWCPin_ReceiveConnection(IPin *iface, IPin *pConnector,
+                                             const AM_MEDIA_TYPE *pmt)
+{
+    PIN_DIRECTION pd;
+    FILTER_STATE fs;
+    HWCInPin *This = impl_from_IPin(iface);
+
+    if (pConnector == NULL || pmt == NULL) {
+        return E_POINTER;
+    }
+
+    if (This->m_pConnectedPin) {
+        return VFW_E_ALREADY_CONNECTED;
+    }
+    IBaseFilter_GetState(This->m_pCFilter, 0, &fs);
+    if (fs != State_Stopped) {
+        return VFW_E_NOT_STOPPED;
+    }
+    IPin_QueryDirection(pConnector, &pd);
+    if (pd == PINDIR_INPUT) {
+        return VFW_E_INVALID_DIRECTION;
+    }
+
+    This->m_pConnectedPin = pConnector;
+    IPin_AddRef(This->m_pConnectedPin);
+    return S_OK;
+}
+
+static STDMETHODIMP HWCPin_Disconnect(IPin *iface)
+{
+    HWCInPin *This = impl_from_IPin(iface);
+
+    HRESULT hr;
+    FILTER_STATE fs;
+    IBaseFilter_GetState(This->m_pCFilter, 0, &fs);
+    if (fs != State_Stopped) {
+        return VFW_E_NOT_STOPPED;
+    }
+    if (This->m_pConnectedPin == NULL) {
+        hr = S_FALSE;
+    } else {
+        if (This->m_pAllocator) {
+            hr = IMemAllocator_Decommit(This->m_pAllocator);
+            if (FAILED(hr)) {
+                return hr;
+            }
+            SAFE_RELEASE(This->m_pAllocator);
+        }
+        SAFE_RELEASE(This->m_pConnectedPin);
+        hr = S_OK;
+    }
+    return hr;
+}
+
+static STDMETHODIMP HWCPin_ConnectedTo(IPin *iface, IPin **ppPin)
+{
+    HWCInPin *This = impl_from_IPin(iface);
+
+    if (ppPin == NULL) {
+        return E_POINTER;
+    }
+
+    if (This->m_pConnectedPin == NULL) {
+        *ppPin = NULL;
+        return VFW_E_NOT_CONNECTED;
+    } else {
+        *ppPin = This->m_pConnectedPin;
+        IPin_AddRef(This->m_pConnectedPin);
+    }
+    return S_OK;
+}
+
+static STDMETHODIMP HWCPin_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *pmt)
+{
+    if (pmt == NULL) {
+        return E_POINTER;
+    }
+    return VFW_E_NOT_CONNECTED;
+}
+
+static STDMETHODIMP HWCPin_QueryPinInfo(IPin *iface, PIN_INFO *pInfo)
+{
+    HWCInPin *This = impl_from_IPin(iface);
+
+    if (pInfo == NULL) {
+        return E_POINTER;
+    }
+
+    pInfo->pFilter = This->m_pCFilter;
+    if (This->m_pCFilter) {
+        IBaseFilter_AddRef(This->m_pCFilter);
+    }
+    memcpy((void *)pInfo->achName, (void *)HWCPinName, sizeof(HWCPinName));
+    pInfo->dir = PINDIR_INPUT;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCPin_QueryDirection(IPin *iface, PIN_DIRECTION *pPinDir)
+{
+    if (pPinDir == NULL) {
+        return E_POINTER;
+    }
+    *pPinDir = PINDIR_INPUT;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCPin_QueryId(IPin *iface, LPWSTR *Id)
+{
+    PVOID pId;
+    if (Id == NULL) {
+        return E_POINTER;
+    }
+    pId = CoTaskMemAlloc(sizeof(HWCPinName));
+    memcpy((void *)pId, (void *)HWCPinName, sizeof(HWCPinName));
+    *Id = (LPWSTR)pId;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCPin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt)
+{
+    if (pmt == NULL) {
+        return E_POINTER;
+    }
+    return S_OK;
+}
+
+static STDMETHODIMP HWCPin_EnumMediaTypes(IPin *iface,
+                                          IEnumMediaTypes **ppEnum)
+{
+    if (ppEnum == NULL) {
+            return E_POINTER;
+    }
+    return E_NOTIMPL;
+}
+
+static STDMETHODIMP HWCPin_QueryInternalConnections(IPin *iface,
+                                                    IPin **ppPin,
+                                                    ULONG *nPin)
+{
+    return E_NOTIMPL;
+}
+
+static STDMETHODIMP HWCPin_EndOfStream(IPin *iface)
+{
+    return S_OK;
+}
+
+static STDMETHODIMP HWCPin_BeginFlush(IPin *iface)
+{
+    return S_OK;
+}
+
+static STDMETHODIMP HWCPin_EndFlush(IPin *iface)
+{
+    return S_OK;
+}
+
+static STDMETHODIMP HWCPin_NewSegment(IPin *iface, REFERENCE_TIME tStart,
+                                      REFERENCE_TIME tStop, double dRate)
+{
+    return S_OK;
+}
+
+static STDMETHODIMP HWCMemInputPin_QueryInterface(IMemInputPin *iface,
+                                                  REFIID riid, void **ppv)
+{
+    HWCInPin *This = impl_from_IMemInputPin(iface);
+
+    if (IsEqualIID(riid, &IID_IUnknown)) {
+        *ppv = (IUnknown *)(&This->IMemInputPin_iface);
+        IPin_AddRef((IPin *)*ppv);
+    } else if (IsEqualIID(riid, &IID_IPin)) {
+        *ppv = (IPin *)(&This->IPin_iface);
+        IPin_AddRef((IPin *)*ppv);
+    } else if (IsEqualIID(riid, &IID_IMemInputPin)) {
+        *ppv = (IMemInputPin *)(&This->IMemInputPin_iface);
+        IPin_AddRef((IMemInputPin *)*ppv);
+    } else {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    return S_OK;
+}
+
+static STDMETHODIMP_(ULONG) HWCMemInputPin_AddRef(IMemInputPin *iface)
+{
+    HWCInPin *This = impl_from_IMemInputPin(iface);
+
+    return InterlockedIncrement(&This->m_cRef);
+}
+
+static STDMETHODIMP_(ULONG) HWCMemInputPin_Release(IMemInputPin *iface)
+{
+    HWCInPin *This = impl_from_IMemInputPin(iface);
+
+    if (InterlockedDecrement(&This->m_cRef) == 0) {
+        if (This->m_pCallback) {
+            SAFE_RELEASE(This->m_pCallback);
+        }
+        if (This->m_pConnectedPin) {
+            SAFE_RELEASE(This->m_pConnectedPin);
+        }
+        if (This->m_pAllocator) {
+            IMemAllocator_Decommit(This->m_pAllocator);
+            SAFE_RELEASE(This->m_pAllocator);
+        }
+        g_free((void *)This);
+        This = NULL;
+        return 0;
+    }
+    return This->m_cRef;
+}
+
+static STDMETHODIMP HWCMemInputPin_GetAllocator(IMemInputPin *iface,
+                                                IMemAllocator **ppAllocator)
+{
+    HWCInPin *This = impl_from_IMemInputPin(iface);
+
+    if (ppAllocator == NULL) {
+        return E_POINTER;
+    }
+
+    if (This->m_pAllocator == NULL) {
+        HRESULT hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL,
+                                        CLSCTX_INPROC_SERVER,
+                                        &IID_IMemAllocator,
+                                        (void **)&(This->m_pAllocator));
+        if (FAILED(hr)) {
+            ERR("Failed to CoCreateInstance for retrieving MemoryAllocator\n");
+            return hr;
+        }
+    }
+    ASSERT(This->m_pAllocator != NULL);
+    *ppAllocator = This->m_pAllocator;
+    IMemAllocator_AddRef(This->m_pAllocator);
+
+    return S_OK;
+}
+
+static STDMETHODIMP HWCMemInputPin_NotifyAllocator(IMemInputPin *iface,
+                                                   IMemAllocator *pAllocator,
+                                                   BOOL bReadOnly)
+{
+    HWCInPin *This = impl_from_IMemInputPin(iface);
+
+    if (pAllocator == NULL) {
+        return E_POINTER;
+    }
+
+    IMemAllocator *pOldAllocator = This->m_pAllocator;
+    IMemAllocator_AddRef(pAllocator);
+    This->m_pAllocator = pAllocator;
+
+    if (pOldAllocator != NULL) {
+        SAFE_RELEASE(pOldAllocator);
+    }
+
+    This->m_bReadOnly = bReadOnly;
+
+    return S_OK;
+}
+
+static STDMETHODIMP HWCMemInputPin_GetAllocatorRequirements(
+                                   IMemInputPin *iface,
+                                   ALLOCATOR_PROPERTIES *pProps)
+{
+    return E_NOTIMPL;
+}
+
+static STDMETHODIMP HWCMemInputPin_Receive(IMemInputPin *iface,
+                                           IMediaSample *pSample)
+{
+    HWCInPin *This = impl_from_IMemInputPin(iface);
+
+    if (pSample == NULL) {
+        ERR("pSample is NULL\n");
+        return E_POINTER;
+    }
+    if (This->m_pCallback != NULL) {
+        HRESULT hr;
+        BYTE *pBuffer = NULL;
+        DWORD dwSize = 0;
+        dwSize = IMediaSample_GetSize(pSample);
+        hr = IMediaSample_GetPointer(pSample, &pBuffer);
+        if (FAILED(hr)) {
+            ERR("Receive function : "
+                "failed to IMediaSample_GetPointer, 0x%ld\n", hr);
+            return hr;
+        }
+        hr = IGrabCallback_Grab(This->m_pCallback, dwSize, pBuffer);
+        if (FAILED(hr)) {
+            ERR("Receive function : failed to IGrabCallback_Grab, 0x%ld\n",
+                hr);
+            return hr;
+        }
+    }
+    return S_OK;
+}
+
+static STDMETHODIMP HWCMemInputPin_ReceiveMultiple(IMemInputPin *iface,
+                                                   IMediaSample **pSamples,
+                                                   long nSamples,
+                                                   long *nSamplesProcessed)
+{
+    HRESULT hr = S_OK;
+
+    if (pSamples == NULL) {
+        return E_POINTER;
+    }
+
+    *nSamplesProcessed = 0;
+
+    while (nSamples-- > 0) {
+        hr = IMemInputPin_Receive(iface, pSamples[*nSamplesProcessed]);
+        if (hr != S_OK) {
+            break;
+        }
+        (*nSamplesProcessed)++;
+    }
+    return hr;
+}
+
+static STDMETHODIMP HWCMemInputPin_ReceiveCanBlock(IMemInputPin *iface)
+{
+    return S_FALSE;
+}
+
+static STDMETHODIMP HWCPin_SetCallback(IPin *iface, IGrabCallback *pCaptureCB)
+{
+    HWCInPin *This = impl_from_IPin(iface);
+
+    if (pCaptureCB == NULL) {
+        SAFE_RELEASE(This->m_pCallback);
+    } else {
+        This->m_pCallback = pCaptureCB;
+        IGrabCallback_AddRef(This->m_pCallback);
+    }
+
+    return S_OK;
+}
+
+
+static IPinVtbl HWCPin_Vtbl = {
+    HWCPin_QueryInterface,
+    HWCPin_AddRef,
+    HWCPin_Release,
+    HWCPin_Connect,
+    HWCPin_ReceiveConnection,
+    HWCPin_Disconnect,
+    HWCPin_ConnectedTo,
+    HWCPin_ConnectionMediaType,
+    HWCPin_QueryPinInfo,
+    HWCPin_QueryDirection,
+    HWCPin_QueryId,
+    HWCPin_QueryAccept,
+    HWCPin_EnumMediaTypes,
+    HWCPin_QueryInternalConnections,
+    HWCPin_EndOfStream,
+    HWCPin_BeginFlush,
+    HWCPin_EndFlush,
+    HWCPin_NewSegment
+};
+
+static IMemInputPinVtbl HWCMemInputPin_Vtbl = {
+    HWCMemInputPin_QueryInterface,
+    HWCMemInputPin_AddRef,
+    HWCMemInputPin_Release,
+    HWCMemInputPin_GetAllocator,
+    HWCMemInputPin_NotifyAllocator,
+    HWCMemInputPin_GetAllocatorRequirements,
+    HWCMemInputPin_Receive,
+    HWCMemInputPin_ReceiveMultiple,
+    HWCMemInputPin_ReceiveCanBlock
+};
+
+static STDMETHODIMP HWCInPin_Construct(IBaseFilter *pFilter, IPin **ppv)
+{
+    HWCInPin *This = (HWCInPin *)g_malloc0(sizeof(HWCInPin));
+
+    if (!This) {
+        ERR("failed to HWCInPin_Construct, E_OUTOFMEMORY\n");
+        return E_OUTOFMEMORY;
+    }
+
+    This->IPin_iface.lpVtbl = &HWCPin_Vtbl;
+    This->IMemInputPin_iface.lpVtbl = &HWCMemInputPin_Vtbl;
+    This->m_bReadOnly = FALSE;
+    This->m_pCFilter = pFilter;
+    This->m_pConnectedPin = NULL;
+    This->m_pCallback = NULL;
+    This->m_pAllocator = NULL;
+    This->m_cRef = 1;
+    This->SetGrabCallbackIF = HWCPin_SetCallback;
+    *ppv = &This->IPin_iface;
+
+    return S_OK;
+}
+
+/*
+ * HWCEnumPins
+ */
+
+typedef struct HWCEnumPins {
+    IEnumPins IEnumPins_iface;
+    IBaseFilter *m_pFilter;
+    int m_nPos;
+    long m_cRef;
+} HWCEnumPins;
+
+static inline HWCEnumPins *impl_from_IEnumPins(IEnumPins *iface)
+{
+    return CONTAINING_RECORD(iface, HWCEnumPins, IEnumPins_iface);
+}
+
+static STDMETHODIMP HWCEnumPins_QueryInterface(IEnumPins *iface,
+                                               REFIID riid, void **ppv)
+{
+    if (ppv == NULL) {
+        return E_POINTER;
+    }
+
+    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumPins)) {
+        *ppv = iface;
+    } else {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IEnumPins_AddRef(iface);
+    return S_OK;
+}
+
+static STDMETHODIMP_(ULONG) HWCEnumPins_AddRef(IEnumPins *iface)
+{
+    HWCEnumPins *This = impl_from_IEnumPins(iface);
+
+    return InterlockedIncrement(&This->m_cRef);
+}
+
+static STDMETHODIMP_(ULONG) HWCEnumPins_Release(IEnumPins *iface)
+{
+    HWCEnumPins *This = impl_from_IEnumPins(iface);
+
+    if (InterlockedDecrement(&This->m_cRef) == 0) {
+        if (This->m_pFilter) {
+            SAFE_RELEASE(This->m_pFilter);
+        }
+        This->m_nPos = 0;
+        g_free((void *)This);
+        This = NULL;
+        return 0;
+    }
+    return This->m_cRef;
+}
+
+static STDMETHODIMP HWCEnumPins_Next(IEnumPins *iface, ULONG cPins,
+                                     IPin **ppPins, ULONG *pcFetched)
+{
+    ULONG fetched;
+    HWCEnumPins *This = impl_from_IEnumPins(iface);
+
+    if (ppPins == NULL) {
+        return E_POINTER;
+    }
+
+    if (This->m_nPos < 1 && cPins > 0) {
+        IPin *pPin;
+        IBaseFilter_FindPin(This->m_pFilter, HWCPinName, &pPin);
+        *ppPins = pPin;
+        fetched = 1;
+        This->m_nPos++;
+    } else {
+        fetched = 0;
+    }
+
+    if (pcFetched != NULL) {
+        *pcFetched = fetched;
+    }
+
+    return (fetched == cPins) ? S_OK : S_FALSE;
+}
+
+static STDMETHODIMP HWCEnumPins_Skip(IEnumPins *iface, ULONG cPins)
+{
+    HWCEnumPins *This = impl_from_IEnumPins(iface);
+    This->m_nPos += cPins;
+    return (This->m_nPos >= 1) ? S_FALSE : S_OK;
+}
+
+static STDMETHODIMP HWCEnumPins_Reset(IEnumPins *iface)
+{
+    HWCEnumPins *This = impl_from_IEnumPins(iface);
+    This->m_nPos = 0;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCEnumPins_Construct(IBaseFilter *pFilter,
+                                          int nPos, IEnumPins **ppv);
+
+static STDMETHODIMP HWCEnumPins_Clone(IEnumPins *iface, IEnumPins **ppEnum)
+{
+    HWCEnumPins *This = impl_from_IEnumPins(iface);
+
+    if (ppEnum == NULL) {
+        return E_POINTER;
+    }
+
+    HWCEnumPins_Construct(This->m_pFilter, This->m_nPos, ppEnum);
+    if (*ppEnum == NULL) {
+        ERR("failed to HWCEnumPins_Construct in clone, E_OUTOFMEMORY\n");
+        return E_OUTOFMEMORY;
+    }
+
+    return S_OK;
+}
+
+static IEnumPinsVtbl HWCEnumPins_Vtbl = {
+    HWCEnumPins_QueryInterface,
+    HWCEnumPins_AddRef,
+    HWCEnumPins_Release,
+    HWCEnumPins_Next,
+    HWCEnumPins_Skip,
+    HWCEnumPins_Reset,
+    HWCEnumPins_Clone
+};
+
+
+static STDMETHODIMP HWCEnumPins_Construct(IBaseFilter *pFilter,
+                                          int nPos, IEnumPins **ppv)
+{
+    HWCEnumPins *This = (HWCEnumPins *)g_malloc0(sizeof(HWCEnumPins));
+
+    if (!This) {
+        ERR("failed to HWCEnumPins_Construct, E_OUTOFMEMORY\n");
+        return E_OUTOFMEMORY;
+    }
+
+    This->IEnumPins_iface.lpVtbl = &HWCEnumPins_Vtbl;
+    This->m_pFilter = pFilter;
+    if (This->m_pFilter) {
+        IBaseFilter_AddRef(This->m_pFilter);
+    }
+    This->m_cRef = 1;
+    This->m_nPos = nPos;
+    *ppv = &This->IEnumPins_iface;
+
+    return S_OK;
+}
+
+/*
+ * HWCFilter
+ */
+
+typedef struct HWCFilter {
+    IBaseFilter IBaseFilter_iface;
+    IPin *m_pPin;
+    IFilterGraph *m_pFilterGraph;
+    FILTER_STATE m_state;
+    long m_cRef;
+} HWCFilter;
+
+static inline HWCFilter *impl_from_IBaseFilter(IBaseFilter *iface)
+{
+    return CONTAINING_RECORD(iface, HWCFilter, IBaseFilter_iface);
+}
+
+static STDMETHODIMP HWCFilter_QueryInterface(IBaseFilter *iface,
+                                             REFIID riid, void **ppv)
+{
+    if (IsEqualIID(riid, &IID_IUnknown)) {
+        *ppv = (IUnknown *)iface;
+    } else if (IsEqualIID(riid, &IID_IPersist)) {
+        *ppv = (IPersist *)iface;
+    } else if (IsEqualIID(riid, &IID_IMediaFilter)) {
+        *ppv = (IMediaFilter *)iface;
+    } else if (IsEqualIID(riid, &IID_IBaseFilter)) {
+        *ppv = (IBaseFilter *)iface;
+    } else {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IBaseFilter_AddRef(iface);
+    return S_OK;
+}
+
+static STDMETHODIMP_(ULONG) HWCFilter_AddRef(IBaseFilter *iface)
+{
+    HWCFilter *This = impl_from_IBaseFilter(iface);
+
+    return InterlockedIncrement(&This->m_cRef);
+}
+
+static STDMETHODIMP_(ULONG) HWCFilter_Release(IBaseFilter *iface)
+{
+    HWCFilter *This = impl_from_IBaseFilter(iface);
+
+    if (InterlockedDecrement(&This->m_cRef) == 0) {
+        if (This->m_pPin) {
+            SAFE_RELEASE(This->m_pPin);
+        }
+        g_free((void *)This);
+        This = NULL;
+        return 0;
+    }
+    return This->m_cRef;
+}
+
+static STDMETHODIMP HWCFilter_GetClassID(IBaseFilter *iface, CLSID *pClsID)
+{
+    if (pClsID == NULL) {
+        return E_POINTER;
+    }
+    return E_NOTIMPL;
+}
+
+static STDMETHODIMP HWCFilter_GetState(IBaseFilter *iface, DWORD dwMSecs,
+                                       FILTER_STATE *State)
+{
+    HWCFilter *This = impl_from_IBaseFilter(iface);
+    *State = This->m_state;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCFilter_SetSyncSource(IBaseFilter *iface,
+                                            IReferenceClock *pClock)
+{
+    return S_OK;
+}
+
+static STDMETHODIMP HWCFilter_GetSyncSource(IBaseFilter *iface,
+                                            IReferenceClock **pClock)
+{
+    *pClock = NULL;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCFilter_Stop(IBaseFilter *iface)
+{
+    HWCFilter *This = impl_from_IBaseFilter(iface);
+
+    IPin_EndFlush(This->m_pPin);
+    This->m_state = State_Stopped;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCFilter_Pause(IBaseFilter *iface)
+{
+    HWCFilter *This = impl_from_IBaseFilter(iface);
+    This->m_state = State_Paused;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCFilter_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
+{
+    HWCFilter *This = impl_from_IBaseFilter(iface);
+
+    if (This->m_state == State_Stopped) {
+        HRESULT hr;
+        hr = IBaseFilter_Pause(iface);
+        if (FAILED(hr)) {
+            ERR("HWCFilter_Run : Failed to IBaseFilter_Pause, ret=0xld%\n", hr);
+            return hr;
+        }
+    }
+
+    This->m_state = State_Running;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCFilter_EnumPins(IBaseFilter *iface, IEnumPins **ppEnum)
+{
+    if (ppEnum == NULL) {
+        return E_POINTER;
+    }
+
+    HWCEnumPins_Construct(iface, 0, ppEnum);
+    return *ppEnum == NULL ? E_OUTOFMEMORY : S_OK;
+}
+
+static STDMETHODIMP HWCFilter_FindPin(IBaseFilter *iface, LPCWSTR Id,
+                                      IPin **ppPin)
+{
+    HWCFilter *This = impl_from_IBaseFilter(iface);
+
+    if (ppPin == NULL) {
+        return E_POINTER;
+    }
+
+    if (memcmp((void *)Id, (void *)HWCPinName, sizeof(HWCPinName))) {
+        return VFW_E_NOT_FOUND;
+    }
+
+    if (!This->m_pPin) {
+        HWCInPin_Construct(iface, &This->m_pPin);
+    }
+    *ppPin = This->m_pPin;
+
+    IPin_AddRef(This->m_pPin);
+    return S_OK;
+}
+
+static STDMETHODIMP HWCFilter_QueryFilterInfo(IBaseFilter *iface,
+                                              FILTER_INFO *pInfo)
+{
+    HWCFilter *This = impl_from_IBaseFilter(iface);
+
+    if (pInfo == NULL) {
+        return E_POINTER;
+    }
+
+    memcpy((void *)pInfo->achName,
+           (void *)HWCFilterName,
+           sizeof(HWCFilterName));
+    pInfo->pGraph = This->m_pFilterGraph;
+    if (This->m_pFilterGraph) {
+        IFilterGraph_AddRef(This->m_pFilterGraph);
+    }
+    return S_OK;
+}
+
+static STDMETHODIMP HWCFilter_JoinFilterGraph(IBaseFilter *iface,
+                                              IFilterGraph *pGraph,
+                                              LPCWSTR pName)
+{
+    HWCFilter *This = impl_from_IBaseFilter(iface);
+
+    This->m_pFilterGraph = pGraph;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCFilter_QueryVendorInfo(IBaseFilter *iface,
+                                              LPWSTR *pVendorInfo)
+{
+    return E_NOTIMPL;
+}
+
+static IBaseFilterVtbl HWCFilter_Vtbl = {
+    HWCFilter_QueryInterface,
+    HWCFilter_AddRef,
+    HWCFilter_Release,
+    HWCFilter_GetClassID,
+    HWCFilter_Stop,
+    HWCFilter_Pause,
+    HWCFilter_Run,
+    HWCFilter_GetState,
+    HWCFilter_SetSyncSource,
+    HWCFilter_GetSyncSource,
+    HWCFilter_EnumPins,
+    HWCFilter_FindPin,
+    HWCFilter_QueryFilterInfo,
+    HWCFilter_JoinFilterGraph,
+    HWCFilter_QueryVendorInfo
+};
+
+static STDMETHODIMP HWCFilter_Construct(IBaseFilter **ppv)
+{
+    HWCFilter *This = (HWCFilter *)g_malloc0(sizeof(HWCFilter));
+
+    if (!This) {
+        ERR("failed to HWCFilter_Construct, E_OUTOFMEMORY\n");
+        return E_OUTOFMEMORY;
+    }
+
+    This->IBaseFilter_iface.lpVtbl = &HWCFilter_Vtbl;
+    This->m_pFilterGraph = NULL;
+    This->m_state = State_Stopped;
+    This->m_cRef = 1;
+    HWCInPin_Construct(&This->IBaseFilter_iface, &This->m_pPin);
+    *ppv = &This->IBaseFilter_iface;
+
+    return S_OK;
+}
+
+/**********************************************************
+ *
+ * Virtual device implementations
+ *
+ **********************************************************/
+
+
+/*
+ * Declaration global variables for Win32 COM Interfaces
+ */
+IGraphBuilder *g_pGB ;
+ICaptureGraphBuilder2 *g_pCGB;
+IMediaControl *g_pMediaControl;
+
+IPin *g_pOutputPin;
+IPin *g_pInputPin;
+IBaseFilter *g_pDstFilter;
+IBaseFilter *g_pSrcFilter;
+
+IGrabCallback *g_pCallback;
+
+/* V4L2 defines copy from videodev2.h */
+#define V4L2_CTRL_FLAG_SLIDER       0x0020
+
+#define V4L2_CTRL_CLASS_USER        0x00980000
+#define V4L2_CID_BASE               (V4L2_CTRL_CLASS_USER | 0x900)
+#define V4L2_CID_BRIGHTNESS         (V4L2_CID_BASE+0)
+#define V4L2_CID_CONTRAST           (V4L2_CID_BASE+1)
+#define V4L2_CID_SATURATION         (V4L2_CID_BASE+2)
+#define V4L2_CID_SHARPNESS          (V4L2_CID_BASE+27)
+
+#define V4L2_PIX_FMT_YUYV    MAKEFOURCC('Y', 'U', 'Y', 'V') /* 16  YUV 4:2:2 */
+#define V4L2_PIX_FMT_YUV420  MAKEFOURCC('Y', 'U', '1', '2') /* 12  YUV 4:2:0 */
+#define V4L2_PIX_FMT_YVU420  MAKEFOURCC('Y', 'V', '1', '2') /* 12  YVU 4:2:0 */
+#define V4L2_PIX_FMT_RGB24   MAKEFOURCC('R', 'G', 'B', '3') /* 24  RGB-8-8-8 */
+
+typedef struct tagMaruCamConvertPixfmt {
+    uint32_t fmt;   /* fourcc */
+    uint32_t bpp;   /* bits per pixel, 0 for compressed formats */
+    uint32_t needs_conversion;
+} MaruCamConvertPixfmt;
+
+static MaruCamConvertPixfmt supported_dst_pixfmts[] = {
+        { V4L2_PIX_FMT_YUYV, 16, 0 },
+        { V4L2_PIX_FMT_YUV420, 12, 0 },
+        { V4L2_PIX_FMT_YVU420, 12, 0 },
+};
+
+typedef struct tagMaruCamConvertFrameInfo {
+    uint32_t width;
+    uint32_t height;
+} MaruCamConvertFrameInfo;
+
+static MaruCamConvertFrameInfo supported_dst_frames[] = {
+        { 640, 480 },
+        { 352, 288 },
+        { 320, 240 },
+        { 176, 144 },
+        { 160, 120 },
+};
+
+#define MARUCAM_CTRL_VALUE_MAX      20
+#define MARUCAM_CTRL_VALUE_MIN      1
+#define MARUCAM_CTRL_VALUE_MID      10
+#define MARUCAM_CTRL_VALUE_STEP     1
+
+struct marucam_qctrl {
+    uint32_t id;
+    uint32_t hit;
+    long min;
+    long max;
+    long step;
+    long init_val;
+};
+
+static struct marucam_qctrl qctrl_tbl[] = {
+    { V4L2_CID_BRIGHTNESS, 0, },
+    { V4L2_CID_CONTRAST, 0, },
+    { V4L2_CID_SATURATION, 0, },
+    { V4L2_CID_SHARPNESS, 0, },
+};
+
+static MaruCamState *g_state;
+
+static uint32_t ready_count;
+static uint32_t cur_fmt_idx;
+static uint32_t cur_frame_idx;
+static void *grab_buf;
+static uint32_t g_dwSrcFmt;
+
+
+/*
+ * Helper functions - converting image formats, converting values
+ */
+
+static uint32_t get_bytesperline(uint32_t pixfmt, uint32_t width)
+{
+    uint32_t bytesperline;
+
+    switch (pixfmt) {
+    case V4L2_PIX_FMT_YUV420:
+    case V4L2_PIX_FMT_YVU420:
+        bytesperline = (width * 12) >> 3;
+        break;
+    case V4L2_PIX_FMT_YUYV:
+    default:
+        bytesperline = width * 2;
+        break;
+    }
+
+    return bytesperline;
+}
+
+static uint32_t get_sizeimage(uint32_t pixfmt, uint32_t width, uint32_t height)
+{
+    return get_bytesperline(pixfmt, width) * height;
+}
+
+void yuyv_to_yuv420(const unsigned char *src, unsigned char *dest,
+        uint32_t width, uint32_t height, uint32_t yvu);
+void rgb24_to_yuv420(const unsigned char *src, unsigned char *dest,
+        uint32_t width, uint32_t height, uint32_t yvu);
+void rgb24_to_yuyv(unsigned char *src, unsigned char *dest,
+        uint32_t width, uint32_t height);
+void yuv420_to_yvu420(unsigned char *src, unsigned char *dest,
+        uint32_t width, uint32_t height);
+void yuv420_to_yuyv(unsigned char *src, unsigned char *dest,
+        uint32_t width, uint32_t height);
+
+static long value_convert_from_guest(long min, long max, long value)
+{
+    double rate = 0.0;
+    long dist = 0, ret = 0;
+
+    dist = max - min;
+
+    if (dist < MARUCAM_CTRL_VALUE_MAX) {
+        rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;
+        ret = min + (int32_t)(value / rate);
+    } else {
+        rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;
+        ret = min + (int32_t)(rate * value);
+    }
+    return ret;
+}
+
+static long value_convert_to_guest(long min, long max, long value)
+{
+    double rate  = 0.0;
+    long dist = 0, ret = 0;
+
+    dist = max - min;
+
+    if (dist < MARUCAM_CTRL_VALUE_MAX) {
+        rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;
+        ret = (int32_t)((double)(value - min) * rate);
+    } else {
+        rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;
+        ret = (int32_t)((double)(value - min) / rate);
+    }
+
+    return ret;
+}
+
+/*
+ * Callback function for grab frames
+ */
+static STDMETHODIMP marucam_device_callbackfn(ULONG dwSize, BYTE *pBuffer)
+{
+    void *tmp_buf;
+    uint32_t width, height, fmt, imgsize;
+
+    width = supported_dst_frames[cur_frame_idx].width;
+    height = supported_dst_frames[cur_frame_idx].height;
+    fmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
+    imgsize = get_sizeimage(fmt, width, height);
+
+    if (imgsize > (uint32_t)dwSize) {
+        ERR("Image size is mismatched\n");
+        return E_FAIL;
+    }
+
+    switch (g_dwSrcFmt) {
+    case V4L2_PIX_FMT_YUYV:
+        switch (fmt) {
+        case V4L2_PIX_FMT_YUV420:
+            yuyv_to_yuv420(pBuffer, grab_buf, width, height, 0);
+            break;
+        case V4L2_PIX_FMT_YVU420:
+            yuyv_to_yuv420(pBuffer, grab_buf, width, height, 1);
+            break;
+        case V4L2_PIX_FMT_YUYV:
+            memcpy(grab_buf, (void *)pBuffer, (size_t)dwSize);
+            break;
+        default:
+            ERR("Invalid pixel format\n");
+            return E_FAIL;
+        }
+        break;
+    case V4L2_PIX_FMT_RGB24:
+        switch (fmt) {
+        case V4L2_PIX_FMT_YUV420:
+            rgb24_to_yuv420(pBuffer, grab_buf, width, height, 0);
+            break;
+        case V4L2_PIX_FMT_YVU420:
+            rgb24_to_yuv420(pBuffer, grab_buf, width, height, 1);
+            break;
+        case V4L2_PIX_FMT_YUYV:
+            rgb24_to_yuyv(pBuffer, grab_buf, width, height);
+            break;
+        default:
+            ERR("Invalid pixel format\n");
+            return E_FAIL;
+        }
+        break;
+    case V4L2_PIX_FMT_YUV420:
+        switch (fmt) {
+        case V4L2_PIX_FMT_YUV420:
+            memcpy(grab_buf, (void *)pBuffer, (size_t)dwSize);
+            break;
+        case V4L2_PIX_FMT_YVU420:
+            yuv420_to_yvu420(pBuffer, grab_buf, width, height);
+            break;
+        case V4L2_PIX_FMT_YUYV:
+            yuv420_to_yuyv(pBuffer, grab_buf, width, height);
+            break;
+        default:
+            ERR("Invalid pixel format\n");
+            return E_FAIL;
+        }
+        break;
+    default:
+        ERR("Invalid pixel format\n");
+        return E_FAIL;
+    }
+
+    qemu_mutex_lock(&g_state->thread_mutex);
+    if (g_state->streamon) {
+        if (ready_count < MARUCAM_SKIPFRAMES) {
+            /* skip a frame cause first some frame are distorted */
+            ++ready_count;
+            TRACE("skip %d frame\n", ready_count);
+            qemu_mutex_unlock(&g_state->thread_mutex);
+            return S_OK;
+        }
+        if (g_state->req_frame == 0) {
+            TRACE("there is no request\n");
+            qemu_mutex_unlock(&g_state->thread_mutex);
+            return S_OK;
+        }
+        tmp_buf = g_state->vaddr + g_state->buf_size * (g_state->req_frame - 1);
+        memcpy(tmp_buf, grab_buf, g_state->buf_size);
+        g_state->req_frame = 0; /* clear request */
+        g_state->isr |= 0x01;   /* set a flag of rasing a interrupt */
+        qemu_bh_schedule(g_state->tx_bh);
+    }
+    qemu_mutex_unlock(&g_state->thread_mutex);
+    return S_OK;
+}
+
+/*
+ * Internal functions for manipulate interfaces
+ */
+
+static STDMETHODIMP_(void) CloseInterfaces(void)
+{
+    if (g_pMediaControl) {
+        g_pMediaControl->lpVtbl->Stop(g_pMediaControl);
+    }
+
+    if (g_pOutputPin) {
+        g_pOutputPin->lpVtbl->Disconnect(g_pOutputPin);
+    }
+
+    SAFE_RELEASE(g_pGB);
+    SAFE_RELEASE(g_pCGB);
+    SAFE_RELEASE(g_pMediaControl);
+    SAFE_RELEASE(g_pOutputPin);
+    SAFE_RELEASE(g_pInputPin);
+    SAFE_RELEASE(g_pDstFilter);
+    SAFE_RELEASE(g_pSrcFilter);
+    SAFE_RELEASE(g_pCallback);
+}
+
+static STDMETHODIMP_(void) DeleteMediaType(AM_MEDIA_TYPE *pmt)
+{
+    if (pmt == NULL) {
+        return;
+    }
+
+    if (pmt->cbFormat != 0) {
+        CoTaskMemFree((PVOID)pmt->pbFormat);
+        pmt->cbFormat = 0;
+        pmt->pbFormat = NULL;
+    }
+    if (pmt->pUnk != NULL) {
+        pmt->pUnk->lpVtbl->Release(pmt->pUnk);
+        pmt->pUnk = NULL;
+    }
+
+    CoTaskMemFree((PVOID)pmt);
+}
+
+static STDMETHODIMP GetPin(IBaseFilter *pFilter,
+                           PIN_DIRECTION PinDir, IPin **ppPin)
+{
+    HRESULT hr;
+    IEnumPins *pEnum = NULL;
+    IPin *pPin = NULL;
+
+    if (ppPin == NULL) {
+        return E_POINTER;
+    }
+
+    hr = pFilter->lpVtbl->EnumPins(pFilter, &pEnum);
+    if (FAILED(hr)) {
+        return hr;
+    }
+
+    while (pEnum->lpVtbl->Next(pEnum, 1, &pPin, 0) == S_OK) {
+        PIN_DIRECTION PinDirThis;
+        hr = pPin->lpVtbl->QueryDirection(pPin, &PinDirThis);
+        if (FAILED(hr)) {
+            SAFE_RELEASE(pPin);
+            SAFE_RELEASE(pEnum);
+            return hr;
+        }
+        if (PinDir == PinDirThis) {
+            *ppPin = pPin;
+            SAFE_RELEASE(pEnum);
+            return S_OK;
+        }
+        SAFE_RELEASE(pPin);
+    }
+
+    SAFE_RELEASE(pEnum);
+    return S_FALSE;
+}
+
+static STDMETHODIMP GraphBuilder_Init(void)
+{
+    HRESULT hr;
+
+    hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC,
+                          &IID_IGraphBuilder, (void **)&g_pGB);
+    if (FAILED(hr)) {
+        ERR("Failed to create instance of GraphBuilder, 0x%x\n", hr);
+        return hr;
+    }
+
+    hr = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,
+                          &IID_ICaptureGraphBuilder2, (void **)&g_pCGB);
+    if (FAILED(hr)) {
+        ERR("Failed to create instance of CaptureGraphBuilder2, 0x%x\n", hr);
+        return hr;
+    }
+
+    hr = g_pCGB->lpVtbl->SetFiltergraph(g_pCGB, g_pGB);
+    if (FAILED(hr)) {
+        ERR("Failed to SetFiltergraph, 0x%x\n", hr);
+        return hr;
+    }
+
+    hr = g_pGB->lpVtbl->QueryInterface(g_pGB, &IID_IMediaControl,
+                                       (void **)&g_pMediaControl);
+    if (FAILED(hr)) {
+        ERR("Failed to QueryInterface for IMediaControl, 0x%x\n", hr);
+        return hr;
+    }
+
+    hr = HWCGrabCallback_Construct(&g_pCallback);
+    if (g_pCallback == NULL) {
+        hr = E_OUTOFMEMORY;
+    }
+
+    hr = ((HWCGrabCallback *)g_pCallback)->SetCallback(g_pCallback,
+                            (CallbackFn)marucam_device_callbackfn);
+
+    return hr;
+}
+
+static STDMETHODIMP BindSourceFilter(void)
+{
+    HRESULT hr;
+    ICreateDevEnum *pCreateDevEnum = NULL;
+    IEnumMoniker *pEnumMK = NULL;
+    IMoniker *pMoniKer;
+
+    hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
+                          &IID_ICreateDevEnum,
+                          (void **)&pCreateDevEnum);
+    if (FAILED(hr)) {
+        ERR("Failed to create instance of CreateDevEnum, 0x%x\n", hr);
+        return hr;
+    }
+
+    hr = pCreateDevEnum->lpVtbl->CreateClassEnumerator(pCreateDevEnum,
+                                      &CLSID_VideoInputDeviceCategory,
+                                      &pEnumMK, 0);
+    if (FAILED(hr)) {
+        ERR("Failed to get VideoInputDeviceCategory, 0x%x\n", hr);
+        SAFE_RELEASE(pCreateDevEnum);
+        return hr;
+    }
+
+    if (!pEnumMK) {
+        ERR("ClassEnumerator moniker is NULL\n");
+        SAFE_RELEASE(pCreateDevEnum);
+        return E_FAIL;
+    }
+    pEnumMK->lpVtbl->Reset(pEnumMK);
+
+    hr = pEnumMK->lpVtbl->Next(pEnumMK, 1, &pMoniKer, NULL);
+    if (hr == S_FALSE) {
+        hr = E_FAIL;
+    }
+    if (SUCCEEDED(hr)) {
+        IPropertyBag *pBag = NULL;
+        hr = pMoniKer->lpVtbl->BindToStorage(pMoniKer, 0, 0,
+                                             &IID_IPropertyBag,
+                                             (void **)&pBag);
+        if (SUCCEEDED(hr)) {
+            VARIANT var;
+            var.vt = VT_BSTR;
+            hr = pBag->lpVtbl->Read(pBag, L"FriendlyName", &var, NULL);
+            if (hr == NOERROR) {
+                hr = pMoniKer->lpVtbl->BindToObject(pMoniKer, NULL, NULL,
+                                                    &IID_IBaseFilter,
+                                                    (void **)&g_pSrcFilter);
+                if (FAILED(hr)) {
+                    ERR("Counldn't bind moniker to filter object!!\n");
+                } else {
+                    g_pSrcFilter->lpVtbl->AddRef(g_pSrcFilter);
+                }
+                SysFreeString(var.bstrVal);
+            }
+            SAFE_RELEASE(pBag);
+        }
+        SAFE_RELEASE(pMoniKer);
+    }
+
+    if (SUCCEEDED(hr)) {
+        hr = g_pGB->lpVtbl->AddFilter(g_pGB, g_pSrcFilter, L"Video Capture");
+        if (hr != S_OK && hr != S_FALSE) {
+            ERR("Counldn't add Video Capture filter to our graph!\n");
+            SAFE_RELEASE(g_pSrcFilter);
+        }
+    }
+    SAFE_RELEASE(pEnumMK);
+    SAFE_RELEASE(pCreateDevEnum);
+
+    return hr;
+}
+
+static STDMETHODIMP BindTargetFilter(void)
+{
+    HRESULT hr;
+    hr = HWCFilter_Construct(&g_pDstFilter);
+
+    if (SUCCEEDED(hr) && g_pDstFilter) {
+        hr = g_pGB->lpVtbl->AddFilter(g_pGB, g_pDstFilter, L"HWCFilter");
+        if (FAILED(hr)) {
+            ERR("Counldn't add HWCFilterr to our graph!\n");
+            SAFE_RELEASE(g_pDstFilter);
+        }
+    }
+    return hr;
+}
+
+static STDMETHODIMP ConnectFilters(void)
+{
+    HRESULT hr;
+
+    hr = GetPin(g_pSrcFilter, PINDIR_OUTPUT , &g_pOutputPin);
+    if (FAILED(hr)) {
+        ERR("Failed to get output pin. 0x%x\n", hr);
+        return hr;
+    }
+
+    hr = GetPin(g_pDstFilter, PINDIR_INPUT , &g_pInputPin);
+    if (FAILED(hr)) {
+        ERR("Failed to get input pin. 0x%x\n", hr);
+        return hr;
+    }
+
+    hr = g_pGB->lpVtbl->Connect(g_pGB, g_pOutputPin, g_pInputPin);
+    if (FAILED(hr)) {
+        ERR("Failed to connect pins. 0x%x\n", hr);
+    }
+    return hr;
+}
+
+static STDMETHODIMP DisconnectPins(void)
+{
+    HRESULT hr;
+
+    hr = g_pGB->lpVtbl->Disconnect(g_pGB, g_pOutputPin);
+    if (FAILED(hr)) {
+        ERR("Failed to disconnect output pin. 0x%x\n", hr);
+        return hr;
+    }
+
+    hr = g_pGB->lpVtbl->Disconnect(g_pGB, g_pInputPin);
+    if (FAILED(hr)) {
+        ERR("Failed to disconnect input pin. 0x%x\n", hr);
+    }
+
+    return hr;
+}
+
+static STDMETHODIMP RemoveFilters(void)
+{
+    HRESULT hr;
+
+    hr = g_pGB->lpVtbl->RemoveFilter(g_pGB, g_pSrcFilter);
+    if (FAILED(hr)) {
+        ERR("Failed to remove source filer. 0x%x\n", hr);
+        return hr;
+    }
+
+    hr = g_pGB->lpVtbl->RemoveFilter(g_pGB, g_pDstFilter);
+    if (FAILED(hr)) {
+        ERR("Failed to remove destination filer. 0x%x\n", hr);
+    }
+
+    return hr;
+}
+
+/* default fps is 15 */
+#define MARUCAM_DEFAULT_FRAMEINTERVAL    666666
+
+static STDMETHODIMP SetFormat(uint32_t dwWidth, uint32_t dwHeight,
+                              uint32_t dwDstFmt, uint32_t *dwSrcFmt)
+{
+    HRESULT hr;
+    IAMStreamConfig *pSConfig;
+    int iCount = 0, iSize = 0;
+    DWORD dwYUY2 = MAKEFOURCC('Y', 'U', 'Y', '2');
+    DWORD dwI420 = MAKEFOURCC('I', '4', '2', '0');
+
+    if (dwSrcFmt == NULL) {
+        ERR("invalid the source format pointer\n");
+        return E_FAIL;
+    }
+
+    hr = g_pCGB->lpVtbl->FindInterface(g_pCGB, &PIN_CATEGORY_CAPTURE, 0,
+                                       g_pSrcFilter, &IID_IAMStreamConfig,
+                                       (void **)&pSConfig);
+    if (FAILED(hr)) {
+        ERR("failed to FindInterface method\n");
+        return hr;
+    }
+
+    hr = pSConfig->lpVtbl->GetNumberOfCapabilities(pSConfig, &iCount, &iSize);
+    if (FAILED(hr)) {
+        ERR("failed to GetNumberOfCapabilities method\n");
+        SAFE_RELEASE(pSConfig);
+        return hr;
+    }
+
+    if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS)) {
+        int iFormat = 0;
+        for (iFormat = 0; iFormat < iCount; iFormat++) {
+            VIDEO_STREAM_CONFIG_CAPS scc;
+            AM_MEDIA_TYPE *pmtConfig;
+
+            hr = pSConfig->lpVtbl->GetStreamCaps(pSConfig, iFormat,
+                                                 &pmtConfig, (BYTE *)&scc);
+            if (hr == S_OK) {
+                if (IsEqualIID(&pmtConfig->formattype, &FORMAT_VideoInfo)) {
+                    VIDEOINFOHEADER *pvi =
+                                         (VIDEOINFOHEADER *)pmtConfig->pbFormat;
+                    if ((pvi->bmiHeader.biWidth == (LONG)dwWidth) &&
+                        (pvi->bmiHeader.biHeight == (LONG)dwHeight)) {
+                        if (pvi->bmiHeader.biCompression == dwYUY2) {
+                            *dwSrcFmt = V4L2_PIX_FMT_YUYV;
+                        } else if ((pvi->bmiHeader.biCompression == BI_RGB) &&
+                                (pvi->bmiHeader.biBitCount == 24)) {
+                            *dwSrcFmt = V4L2_PIX_FMT_RGB24;
+                        } else if (pvi->bmiHeader.biCompression == dwI420) {
+                            *dwSrcFmt = V4L2_PIX_FMT_YUV420;
+                        } else { /* not support format */
+                            DeleteMediaType(pmtConfig);
+                            continue;
+                        }
+                        /* use minimum FPS(maximum frameinterval)
+                           with non-VT system  */
+#ifdef CONFIG_HAX
+                        if (!hax_enabled()) {
+                            pvi->AvgTimePerFrame =
+                                    (REFERENCE_TIME)scc.MaxFrameInterval;
+                        } else {
+                            pvi->AvgTimePerFrame =
+                                (REFERENCE_TIME)MARUCAM_DEFAULT_FRAMEINTERVAL;
+                        }
+#else
+                        pvi->AvgTimePerFrame =
+                                (REFERENCE_TIME)scc.MaxFrameInterval;
+#endif
+                        hr = pSConfig->lpVtbl->SetFormat(pSConfig, pmtConfig);
+                        DeleteMediaType(pmtConfig);
+                        break;
+                    }
+                }
+                DeleteMediaType(pmtConfig);
+            }
+        }
+        if (iFormat >= iCount) {
+            ERR("Failed to Set format. "
+                "Maybe connected webcam does not support the (%ldx%ld) "
+                "resolution or image formats(YUY2, RGB24, I420).\n",
+                dwWidth, dwHeight);
+            hr = E_FAIL;
+        }
+    }
+    SAFE_RELEASE(pSConfig);
+    return hr;
+}
+
+static STDMETHODIMP QueryVideoProcAmp(long nProperty, long *pMin, long *pMax,
+                                      long *pStep, long *pDefault)
+{
+    HRESULT hr;
+    long Flags;
+    IAMVideoProcAmp *pProcAmp = NULL;
+
+    hr = g_pSrcFilter->lpVtbl->QueryInterface(g_pSrcFilter,
+                                              &IID_IAMVideoProcAmp,
+                                              (void **)&pProcAmp);
+    if (FAILED(hr)) {
+        return hr;
+    }
+
+    hr = pProcAmp->lpVtbl->GetRange(pProcAmp, nProperty, pMin, pMax,
+                                    pStep, pDefault, &Flags);
+
+    SAFE_RELEASE(pProcAmp);
+    return hr;
+}
+
+static STDMETHODIMP GetVideoProcAmp(long nProperty, long *pValue)
+{
+    HRESULT hr;
+    long Flags;
+    IAMVideoProcAmp *pProcAmp = NULL;
+
+    hr = g_pSrcFilter->lpVtbl->QueryInterface(g_pSrcFilter,
+                                              &IID_IAMVideoProcAmp,
+                                              (void **)&pProcAmp);
+    if (FAILED(hr)) {
+        return hr;
+    }
+
+    hr = pProcAmp->lpVtbl->Get(pProcAmp, nProperty, pValue, &Flags);
+    if (FAILED(hr)) {
+        ERR("Failed to get property for video\n");
+    }
+
+    SAFE_RELEASE(pProcAmp);
+    return hr;
+}
+
+static STDMETHODIMP SetVideoProcAmp(long nProperty, long value)
+{
+    HRESULT hr;
+
+    IAMVideoProcAmp *pProcAmp = NULL;
+    hr = g_pSrcFilter->lpVtbl->QueryInterface(g_pSrcFilter,
+                                              &IID_IAMVideoProcAmp,
+                                              (void **)&pProcAmp);
+    if (FAILED(hr)) {
+        return hr;
+    }
+
+    hr = pProcAmp->lpVtbl->Set(pProcAmp, nProperty, value,
+                               VideoProcAmp_Flags_Manual);
+    if (FAILED(hr)) {
+        ERR("Failed to set property for video\n");
+    }
+    SAFE_RELEASE(pProcAmp);
+    return hr;
+}
+
+static char *__wchar_to_char(const WCHAR *pwstr)
+{
+    char *pstr = NULL;
+    int len = 0;
+
+    len = wcslen(pwstr) + 1;
+    pstr = (char *)g_malloc0(sizeof(char) * len);
+    wcstombs(pstr, pwstr, len + 1);
+
+    return pstr;
+}
+
+int marucam_device_check(int log_flag)
+{
+    struct timeval t1, t2;
+    int ret = 0;
+    char *device_name = NULL;
+    HRESULT hr = E_FAIL;
+    ICreateDevEnum *pCreateDevEnum = NULL;
+    IGraphBuilder *pGB = NULL;
+    ICaptureGraphBuilder2 *pCGB = NULL;
+    IBaseFilter *pSrcFilter = NULL;
+    IEnumMoniker *pEnumMK = NULL;
+    IMoniker *pMoniKer = NULL;
+    IAMStreamConfig *pSConfig = NULL;
+    int iCount = 0, iSize = 0;
+
+    gettimeofday(&t1, NULL);
+    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+    if (FAILED(hr)) {
+        fprintf(stdout, "[Webcam] failed to CoInitailizeEx\n");
+        gettimeofday(&t2, NULL);
+        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    hr = CoCreateInstance(&CLSID_FilterGraph, NULL,
+                          CLSCTX_INPROC,
+                          &IID_IGraphBuilder,
+                          (void **)&pGB);
+    if (FAILED(hr)) {
+        fprintf(stdout, "[Webcam] Failed to create GraphBuilder, 0x%x\n", hr);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    hr = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL,
+                          CLSCTX_INPROC,
+                          &IID_ICaptureGraphBuilder2,
+                          (void **)&pCGB);
+    if (FAILED(hr)) {
+        fprintf(stdout,
+        "[Webcam] Failed to create CaptureGraphBuilder2, 0x%x\n", hr);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    hr = pCGB->lpVtbl->SetFiltergraph(pCGB, pGB);
+    if (FAILED(hr)) {
+        fprintf(stdout, "[Webcam] Failed to SetFiltergraph, 0x%x\n", hr);
+        SAFE_RELEASE(pCGB);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL,
+                          CLSCTX_INPROC,
+                          &IID_ICreateDevEnum,
+                          (void **)&pCreateDevEnum);
+    if (FAILED(hr)) {
+        fprintf(stdout,
+            "[Webcam] failed to create instance of CLSID_SystemDeviceEnum\n");
+        SAFE_RELEASE(pCGB);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    hr = pCreateDevEnum->lpVtbl->CreateClassEnumerator(pCreateDevEnum,
+                                  &CLSID_VideoInputDeviceCategory, &pEnumMK, 0);
+    if (FAILED(hr)) {
+        fprintf(stdout, "[Webcam] failed to create class enumerator\n");
+        SAFE_RELEASE(pCreateDevEnum);
+        SAFE_RELEASE(pCGB);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    if (!pEnumMK) {
+        fprintf(stdout, "[Webcam] class enumerator is NULL!!\n");
+        SAFE_RELEASE(pCreateDevEnum);
+        SAFE_RELEASE(pCGB);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+    pEnumMK->lpVtbl->Reset(pEnumMK);
+
+    hr = pEnumMK->lpVtbl->Next(pEnumMK, 1, &pMoniKer, NULL);
+    if (FAILED(hr) || (hr == S_FALSE)) {
+        fprintf(stdout, "[Webcam] enum moniker returns a invalid value.\n");
+        SAFE_RELEASE(pEnumMK);
+        SAFE_RELEASE(pCreateDevEnum);
+        SAFE_RELEASE(pCGB);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    IPropertyBag *pBag = NULL;
+    hr = pMoniKer->lpVtbl->BindToStorage(pMoniKer, 0, 0,
+                                         &IID_IPropertyBag,
+                                         (void **)&pBag);
+    if (FAILED(hr)) {
+        fprintf(stdout, "[Webcam] failed to bind to storage.\n");
+        SAFE_RELEASE(pEnumMK);
+        SAFE_RELEASE(pCreateDevEnum);
+        SAFE_RELEASE(pCGB);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    } else {
+        VARIANT var;
+        var.vt = VT_BSTR;
+        hr = pBag->lpVtbl->Read(pBag, L"FriendlyName", &var, NULL);
+        if (hr == S_OK) {
+            ret = 1;
+            if (!log_flag) {
+                SysFreeString(var.bstrVal);
+                SAFE_RELEASE(pBag);
+                SAFE_RELEASE(pMoniKer);
+                SAFE_RELEASE(pEnumMK);
+                SAFE_RELEASE(pCreateDevEnum);
+                SAFE_RELEASE(pCGB);
+                SAFE_RELEASE(pGB);
+                CoUninitialize();
+                gettimeofday(&t2, NULL);
+                fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+                                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+                return ret;
+            }
+            device_name = __wchar_to_char(var.bstrVal);
+            fprintf(stdout, "[Webcam] Device name : %s\n", device_name);
+            g_free(device_name);
+            hr = pMoniKer->lpVtbl->BindToObject(pMoniKer, NULL, NULL,
+                                                &IID_IBaseFilter,
+                                                (void **)&pSrcFilter);
+            if (FAILED(hr)) {
+                fprintf(stdout,
+                   "[Webcam] Counldn't bind moniker to filter object!!\n");
+                SysFreeString(var.bstrVal);
+                SAFE_RELEASE(pBag);
+                SAFE_RELEASE(pMoniKer);
+                SAFE_RELEASE(pEnumMK);
+                SAFE_RELEASE(pCreateDevEnum);
+                SAFE_RELEASE(pCGB);
+                SAFE_RELEASE(pGB);
+                CoUninitialize();
+                gettimeofday(&t2, NULL);
+                fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+                                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+                return ret;
+            } else {
+                pSrcFilter->lpVtbl->AddRef(pSrcFilter);
+            }
+            SysFreeString(var.bstrVal);
+        }
+        SAFE_RELEASE(pBag);
+    }
+    SAFE_RELEASE(pMoniKer);
+
+    hr = pGB->lpVtbl->AddFilter(pGB, pSrcFilter, L"Video Capture");
+    if (hr != S_OK && hr != S_FALSE) {
+        fprintf(stdout,
+                "[Webcam] Counldn't add Video Capture filter to our graph!\n");
+        SAFE_RELEASE(pSrcFilter);
+        SAFE_RELEASE(pEnumMK);
+        SAFE_RELEASE(pCreateDevEnum);
+        SAFE_RELEASE(pCGB);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    hr = pCGB->lpVtbl->FindInterface(pCGB, &PIN_CATEGORY_CAPTURE, 0,
+                                       pSrcFilter, &IID_IAMStreamConfig,
+                                       (void **)&pSConfig);
+    if (FAILED(hr)) {
+        fprintf(stdout, "[Webcam] failed to FindInterface method\n");
+        SAFE_RELEASE(pSrcFilter);
+        SAFE_RELEASE(pEnumMK);
+        SAFE_RELEASE(pCreateDevEnum);
+        SAFE_RELEASE(pCGB);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    hr = pSConfig->lpVtbl->GetNumberOfCapabilities(pSConfig, &iCount, &iSize);
+    if (FAILED(hr)) {
+        fprintf(stdout, "[Webcam] failed to GetNumberOfCapabilities method\n");
+        SAFE_RELEASE(pSConfig);
+        SAFE_RELEASE(pSrcFilter);
+        SAFE_RELEASE(pEnumMK);
+        SAFE_RELEASE(pCreateDevEnum);
+        SAFE_RELEASE(pCGB);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS)) {
+        int iFormat = 0;
+        for (iFormat = 0; iFormat < iCount; iFormat++) {
+            VIDEO_STREAM_CONFIG_CAPS scc;
+            AM_MEDIA_TYPE *pmtConfig;
+
+            hr = pSConfig->lpVtbl->GetStreamCaps(pSConfig, iFormat, &pmtConfig,
+                                                 (BYTE *)&scc);
+            if (hr == S_OK) {
+                if (IsEqualIID(&pmtConfig->formattype, &FORMAT_VideoInfo)) {
+                    VIDEOINFOHEADER *pvi =
+                                         (VIDEOINFOHEADER *)pmtConfig->pbFormat;
+                    if (pvi->bmiHeader.biCompression == BI_RGB) {
+                        fprintf(stdout, "[Webcam] RGB BitCount: %d, %ux%u\n",
+                                pvi->bmiHeader.biBitCount,
+                                pvi->bmiHeader.biWidth,
+                                pvi->bmiHeader.biHeight);
+                    } else {
+                        fprintf(stdout,
+                                "[Webcam] PixelFormat: %c%c%c%c, %ux%u\n",
+                                (char)(pvi->bmiHeader.biCompression),
+                                (char)(pvi->bmiHeader.biCompression >> 8),
+                                (char)(pvi->bmiHeader.biCompression >> 16),
+                                (char)(pvi->bmiHeader.biCompression >> 24),
+                                pvi->bmiHeader.biWidth,
+                                pvi->bmiHeader.biHeight);
+                    }
+                }
+                DeleteMediaType(pmtConfig);
+            }
+        }
+    }
+
+    hr = pGB->lpVtbl->RemoveFilter(pGB, pSrcFilter);
+    if (FAILED(hr)) {
+        fprintf(stdout, "[Webcam] Failed to remove source filer. 0x%x\n", hr);
+    }
+
+    SAFE_RELEASE(pSConfig);
+    SAFE_RELEASE(pSrcFilter);
+    SAFE_RELEASE(pCGB);
+    SAFE_RELEASE(pGB);
+    SAFE_RELEASE(pEnumMK);
+    SAFE_RELEASE(pCreateDevEnum);
+    CoUninitialize();
+    gettimeofday(&t2, NULL);
+    fprintf(stdout, "[Webcam] Elapsed time : %lu.%06lu\n",
+                    t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+
+    return ret;
+}
+
+/* MARUCAM_CMD_INIT */
+void marucam_device_init(MaruCamState *state)
+{
+    g_state = state;
+}
+
+void marucam_device_exit(MaruCamState *state)
+{
+}
+
+/* MARUCAM_CMD_OPEN */
+void marucam_device_open(MaruCamState *state)
+{
+    HRESULT hr;
+    uint32_t dwHeight, dwWidth, dwDstFmt;
+    MaruCamParam *param = state->param;
+    param->top = 0;
+
+    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+    if (FAILED(hr)) {
+        ERR("CoInitailizeEx\n");
+        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
+        param->errCode = EINVAL;
+        return;
+    }
+
+    hr = GraphBuilder_Init();
+    if (FAILED(hr)) {
+        ERR("GraphBuilder_Init\n");
+        DisconnectPins();
+        RemoveFilters();
+        CloseInterfaces();
+        CoUninitialize();
+        param->errCode = EINVAL;
+        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
+        return;
+    }
+
+    hr = BindSourceFilter();
+    if (FAILED(hr)) {
+        ERR("BindSourceFilter\n");
+        DisconnectPins();
+        RemoveFilters();
+        CloseInterfaces();
+        CoUninitialize();
+        param->errCode = EINVAL;
+        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
+        return;
+    }
+
+    hr = BindTargetFilter();
+    if (FAILED(hr)) {
+        ERR("BindTargetFilter\n");
+        DisconnectPins();
+        RemoveFilters();
+        CloseInterfaces();
+        CoUninitialize();
+        param->errCode = EINVAL;
+        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
+        return;
+    }
+
+    hr = ConnectFilters();
+    if (FAILED(hr)) {
+        ERR("ConnectFilters\n");
+        DisconnectPins();
+        RemoveFilters();
+        CloseInterfaces();
+        CoUninitialize();
+        param->errCode = EINVAL;
+        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
+        return;
+    }
+
+    cur_frame_idx = 0;
+    cur_fmt_idx = 0;
+
+    dwHeight = supported_dst_frames[cur_frame_idx].height;
+    dwWidth = supported_dst_frames[cur_frame_idx].width;
+    dwDstFmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
+    hr = SetFormat(dwWidth, dwHeight, dwDstFmt, &g_dwSrcFmt);
+    if (hr != S_OK) {
+        ERR("failed to Set default values\n");
+        DisconnectPins();
+        RemoveFilters();
+        CloseInterfaces();
+        CoUninitialize();
+        param->errCode = EINVAL;
+        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
+        return;
+    }
+
+    INFO("Opened\n");
+    return;
+}
+
+/* MARUCAM_CMD_CLOSE */
+void marucam_device_close(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+    param->top = 0;
+
+    DisconnectPins();
+    RemoveFilters();
+    CloseInterfaces();
+    CoUninitialize();
+    INFO("Closed\n");
+}
+
+/* MARUCAM_CMD_START_PREVIEW */
+void marucam_device_start_preview(MaruCamState *state)
+{
+    HRESULT hr;
+    uint32_t pixfmt, width, height;
+    MaruCamParam *param = state->param;
+    param->top = 0;
+
+    ready_count = 0;
+    width = supported_dst_frames[cur_frame_idx].width;
+    height = supported_dst_frames[cur_frame_idx].height;
+    pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
+    state->buf_size = get_sizeimage(pixfmt, width, height);
+
+    INFO("Pixfmt(%c%c%c%c), W:H(%d:%d), buf size(%u)\n",
+         (char)(pixfmt), (char)(pixfmt >> 8),
+         (char)(pixfmt >> 16), (char)(pixfmt >> 24),
+         width, height, state->buf_size);
+    INFO("Starting preview\n");
+
+    assert(g_pCallback != NULL);
+    hr = ((HWCInPin *)g_pInputPin)->SetGrabCallbackIF(g_pInputPin,
+                                                       g_pCallback);
+    if (FAILED(hr)) {
+        ERR("Failed to set IGrabCallback interface.\n");
+        param->errCode = EINVAL;
+        return;
+    }
+
+    if (grab_buf) {
+        g_free(grab_buf);
+        grab_buf = NULL;
+    }
+    grab_buf = (void *)g_malloc0(state->buf_size);
+    if (grab_buf == NULL) {
+        param->errCode = ENOMEM;
+        return;
+    }
+
+    hr = g_pMediaControl->lpVtbl->Run(g_pMediaControl);
+    if (FAILED(hr)) {
+        ERR("Failed to run media control. hr=0x%x\n", hr);
+        param->errCode = EINVAL;
+        return;
+    }
+
+    qemu_mutex_lock(&state->thread_mutex);
+    state->streamon = 1;
+    qemu_mutex_unlock(&state->thread_mutex);
+
+    INFO("Streaming on ......\n");
+}
+
+/* MARUCAM_CMD_STOP_PREVIEW */
+void marucam_device_stop_preview(MaruCamState *state)
+{
+    HRESULT hr;
+    MaruCamParam *param = state->param;
+    param->top = 0;
+
+    INFO("...... Streaming off\n");
+    qemu_mutex_lock(&state->thread_mutex);
+    state->streamon = 0;
+    qemu_mutex_unlock(&state->thread_mutex);
+
+    hr = ((HWCInPin *)g_pInputPin)->SetGrabCallbackIF(g_pInputPin, NULL);
+    if (FAILED(hr)) {
+        ERR("Failed to set IGrabCallback interface.\n");
+        param->errCode = EINVAL;
+        return;
+    }
+
+    hr = g_pMediaControl->lpVtbl->Stop(g_pMediaControl);
+    if (FAILED(hr)) {
+        ERR("Failed to stop media control.\n");
+        param->errCode = EINVAL;
+        return;
+    }
+
+    if (grab_buf) {
+        g_free(grab_buf);
+        grab_buf = NULL;
+    }
+    state->buf_size = 0;
+
+    INFO("Stopping preview\n");
+}
+
+/* MARUCAM_CMD_S_PARAM */
+void marucam_device_s_param(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+
+    /* We use default FPS of the webcam */
+    param->top = 0;
+}
+
+/* MARUCAM_CMD_G_PARAM */
+void marucam_device_g_param(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+
+    /* We use default FPS of the webcam
+     * return a fixed value on guest ini file (1/30).
+     */
+    param->top = 0;
+    param->stack[0] = 0x1000; /* V4L2_CAP_TIMEPERFRAME */
+    param->stack[1] = 1; /* numerator */
+    param->stack[2] = 30; /* denominator */
+}
+
+/* MARUCAM_CMD_S_FMT */
+void marucam_device_s_fmt(MaruCamState *state)
+{
+    uint32_t width, height, pixfmt, pidx, fidx;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    width = param->stack[0];
+    height = param->stack[1];
+    pixfmt = param->stack[2];
+
+    for (fidx = 0; fidx < ARRAY_SIZE(supported_dst_frames); fidx++) {
+        if ((supported_dst_frames[fidx].width == width) &&
+                (supported_dst_frames[fidx].height == height)) {
+            break;
+        }
+    }
+    if (fidx == ARRAY_SIZE(supported_dst_frames)) {
+        param->errCode = EINVAL;
+        return;
+    }
+    for (pidx = 0; pidx < ARRAY_SIZE(supported_dst_pixfmts); pidx++) {
+        if (supported_dst_pixfmts[pidx].fmt == pixfmt) {
+            break;
+        }
+    }
+    if (pidx == ARRAY_SIZE(supported_dst_pixfmts)) {
+        param->errCode = EINVAL;
+        return;
+    }
+
+    if ((supported_dst_frames[cur_frame_idx].width != width) &&
+            (supported_dst_frames[cur_frame_idx].height != height)) {
+        HRESULT hr = SetFormat(width, height, pixfmt, &g_dwSrcFmt);
+        if (FAILED(hr)) {
+            param->errCode = EINVAL;
+            return;
+        }
+    }
+
+    cur_frame_idx = fidx;
+    cur_fmt_idx = pidx;
+
+    pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
+    width = supported_dst_frames[cur_frame_idx].width;
+    height = supported_dst_frames[cur_frame_idx].height;
+
+    param->stack[0] = width;
+    param->stack[1] = height;
+    param->stack[2] = 1; /* V4L2_FIELD_NONE */
+    param->stack[3] = pixfmt;
+    param->stack[4] = get_bytesperline(pixfmt, width);
+    param->stack[5] = get_sizeimage(pixfmt, width, height);
+    param->stack[6] = 0;
+    param->stack[7] = 0;
+
+    TRACE("Set format...\n");
+}
+
+/* MARUCAM_CMD_G_FMT */
+void marucam_device_g_fmt(MaruCamState *state)
+{
+    uint32_t width, height, pixfmt;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
+    width = supported_dst_frames[cur_frame_idx].width;
+    height = supported_dst_frames[cur_frame_idx].height;
+
+    param->stack[0] = width;
+    param->stack[1] = height;
+    param->stack[2] = 1; /* V4L2_FIELD_NONE */
+    param->stack[3] = pixfmt;
+    param->stack[4] = get_bytesperline(pixfmt, width);
+    param->stack[5] = get_sizeimage(pixfmt, width, height);
+    param->stack[6] = 0;
+    param->stack[7] = 0;
+
+    TRACE("Get format...\n");
+}
+
+void marucam_device_try_fmt(MaruCamState *state)
+{
+    uint32_t width, height, pixfmt, i;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    width = param->stack[0];
+    height = param->stack[1];
+    pixfmt = param->stack[2];
+
+    for (i = 0; i < ARRAY_SIZE(supported_dst_frames); i++) {
+        if ((supported_dst_frames[i].width == width) &&
+                (supported_dst_frames[i].height == height)) {
+            break;
+        }
+    }
+    if (i == ARRAY_SIZE(supported_dst_frames)) {
+        param->errCode = EINVAL;
+        return;
+    }
+    for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) {
+        if (supported_dst_pixfmts[i].fmt == pixfmt) {
+            break;
+        }
+    }
+    if (i == ARRAY_SIZE(supported_dst_pixfmts)) {
+        param->errCode = EINVAL;
+        return;
+    }
+
+    param->stack[0] = width;
+    param->stack[1] = height;
+    param->stack[2] = 1; /* V4L2_FIELD_NONE */
+    param->stack[3] = pixfmt;
+    param->stack[4] = get_bytesperline(pixfmt, width);
+    param->stack[5] = get_sizeimage(pixfmt, width, height);
+    param->stack[6] = 0;
+    param->stack[7] = 0;
+}
+
+void marucam_device_enum_fmt(MaruCamState *state)
+{
+    uint32_t index;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    index = param->stack[0];
+
+    if (index >= ARRAY_SIZE(supported_dst_pixfmts)) {
+        param->errCode = EINVAL;
+        return;
+    }
+    param->stack[1] = 0; /* flags = NONE */
+    param->stack[2] = supported_dst_pixfmts[index].fmt; /* pixelformat */
+    /* set description */
+    switch (supported_dst_pixfmts[index].fmt) {
+    case V4L2_PIX_FMT_YUYV:
+        memcpy(&param->stack[3], "YUYV", 32);
+        break;
+    case V4L2_PIX_FMT_YUV420:
+        memcpy(&param->stack[3], "YU12", 32);
+        break;
+    case V4L2_PIX_FMT_YVU420:
+        memcpy(&param->stack[3], "YV12", 32);
+        break;
+    default:
+        ERR("Invalid pixel format\n");
+        param->errCode = EINVAL;
+        break;
+    }
+}
+
+void marucam_device_qctrl(MaruCamState *state)
+{
+    HRESULT hr;
+    uint32_t id, i;
+    long property, min, max, step, def_val, set_val;
+    char name[32] = {0,};
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    id = param->stack[0];
+
+    switch (id) {
+    case V4L2_CID_BRIGHTNESS:
+        TRACE("V4L2_CID_BRIGHTNESS\n");
+        property = VideoProcAmp_Brightness;
+        memcpy((void *)name, (void *)"brightness", 32);
+        i = 0;
+        break;
+    case V4L2_CID_CONTRAST:
+        TRACE("V4L2_CID_CONTRAST\n");
+        property = VideoProcAmp_Contrast;
+        memcpy((void *)name, (void *)"contrast", 32);
+        i = 1;
+        break;
+    case V4L2_CID_SATURATION:
+        TRACE("V4L2_CID_SATURATION\n");
+        property = VideoProcAmp_Saturation;
+        memcpy((void *)name, (void *)"saturation", 32);
+        i = 2;
+        break;
+    case V4L2_CID_SHARPNESS:
+        TRACE("V4L2_CID_SHARPNESS\n");
+        property = VideoProcAmp_Sharpness;
+        memcpy((void *)name, (void *)"sharpness", 32);
+        i = 3;
+        break;
+    default:
+        ERR("Invalid control ID\n");
+        param->errCode = EINVAL;
+        return;
+    }
+    hr = QueryVideoProcAmp(property, &min, &max, &step, &def_val);
+    if (FAILED(hr)) {
+        param->errCode = EINVAL;
+        ERR("failed to query video controls [HRESULT : 0x%x]\n", hr);
+        return;
+    } else {
+        qctrl_tbl[i].hit = 1;
+        qctrl_tbl[i].min = min;
+        qctrl_tbl[i].max = max;
+        qctrl_tbl[i].step = step;
+        qctrl_tbl[i].init_val = def_val;
+
+        if ((qctrl_tbl[i].min + qctrl_tbl[i].max) == 0) {
+            set_val = 0;
+        } else {
+            set_val = (qctrl_tbl[i].min + qctrl_tbl[i].max) / 2;
+        }
+        hr = SetVideoProcAmp(property, set_val);
+        if (FAILED(hr)) {
+            param->errCode = EINVAL;
+            ERR("failed to set video control value, [HRESULT : 0x%x]\n", hr);
+            return;
+        }
+    }
+
+    param->stack[0] = id;
+    param->stack[1] = MARUCAM_CTRL_VALUE_MIN;  /* minimum */
+    param->stack[2] = MARUCAM_CTRL_VALUE_MAX;  /* maximum */
+    param->stack[3] = MARUCAM_CTRL_VALUE_STEP; /*  step   */
+    param->stack[4] = MARUCAM_CTRL_VALUE_MID;  /* default_value */
+    param->stack[5] = V4L2_CTRL_FLAG_SLIDER;
+    /* name field setting */
+    memcpy(&param->stack[6], (void *)name, sizeof(name)/sizeof(name[0]));
+}
+
+void marucam_device_s_ctrl(MaruCamState *state)
+{
+    HRESULT hr;
+    uint32_t i;
+    long property, set_val;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+
+    switch (param->stack[0]) {
+    case V4L2_CID_BRIGHTNESS:
+        i = 0;
+        property = VideoProcAmp_Brightness;
+        break;
+    case V4L2_CID_CONTRAST:
+        i = 1;
+        property = VideoProcAmp_Contrast;
+        break;
+    case V4L2_CID_SATURATION:
+        i = 2;
+        property = VideoProcAmp_Saturation;
+        break;
+    case V4L2_CID_SHARPNESS:
+        i = 3;
+        property = VideoProcAmp_Sharpness;
+        break;
+    default:
+        param->errCode = EINVAL;
+        return;
+    }
+    set_val = value_convert_from_guest(qctrl_tbl[i].min,
+            qctrl_tbl[i].max, (long)param->stack[1]);
+    hr = SetVideoProcAmp(property, set_val);
+    if (FAILED(hr)) {
+        param->errCode = EINVAL;
+        ERR("failed to set video control value, [HRESULT : 0x%x]\n", hr);
+        return;
+    }
+}
+
+void marucam_device_g_ctrl(MaruCamState *state)
+{
+    HRESULT hr;
+    uint32_t i;
+    long property, get_val;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    switch (param->stack[0]) {
+    case V4L2_CID_BRIGHTNESS:
+        i = 0;
+        property = VideoProcAmp_Brightness;
+        break;
+    case V4L2_CID_CONTRAST:
+        i = 1;
+        property = VideoProcAmp_Contrast;
+        break;
+    case V4L2_CID_SATURATION:
+        i = 2;
+        property = VideoProcAmp_Saturation;
+        break;
+    case V4L2_CID_SHARPNESS:
+        i = 3;
+        property = VideoProcAmp_Sharpness;
+        break;
+    default:
+        param->errCode = EINVAL;
+        return;
+    }
+
+    hr = GetVideoProcAmp(property, &get_val);
+    if (FAILED(hr)) {
+        param->errCode = EINVAL;
+        ERR("failed to get video control value!!!, [HRESULT : 0x%x]\n", hr);
+        return;
+    }
+    param->stack[0] = (uint32_t)value_convert_to_guest(qctrl_tbl[i].min,
+                qctrl_tbl[i].max, get_val);
+}
+
+void marucam_device_enum_fsizes(MaruCamState *state)
+{
+    uint32_t index, pixfmt, i;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    index = param->stack[0];
+    pixfmt = param->stack[1];
+
+    if (index >= ARRAY_SIZE(supported_dst_frames)) {
+        param->errCode = EINVAL;
+        return;
+    }
+    for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) {
+        if (supported_dst_pixfmts[i].fmt == pixfmt) {
+            break;
+        }
+    }
+
+    if (i == ARRAY_SIZE(supported_dst_pixfmts)) {
+        param->errCode = EINVAL;
+        return;
+    }
+
+    param->stack[0] = supported_dst_frames[index].width;
+    param->stack[1] = supported_dst_frames[index].height;
+}
+
+void marucam_device_enum_fintv(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+
+    /* switch by index(param->stack[0]) */
+    switch (param->stack[0]) {
+    case 0:
+        param->stack[1] = 30; /* denominator */
+        break;
+    default:
+        param->errCode = EINVAL;
+        return;
+    }
+    param->stack[0] = 1; /* numerator */
+}
+
+void yuyv_to_yuv420(const unsigned char *src, unsigned char *dest,
+        uint32_t width, uint32_t height, uint32_t yvu)
+{
+    uint32_t i, j;
+    const unsigned char *src1;
+    unsigned char *udest, *vdest;
+
+    /* copy the Y values */
+    src1 = src;
+    for (i = 0; i < height; i++) {
+        for (j = 0; j < width; j += 2) {
+            *dest++ = src1[0];
+            *dest++ = src1[2];
+            src1 += 4;
+        }
+    }
+
+    /* copy the U and V values */
+    src++;              /* point to V */
+    src1 = src + width * 2;     /* next line */
+    if (yvu) {
+        vdest = dest;
+        udest = dest + width * height / 4;
+    } else {
+        udest = dest;
+        vdest = dest + width * height / 4;
+    }
+    for (i = 0; i < height; i += 2) {
+        for (j = 0; j < width; j += 2) {
+            *udest++ = ((int) src[0] + src1[0]) / 2;    /* U */
+            *vdest++ = ((int) src[2] + src1[2]) / 2;    /* V */
+            src += 4;
+            src1 += 4;
+        }
+        src = src1;
+        src1 += width * 2;
+    }
+}
+
+#define RGB2Y(r, g, b, y)   \
+    (y) = ((8453 * (r) + 16594 * (g) + 3223 * (b) + 524288) >> 15)
+
+#define RGB2UV(r, g, b, u, v)   \
+    do {    \
+        (u) = ((-4878 * (r) - 9578 * (g) + 14456 * (b) + 4210688) >> 15);   \
+        (v) = ((14456 * (r) - 12105 * (g) - 2351 * (b) + 4210688) >> 15);   \
+    } while (0)
+
+#define CLIP(color) \
+    (unsigned char)(((color) > 0xFF) ? 0xff : (((color) < 0) ? 0 : (color)))
+
+void rgb24_to_yuv420(const unsigned char *src, unsigned char *dest,
+                     uint32_t width, uint32_t height, uint32_t yvu)
+{
+    uint32_t x, y;
+    unsigned char *udest, *vdest;
+    uint32_t bytesperline = width * 3;
+
+    /* Y */
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x++) {
+            RGB2Y(src[2], src[1], src[0], *dest++);
+            src += 3;
+        }
+        src += bytesperline - 3 * width;
+    }
+    src -= height * bytesperline;
+
+    /* U + V */
+    if (yvu) {
+        vdest = dest;
+        udest = dest + width * height / 4;
+    } else {
+        udest = dest;
+        vdest = dest + width * height / 4;
+    }
+
+    for (y = 0; y < height / 2; y++) {
+        for (x = 0; x < width / 2; x++) {
+            uint32_t avg_src[3];
+
+            avg_src[0] = (src[0] + src[3] + src[bytesperline] +
+                    src[bytesperline + 3]) / 4;
+            avg_src[1] = (src[1] + src[4] + src[bytesperline + 1] +
+                    src[bytesperline + 4]) / 4;
+            avg_src[2] = (src[2] + src[5] + src[bytesperline + 2] +
+                    src[bytesperline + 5]) / 4;
+            RGB2UV(avg_src[2], avg_src[1], avg_src[0], *udest++, *vdest++);
+            src += 6;
+        }
+        src += 2 * bytesperline - 3 * width;
+    }
+}
+
+void rgb24_to_yuyv(unsigned char *src, unsigned char *dest,
+                   uint32_t width, uint32_t height)
+{
+    uint32_t i = 0;
+
+    for (i = 0; i < (width * height * 3); i = i + 6) {
+        /* y */
+        *dest++ = CLIP(0.299 * (src[i + 2] - 128) +
+                    0.587 * (src[i + 1] - 128) +
+                    0.114 * (src[i] - 128) + 128);
+        /* u */
+        *dest++ = CLIP(((-0.147 * (src[i + 2] - 128) -
+                    0.289 * (src[i + 1] - 128) +
+                    0.436 * (src[i] - 128) + 128) +
+                    (-0.147 * (src[i + 5] - 128) -
+                    0.289 * (src[i + 4] - 128) +
+                    0.436 * (src[i + 3] - 128) + 128)) / 2);
+        /* y1 */
+        *dest++ = CLIP(0.299 * (src[i + 5] - 128) +
+                    0.587 * (src[i + 4] - 128) +
+                    0.114 * (src[i + 3] - 128) + 128);
+        /* v */
+        *dest++ = CLIP(((0.615 * (src[i + 2] - 128) -
+                    0.515 * (src[i + 1] - 128) -
+                    0.100 * (src[i] - 128) + 128) +
+                    (0.615 * (src[i + 5] - 128) -
+                    0.515 * (src[i + 4] - 128) -
+                    0.100 * (src[i + 3] - 128) + 128)) / 2);
+    }
+}
+
+void yuv420_to_yvu420(unsigned char *src, unsigned char *dest,
+                      uint32_t width, uint32_t height)
+{
+    unsigned char *psrc_y, *pdst_y;
+    unsigned char *psrc_u, *pdst_u;
+    unsigned char *psrc_v, *pdst_v;
+
+    psrc_y = src;
+    psrc_u = psrc_y + (width * height);
+    psrc_v = psrc_u + (width * height / 4);
+
+    pdst_y = dest;
+    pdst_v = pdst_y + (width * height);
+    pdst_u = pdst_v + (width * height / 4);
+
+    memcpy(pdst_y, psrc_y, width * height);
+    memcpy(pdst_v, psrc_v, width * height / 4);
+    memcpy(pdst_u, psrc_u, width * height / 4);
+}
+
+void yuv420_to_yuyv(unsigned char *src, unsigned char *dest,
+                    uint32_t width, uint32_t height)
+{
+    unsigned char *py;
+    unsigned char *pu;
+    unsigned char *pv;
+
+    uint32_t linesize = width * 2;
+    uint32_t uvlinesize = width / 2;
+    uint32_t offset = 0;
+    uint32_t offset1 = 0;
+    uint32_t offsety = 0;
+    uint32_t offsety1 = 0;
+    uint32_t offsetuv = 0;
+    uint32_t h = 0;
+    uint32_t w = 0;
+    uint32_t wy = 0;
+    uint32_t huv = 0;
+    uint32_t wuv = 0;
+
+    py = src;
+    pu = py + (width * height);
+    pv = pu + (width * height / 4);
+
+    for (h = 0; h < height; h += 2) {
+        wy = 0;
+        wuv = 0;
+        offset = h * linesize;
+        offset1 = (h + 1) * linesize;
+        offsety = h * width;
+        offsety1 = (h + 1) * width;
+        offsetuv = huv * uvlinesize;
+
+        for (w = 0; w < linesize; w += 4) {
+            /* y00 */
+            dest[w + offset] = py[wy + offsety];
+            /* u0 */
+            dest[(w + 1) + offset] = pu[wuv + offsetuv];
+            /* y01 */
+            dest[(w + 2) + offset] = py[(wy + 1) + offsety];
+            /* v0 */
+            dest[(w + 3) + offset] = pv[wuv + offsetuv];
+
+            /* y10 */
+            dest[w + offset1] = py[wy + offsety1];
+            /* u0 */
+            dest[(w + 1) + offset1] = pu[wuv + offsetuv];
+            /* y11 */
+            dest[(w + 2) + offset1] = py[(wy + 1) + offsety1];
+            /* v0 */
+            dest[(w + 3) + offset1] = pv[wuv + offsetuv];
+
+            wuv++;
+            wy += 2;
+        }
+        huv++;
+    }
+}
index 0fc77de..8a2a0bd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Maru Device IDs
  *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Contact:
  * SeokYeon Hwang <syeon.hwang@samsung.com>
@@ -49,8 +49,9 @@
 #define PCI_DEVICE_ID_VIRTUAL_CODEC      0x101C
 /* Device ID 0x1000 through 0x103F inclusive is a virtio device */
 #define PCI_DEVICE_ID_VIRTIO_TOUCHSCREEN 0x101D
-#define PCI_DEVICE_ID_VIRTIO_KEYBOARD   0x1020
+#define PCI_DEVICE_ID_VIRTIO_KEYBOARD    0x1020
 #define PCI_DEVICE_ID_VIRTIO_ESM         0x1024
+#define PCI_DEVICE_ID_VIRTIO_HWKEY       0x1028
 
 /* Virtio */
 /*
@@ -82,5 +83,6 @@
 #define VIRTIO_ID_TOUCHSCREEN   11
 #define VIRTIO_ID_KEYBOARD      12
 #define VIRTIO_ID_ESM           13
+#define VIRTIO_ID_HWKEY         14
 
 #endif /* MARU_DEVICE_IDS_H_ */
index 43194b4..7072f58 100644 (file)
@@ -1,17 +1,10 @@
-/* 
+/*
  * Maru overlay device for VGA
  *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
- * Contact: 
- * SeokYeon Hwang <syeon.hwang@samsung.com>
- * SangJin Kim <sangjin3.kim@samsung.com>
- * MunKyu Im <munkyu.im@samsung.com>
- * KiTae Kim <kt920.kim@samsung.com>
+ * Contact:
  * JinHyung Jo <jinhyung.jo@samsung.com>
- * SungMin Ha <sungmin82.ha@samsung.com>
- * JiHye Kim <jihye1128.kim@samsung.com>
- * GiWoong Kim <giwoong.kim@samsung.com>
  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
  * DongKyun Yun
  * DoHyung Hong
  *
  * 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.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
  *
  * Contributors:
  * - S-Core Co., Ltd
  *
  */
+
 #include "pc.h"
 #include "pci.h"
 #include "maru_device_ids.h"
 
 MULTI_DEBUG_CHANNEL(qemu, maru_overlay);
 
-#define QEMU_DEV_NAME           "MARU_OVERLAY"
+#define QEMU_DEV_NAME       "MARU_OVERLAY"
 
-#define OVERLAY_MEM_SIZE       (8192 * 1024)   // 4MB(overlay0) + 4MB(overlay1)
-#define OVERLAY_REG_SIZE       256
-#define OVERLAY1_REG_OFFSET    (OVERLAY_REG_SIZE / 2)
+#define OVERLAY_MEM_SIZE    (8192 * 1024)   /* 4MB(overlay0) + 4MB(overlay1) */
+#define OVERLAY_REG_SIZE    256
+#define OVERLAY1_REG_OFFSET (OVERLAY_REG_SIZE / 2)
 
 
 enum {
-       OVERLAY_POWER    = 0x00,
-       OVERLAY_POSITION = 0x04,        // left top position
-       OVERLAY_SIZE     = 0x08,        // width and height
+    OVERLAY_POWER    = 0x00,
+    OVERLAY_POSITION = 0x04,    /* left top position */
+    OVERLAY_SIZE     = 0x08,    /* width and height */
 };
 
-uint8_toverlay_ptr;
+uint8_t *overlay_ptr;
 
 uint8_t overlay0_power;
 uint16_t overlay0_left;
@@ -75,11 +70,12 @@ typedef struct OverlayState {
 
     MemoryRegion    mem_addr;
     MemoryRegion    mmio_addr;
-
 } OverlayState;
 
 
-static uint64_t overlay_reg_read(void *opaque, target_phys_addr_t addr, unsigned size)
+static uint64_t overlay_reg_read(void *opaque,
+                                 target_phys_addr_t addr,
+                                 unsigned size)
 {
     switch (addr) {
     case OVERLAY_POWER:
@@ -118,7 +114,10 @@ static uint64_t overlay_reg_read(void *opaque, target_phys_addr_t addr, unsigned
     return 0;
 }
 
-static void overlay_reg_write(void *opaque, target_phys_addr_t addr, uint64_t val, unsigned size)
+static void overlay_reg_write(void *opaque,
+                              target_phys_addr_t addr,
+                              uint64_t val,
+                              unsigned size)
 {
     switch (addr) {
     case OVERLAY_POWER:
@@ -190,7 +189,10 @@ static int overlay_initfn(PCIDevice *dev)
     memory_region_init_ram(&s->mem_addr, "maru_overlay.ram", OVERLAY_MEM_SIZE);
     overlay_ptr = memory_region_get_ram_ptr(&s->mem_addr);
 
-    memory_region_init_io (&s->mmio_addr, &overlay_mmio_ops, s, "maru_overlay_mmio", OVERLAY_REG_SIZE);
+    memory_region_init_io(&s->mmio_addr, &overlay_mmio_ops,
+                          s,
+                          "maru_overlay_mmio",
+                          OVERLAY_REG_SIZE);
 
     /* setup memory space */
     /* memory #0 device memory (overlay surface) */
index 673e0d6..24a4529 100644 (file)
@@ -1,17 +1,10 @@
 /*
  * Maru overlay device for VGA
  *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Contact:
- * SeokYeon Hwang <syeon.hwang@samsung.com>
- * SangJin Kim <sangjin3.kim@samsung.com>
- * MunKyu Im <munkyu.im@samsung.com>
- * KiTae Kim <kt920.kim@samsung.com>
  * JinHyung Jo <jinhyung.jo@samsung.com>
- * SungMin Ha <sungmin82.ha@samsung.com>
- * JiHye Kim <jihye1128.kim@samsung.com>
- * GiWoong Kim <giwoong.kim@samsung.com>
  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
  * DoHyung Hong
  * Hyunjun Son
@@ -28,7 +21,8 @@
  *
  * 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.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
  *
  * Contributors:
  * - S-Core Co., Ltd
@@ -41,7 +35,7 @@
 
 #include "qemu-common.h"
 
-extern uint8_toverlay_ptr;
+extern uint8_t *overlay_ptr;
 extern uint8_t overlay0_power;
 extern uint16_t overlay0_left;
 extern uint16_t overlay0_top;
@@ -54,6 +48,6 @@ extern uint16_t overlay1_top;
 extern uint16_t overlay1_width;
 extern uint16_t overlay1_height;
 
-DeviceState *pci_maru_overlay_init( PCIBus *bus );
+DeviceState *pci_maru_overlay_init(PCIBus *bus);
 
 #endif /* MARU_OVERLAY_H_ */
index 144cfbd..fbb7f81 100644 (file)
@@ -2,7 +2,7 @@
  * Maru vga device
  * Based on qemu/hw/vga.c
  *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Contact:
  * GiWoong Kim <giwoong.kim@samsung.com>
 #include <sys/ipc.h>
 #include <sys/shm.h>
 #include "maru_err_table.h"
+#include "emul_state.h"
 #endif
 
 #ifdef CONFIG_USE_SHM
 void *shared_memory = (void*) 0;
-int shmid;
+int skin_shmid;
 #endif
 
 
@@ -1872,37 +1873,23 @@ void maru_vga_common_init(VGACommonState *s)
     vga_dirty_log_start(s);
 
 #ifdef CONFIG_USE_SHM
-    int mykey;
-    void *temp;
-
-    shmid = shmget((key_t)SHMKEY, (size_t)MAXLEN, 0666 | IPC_CREAT);
-    if (shmid == -1) {
-        ERR("shmget failed\n");
-        perror("maru_vga: ");
-        exit(1);
-    }
-
-    temp = shmat(shmid, (char*)0x0, 0);
-    if (temp == (void *)-1) {
-        ERR("shmat failed\n");
-        perror("maru_vga: ");
-        exit(1);
-    }
+    /* base + 1 = sdb port */
+    /* base + 2 = shared memory key */
+    int mykey = get_emul_vm_base_port() + 2;
 
-    mykey = atoi(temp);
-    shmdt(temp);
     INFO("shared memory key: %d, vga ram_size : %d\n", mykey, s->vram_size);
 
-    shmid = shmget((key_t)mykey, (size_t)s->vram_size, 0666 | IPC_CREAT);
-    if (shmid == -1) {
+    skin_shmid = shmget((key_t)mykey, (size_t)s->vram_size, 0666 | IPC_CREAT);
+    if (skin_shmid == -1) {
         ERR("shmget failed\n");
         perror("maru_vga: ");
-        maru_register_exit_msg(MARU_EXIT_UNKNOWN, (char*)"Cannot launch this VM.\n"
-                        "Shared memory is not enough.");
+        maru_register_exit_msg(MARU_EXIT_UNKNOWN,
+            (char*) "Cannot launch this VM.\n"
+            "Shared memory is not enough.");
         exit(0);
     }
 
-    shared_memory = shmat(shmid, (void*)0, 0);
+    shared_memory = shmat(skin_shmid, (void*)0, 0);
     if (shared_memory == (void *)-1) {
         ERR("shmat failed\n");
         perror("maru_vga: ");
@@ -1923,7 +1910,7 @@ void maru_vga_common_fini(void)
         perror("maru_vga: ");
     }
 
-    if (shmctl(shmid, IPC_RMID, 0) == -1) {
+    if (shmctl(skin_shmid, IPC_RMID, 0) == -1) {
         ERR("shmctl failed\n");
         perror("maru_vga: ");
     }
diff --git a/tizen/src/hw/maru_virtio_hwkey.c b/tizen/src/hw/maru_virtio_hwkey.c
new file mode 100644 (file)
index 0000000..29f541b
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * Maru Virtio HW Key Device
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  GiWoong Kim <giwoong.kim@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 <pthread.h>
+#include "console.h"
+#include "emul_state.h"
+#include "maru_virtio_hwkey.h"
+#include "maru_device_ids.h"
+#include "debug_ch.h"
+
+MULTI_DEBUG_CHANNEL(qemu, hwkey);
+
+#define DEVICE_NAME "virtio-hwkey"
+
+/*
+ * HW key event queue
+ */
+typedef struct HwKeyEventEntry {
+    unsigned int index;
+    EmulHwKeyEvent hwkey;
+
+    QTAILQ_ENTRY(HwKeyEventEntry) node;
+} HwKeyEventEntry;
+
+/* the maximum number of HW key event that can be put into a queue */
+#define MAX_HWKEY_EVENT_CNT 64
+
+static HwKeyEventEntry _events_buf[MAX_HWKEY_EVENT_CNT];
+static QTAILQ_HEAD(, HwKeyEventEntry) events_queue =
+    QTAILQ_HEAD_INITIALIZER(events_queue);
+
+static unsigned int event_ringbuf_cnt; /* _events_buf */
+static unsigned int event_queue_cnt; /* events_queue */
+
+/*
+ * VirtQueueElement queue
+ */
+typedef struct ElementEntry {
+    unsigned int el_index;
+    unsigned int sg_index;
+    VirtQueueElement elem;
+
+    QTAILQ_ENTRY(ElementEntry) node;
+} ElementEntry;
+
+static ElementEntry _elem_buf[10];
+static QTAILQ_HEAD(, ElementEntry) elem_queue =
+    QTAILQ_HEAD_INITIALIZER(elem_queue);
+
+static unsigned int elem_ringbuf_cnt; /* _elem_buf */
+static unsigned int elem_queue_cnt; /* elem_queue */
+
+VirtIOHwKey *vhk;
+
+/* lock for between communication thread and IO thread */
+static pthread_mutex_t event_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t elem_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+void maru_hwkey_event(int event_type, int keycode)
+{
+    HwKeyEventEntry *entry = NULL;
+
+    if (unlikely(event_queue_cnt >= MAX_HWKEY_EVENT_CNT)) {
+        INFO("full hwkey event queue, lose event\n", event_queue_cnt);
+
+        qemu_bh_schedule(vhk->bh);
+        return;
+    }
+
+    entry = &(_events_buf[event_ringbuf_cnt % MAX_HWKEY_EVENT_CNT]);
+    event_ringbuf_cnt++;
+
+    /* hwkey event is copied into the queue */
+    entry->hwkey.keycode = keycode;
+    entry->hwkey.event_type = event_type;
+
+    pthread_mutex_lock(&event_mutex);
+
+    entry->index = ++event_queue_cnt; // 1 ~
+
+    QTAILQ_INSERT_TAIL(&events_queue, entry, node);
+
+    pthread_mutex_unlock(&event_mutex);
+
+    /* call maru_virtio_hwkey_notify */
+    qemu_bh_schedule(vhk->bh);
+
+    TRACE("hwkey event (%d) : keycode=%d, event_type=%d\n",
+        entry->index, entry->hwkey.keycode, entry->hwkey.event_type);
+}
+
+static void maru_virtio_hwkey_handle(VirtIODevice *vdev, VirtQueue *vq)
+{
+    int virt_sg_index = 0;
+    ElementEntry *elem_entry = NULL;
+
+    TRACE("maru_virtio_hwkey_handle\n");
+
+    if (unlikely(virtio_queue_empty(vhk->vq))) {
+        TRACE("virtqueue is empty\n");
+        return;
+    }
+
+    while (true) {
+        elem_entry = &(_elem_buf[elem_ringbuf_cnt % 10]);
+        elem_ringbuf_cnt++;
+
+        virt_sg_index = virtqueue_pop(vhk->vq, &elem_entry->elem);
+        if (virt_sg_index == 0) {
+            elem_ringbuf_cnt--;
+            break;
+        } else if (virt_sg_index < 0) {
+            ERR("virtqueue is broken\n");
+            elem_ringbuf_cnt--;
+            return;
+        }
+
+        pthread_mutex_lock(&elem_mutex);
+
+        elem_entry->el_index = ++elem_queue_cnt;
+        elem_entry->sg_index = (unsigned int)virt_sg_index;
+
+        /* save VirtQueueElement */
+        QTAILQ_INSERT_TAIL(&elem_queue, elem_entry, node);
+        /* call maru_virtio_hwkey_notify */
+        qemu_bh_schedule(vhk->bh);
+
+        pthread_mutex_unlock(&elem_mutex);
+    }
+}
+
+void maru_virtio_hwkey_notify(void)
+{
+    HwKeyEventEntry *event_entry = NULL;
+    ElementEntry *elem_entry = NULL;
+    VirtQueueElement *element = NULL;
+    void *vbuf = NULL;
+
+    TRACE("maru_virtio_hwkey_notify\n");
+
+    if (unlikely(!virtio_queue_ready(vhk->vq))) {
+        ERR("virtio queue is not ready\n");
+        return;
+    }
+
+    while (true) {
+        if (event_queue_cnt == 0) {
+            TRACE("no event\n");
+            break;
+        }
+
+        elem_entry = QTAILQ_FIRST(&elem_queue);
+
+        if ( elem_entry->sg_index > 0) {
+            /* get hwkey event from host queue */
+            event_entry = QTAILQ_FIRST(&events_queue);
+
+            TRACE("hwkey(%d) : keycode=%d, event_type=%d | \
+              event_queue_cnt=%d\n",
+              event_entry->index,
+              event_entry->hwkey.keycode, event_entry->hwkey.event_type,
+              event_queue_cnt);
+          
+            element = &elem_entry->elem;
+            vbuf = element->in_sg[elem_entry->sg_index - 1].iov_base;
+
+            /* copy event into virtio buffer */
+            memcpy(vbuf, &(event_entry->hwkey), sizeof(EmulHwKeyEvent));
+
+            virtqueue_push(vhk->vq, element, sizeof(EmulHwKeyEvent));
+            virtio_notify(&vhk->vdev, vhk->vq);
+        }
+
+        pthread_mutex_lock(&event_mutex);
+
+        /* remove host event */
+        QTAILQ_REMOVE(&events_queue, event_entry, node);
+        event_queue_cnt--;
+
+        pthread_mutex_unlock(&event_mutex);
+    }
+}
+
+static uint32_t virtio_hwkey_get_features(
+    VirtIODevice *vdev, uint32_t request_features)
+{
+    // TODO:
+    return request_features;
+}
+
+static void maru_hwkey_bh(void *opaque)
+{
+    maru_virtio_hwkey_notify();
+}
+
+VirtIODevice *maru_virtio_hwkey_init(DeviceState *dev)
+{
+    INFO("initialize the hwkey device\n");
+
+    vhk = (VirtIOHwKey *)virtio_common_init(DEVICE_NAME,
+        VIRTIO_ID_HWKEY, 0 /*config_size*/, sizeof(VirtIOHwKey));
+
+    if (vhk == NULL) {
+        ERR("failed to initialize the hwkey device\n");
+        return NULL;
+    }
+
+    vhk->vdev.get_features = virtio_hwkey_get_features;
+    vhk->vq = virtio_add_queue(&vhk->vdev, 64, maru_virtio_hwkey_handle);
+
+    vhk->qdev = dev;
+
+    /* reset the counters */
+    event_queue_cnt = event_ringbuf_cnt = 0;
+    elem_queue_cnt = elem_ringbuf_cnt = 0;
+
+    /* bottom-half */
+    vhk->bh = qemu_bh_new(maru_hwkey_bh, vhk);
+
+    return &(vhk->vdev);
+}
+
+void maru_virtio_hwkey_exit(VirtIODevice *vdev)
+{
+    VirtIOHwKey *vhk = (VirtIOHwKey *)vdev;
+
+    INFO("exit the hwkey device\n");
+
+    if (vhk->bh) {
+        qemu_bh_delete(vhk->bh);
+    }
+
+    virtio_cleanup(vdev);
+
+    pthread_mutex_destroy(&event_mutex);
+}
+
diff --git a/tizen/src/hw/maru_virtio_hwkey.h b/tizen/src/hw/maru_virtio_hwkey.h
new file mode 100644 (file)
index 0000000..d80866a
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Maru Virtio HW Key Device
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  GiWoong Kim <giwoong.kim@samsung.com>
+ *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+
+#ifndef MARU_HWKEY_H_
+#define MARU_HWKEY_H_
+
+#include "console.h"
+#include "hw/virtio.h"
+
+typedef struct VirtIOHwKey
+{
+    VirtIODevice vdev;
+    /* simply a queue into which buffers are posted
+    by the guest for consumption by the host */
+    VirtQueue *vq;
+
+    QEMUBH *bh;
+    DeviceState *qdev;
+} VirtIOHwKey;
+
+/* This structure must match the kernel definitions */
+typedef struct EmulHwKeyEvent {
+    uint8_t event_type;
+    uint32_t keycode;
+} EmulHwKeyEvent;
+
+
+VirtIODevice *maru_virtio_hwkey_init(DeviceState *dev);
+void maru_virtio_hwkey_exit(VirtIODevice *vdev);
+
+void maru_hwkey_event(int event_type, int keycode);
+void maru_virtio_hwkey_notify(void);
+
+#endif /* MARU_HWKEY_H_ */
index e331070..97f4d2a 100644 (file)
@@ -5,6 +5,7 @@
  *
  * Contact:
  *  Kitae Kim <kt920.kim@samsung.com>
+ *  GiWoong Kim <giwoong.kim@samsung.com>
  *  SeokYeon Hwang <syeon.hwang@samsung.com>
  *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>
  *
  *
  */
 
-#include "mloop_event.h"
 #include "maru_device_ids.h"
 #include "maru_virtio_keyboard.h"
 #include "tizen/src/debug_ch.h"
 
+
 MULTI_DEBUG_CHANNEL(qemu, virtio-kbd);
 
 VirtQueueElement elem;
@@ -60,22 +61,13 @@ void virtio_keyboard_notify(void *opaque)
     EmulKbdEvent *kbdevt;
     int index = 0;
     int written_cnt = 0;
-    int *rptr = NULL;
 
     if (!vkbd) {
         ERR("VirtIOKeyboard is NULL.\n");
         return;
     }
 
-    qemu_mutex_lock(&vkbd->event_mutex);
-    written_cnt = vkbd->kbdqueue.wptr;
     TRACE("[Enter] virtqueue notifier. %d\n", written_cnt);
-    qemu_mutex_unlock(&vkbd->event_mutex);
-    if (written_cnt < 0) {
-        TRACE("there is no input data to copy to guest.\n");
-        return;
-    }
-    rptr = &vkbd->kbdqueue.rptr;
 
     if (!virtio_queue_ready(vkbd->vq)) {
         INFO("virtqueue is not ready.\n");
@@ -83,30 +75,32 @@ void virtio_keyboard_notify(void *opaque)
     }
 
     if (vkbd->kbdqueue.rptr == VIRTIO_KBD_QUEUE_SIZE) {
-        *rptr = 0;
+        vkbd->kbdqueue.rptr = 0;
     }
 
+    qemu_mutex_lock(&vkbd->event_mutex);
+    written_cnt = vkbd->kbdqueue.wptr;
+
     while ((written_cnt--)) {
-        index = *rptr;
-        kbdevt = &vkbd->kbdqueue.kbdevent[index];
+        kbdevt = &vkbd->kbdqueue.kbdevent[vkbd->kbdqueue.rptr];
 
         /* Copy keyboard data into guest side. */
-        TRACE("copy: keycode %d, type %d, index %d\n",
+        TRACE("copy: keycode %d, type %d, elem_index %d\n",
             kbdevt->code, kbdevt->type, index);
-        memcpy(elem.in_sg[index].iov_base, kbdevt, sizeof(EmulKbdEvent));
+        memcpy(elem.in_sg[index++].iov_base, kbdevt, sizeof(EmulKbdEvent));
         memset(kbdevt, 0x00, sizeof(EmulKbdEvent));
 
-        qemu_mutex_lock(&vkbd->event_mutex);
         if (vkbd->kbdqueue.wptr > 0) {
             vkbd->kbdqueue.wptr--;
+            TRACE("written_cnt: %d, wptr: %d, qemu_index: %d\n", written_cnt, vkbd->kbdqueue.wptr, vkbd->kbdqueue.rptr);
         }
-        qemu_mutex_unlock(&vkbd->event_mutex);
 
-        (*rptr)++;
-        if (*rptr == VIRTIO_KBD_QUEUE_SIZE) {
-            *rptr = 0;
+        vkbd->kbdqueue.rptr++;
+        if (vkbd->kbdqueue.rptr == VIRTIO_KBD_QUEUE_SIZE) {
+            vkbd->kbdqueue.rptr = 0;
         }
     }
+    qemu_mutex_unlock(&vkbd->event_mutex);
 
     virtqueue_push(vkbd->vq, &elem, sizeof(EmulKbdEvent));
     virtio_notify(&vkbd->vdev, vkbd->vq);
@@ -198,16 +192,17 @@ static void virtio_keyboard_event(void *opaque, int keycode)
         vkbd->extension_key = 1;
     }
 
+    qemu_mutex_lock(&vkbd->event_mutex);
     memcpy(&vkbd->kbdqueue.kbdevent[(*index)++], &kbdevt, sizeof(kbdevt));
     TRACE("event: keycode %d, type %d, index %d.\n",
         kbdevt.code, kbdevt.type, ((*index) - 1));
 
-    qemu_mutex_lock(&vkbd->event_mutex);
     vkbd->kbdqueue.wptr++;
     qemu_mutex_unlock(&vkbd->event_mutex);
 
     TRACE("[Leave] input_event handler. cnt:%d\n", vkbd->kbdqueue.wptr);
-    mloop_evcmd_keyboard(vkbd);
+
+    qemu_bh_schedule(vkbd->bh);
 }
 
 static uint32_t virtio_keyboard_get_features(VirtIODevice *vdev,
@@ -217,6 +212,11 @@ static uint32_t virtio_keyboard_get_features(VirtIODevice *vdev,
     return 0;
 }
 
+static void virtio_keyboard_bh(void *opaque)
+{
+    virtio_keyboard_notify(opaque);
+}
+
 VirtIODevice *virtio_keyboard_init(DeviceState *dev)
 {
     VirtIOKeyboard *vkbd;
@@ -238,6 +238,9 @@ VirtIODevice *virtio_keyboard_init(DeviceState *dev)
     vkbd->vq = virtio_add_queue(&vkbd->vdev, 64, virtio_keyboard_handle);
     vkbd->qdev = dev;
 
+    /* bottom half */
+    vkbd->bh = qemu_bh_new(virtio_keyboard_bh, vkbd);
+
     /* register keyboard handler */
     qemu_add_kbd_event_handler(virtio_keyboard_event, vkbd);
 
@@ -249,6 +252,12 @@ void virtio_keyboard_exit(VirtIODevice *vdev)
     VirtIOKeyboard *vkbd = (VirtIOKeyboard *)vdev;
     INFO("destroy device\n");
 
+    qemu_remove_kbd_event_handler();
+
+    if (vkbd->bh) {
+        qemu_bh_delete(vkbd->bh);
+    }
+
     qemu_mutex_destroy(&vkbd->event_mutex);
 
     virtio_cleanup(vdev);
index 0e06e6a..a744760 100644 (file)
@@ -5,6 +5,7 @@
  *
  * Contact:
  *  Kitae Kim <kt920.kim@samsung.com>
+ *  GiWoong Kim <giwoong.kim@samsung.com>
  *  SeokYeon Hwang <syeon.hwang@samsung.com>
  *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>
  *
@@ -59,6 +60,7 @@ typedef struct VirtIOKeyboard {
 
     VirtIOKbdQueue  kbdqueue;
     QemuMutex       event_mutex;
+    QEMUBH          *bh;
 } VirtIOKeyboard;
 
 VirtIODevice *virtio_keyboard_init(DeviceState *dev);
index 9c08fb7..f5b041b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Maru Virtio Touchscreen Device
  *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Contact:
  *  GiWoong Kim <giwoong.kim@samsung.com>
@@ -31,7 +31,6 @@
 #include "console.h"
 #include "maru_virtio_touchscreen.h"
 #include "maru_device_ids.h"
-#include "mloop_event.h"
 #include "debug_ch.h"
 
 MULTI_DEBUG_CHANNEL(qemu, touchscreen);
@@ -92,7 +91,7 @@ void virtio_touchscreen_event(void *opaque, int x, int y, int z, int buttons_sta
     if (unlikely(event_queue_cnt >= MAX_TOUCH_EVENT_CNT)) {
         INFO("full touch event queue, lose event\n", event_queue_cnt);
 
-        mloop_evcmd_touch();
+        qemu_bh_schedule(ts->bh);
         return;
     }
 
@@ -114,7 +113,7 @@ void virtio_touchscreen_event(void *opaque, int x, int y, int z, int buttons_sta
     pthread_mutex_unlock(&event_mutex);
 
     /* call maru_virtio_touchscreen_notify */
-    mloop_evcmd_touch();
+    qemu_bh_schedule(ts->bh);
 
     TRACE("touch event (%d) : x=%d, y=%d, z=%d, state=%d\n",
         entry->index, entry->touch.x, entry->touch.y, entry->touch.z, entry->touch.state);
@@ -183,7 +182,9 @@ static void maru_virtio_touchscreen_handle(VirtIODevice *vdev, VirtQueue *vq)
 
         if (ts->waitBuf == true) {
             ts->waitBuf = false;
-            mloop_evcmd_touch(); // call maru_virtio_touchscreen_notify
+
+            /* call maru_virtio_touchscreen_notify */
+            qemu_bh_schedule(ts->bh);
         }
 
         pthread_mutex_unlock(&elem_mutex);
@@ -274,6 +275,13 @@ static uint32_t virtio_touchscreen_get_features(
     return request_features;
 }
 
+static void maru_touchscreen_bh(void *opaque)
+{
+    //TouchscreenState *ts = (TouchscreenState *)opaque;
+
+    maru_virtio_touchscreen_notify();
+}
+
 VirtIODevice *maru_virtio_touchscreen_init(DeviceState *dev)
 {
     INFO("initialize the touchscreen device\n");
@@ -297,6 +305,9 @@ VirtIODevice *maru_virtio_touchscreen_init(DeviceState *dev)
 
     ts->waitBuf = false;
 
+    /* bottom halves */
+    ts->bh = qemu_bh_new(maru_touchscreen_bh, ts);
+
 #if 1
     /* register a event handler */
     ts->eh_entry = qemu_add_mouse_event_handler(
@@ -316,6 +327,13 @@ void maru_virtio_touchscreen_exit(VirtIODevice *vdev)
         qemu_remove_mouse_event_handler(ts->eh_entry);
     }
 
+    if (ts->bh) {
+        qemu_bh_delete(ts->bh);
+    }
+
     virtio_cleanup(vdev);
+
+    pthread_mutex_destroy(&event_mutex);
+    pthread_mutex_destroy(&elem_mutex);
 }
 
index ad7756c..b78abad 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Maru Virtual Virtio Touchscreen emulation
+ * Maru Virtio Touchscreen Device
  *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Contact:
  *  GiWoong Kim <giwoong.kim@samsung.com>
@@ -41,6 +41,7 @@ typedef struct TouchscreenState
     VirtQueue *vq;
     bool waitBuf;
 
+    QEMUBH *bh;
     DeviceState *qdev;
     QEMUPutMouseEntry *eh_entry;
 } TouchscreenState;
index db336b3..5085d4a 100644 (file)
@@ -628,17 +628,12 @@ static void unbind_qsurface(GLState *state,
                state->current_qsurface = NULL;
 }
 
-/* Find the qsurface with required drawable in active & pending qsurfaces */
+/* Find the qsurface with required drawable in all pixmap/pbuffer surfaces */
 QGloSurface* find_qsurface_from_client_drawable(ProcessState *process, ClientGLXDrawable client_drawable)
 {
-    /* search for surfaces in current conetxt */
     int i;
-    QGloSurface *qsurface = get_qsurface_from_client_drawable(process->current_state, client_drawable);
-
-    if (qsurface)
-        return qsurface;
+    QGloSurface *qsurface;
 
-    /* search the pending surfaces */
     for ( i = 0; i < process->nb_qsurf; i++ )
     {
         qsurface = process->pending_qsurfaces[i];
@@ -700,14 +695,13 @@ static int link_drawable(ProcessState *process, ClientGLXDrawable drawable)
     return 0;
 }
 
-/* Need to create pixmap surface when guest do so, as guest may use it before
- * MakeCurrent. As no context available at this point, we do the follwoing:
+/* Need to create pixmap/pbuffer surface when guest do so, as guest may use it
+ * before MakeCurrent. As no context available at this point, do the following:
  * 1. Create one light-weight context just for surface creation.
  * 2. Store this qsurface, and link it with right context when MakeCurrent
  */
 static void keep_qsurface(ProcessState *process, QGloSurface *qsurface)
 {
-    int i;
     process->pending_qsurfaces =
         g_realloc(process->pending_qsurfaces,
                   (process->nb_qsurf + 1) * sizeof(QGloSurface*));
@@ -760,8 +754,9 @@ static int link_qsurface(ProcessState *process, GLState *glstate, ClientGLXDrawa
     return 0;
 }
 
-/* Pixmap can be used as texture via glEGLImageTargetTexture2DOES, so need keep
- * the mapping between them to add proper action when bind the texture again
+/* Pixmap and Pbuffer can be used as texture via glEGLImageTargetTexture2DOES
+ * and glXBindTexImage, so need keep the mapping between them to add proper
+ * action when bind the texture again
  */
 static void del_pixmap_texture_mapping(GLState *state,
         unsigned int texture)
@@ -780,6 +775,23 @@ static void del_pixmap_texture_mapping(GLState *state,
     }
 }
 
+static void remove_pixmap_texture_mapping(GLState *state,
+        ClientGLXDrawable drawable)
+{
+    int i;
+    for ( i = 0; i < MAX_PIXMAP_TEXTURE; i++ )
+    {
+        if ( state->pixmapTextures[i].used &&
+             state->pixmapTextures[i].drawable == drawable )
+        {
+            state->pixmapTextures[i].used = 0;
+            state->pixmapTextures[i].texture = 0;
+            state->pixmapTextures[i].drawable = 0;
+            return;
+        }
+    }
+}
+
 static int add_pixmap_texture_mapping(GLState *state,
         unsigned int texture, ClientGLXDrawable drawable)
 {
@@ -796,8 +808,7 @@ static int add_pixmap_texture_mapping(GLState *state,
         }
     }
 
-    if ( i >= MAX_PIXMAP_TEXTURE )
-        return 0;
+    return 0;
 }
 
 static ClientGLXDrawable find_pixmap_texture(GLState *state,
@@ -1759,7 +1770,7 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args
 
                     ret.i = glo_surface_makecurrent(glstate->current_qsurface->surface);
 /*                    if (reset_texture)*/
-/*                        glo_surface_as_texture(old_glstate->current_qsurface->surface);*/
+/*                        glo_surface_as_texture(process->current_state->context, old_glstate->current_qsurface->surface);*/
                 }
             }
             break;
@@ -2030,8 +2041,10 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args
                 keep_qsurface(process, qsurface);
 
                 /* If this pixmap is linked as texture previously */
-                if (link_drawable(process, client_drawable))
-                        glo_surface_as_texture(qsurface->surface);
+                               if (link_drawable(process, client_drawable))
+                                       glo_surface_as_texture(process->current_state->context,
+                                                       qsurface->surface);
+
 
                 ret.i = client_drawable;
 
@@ -2040,6 +2053,17 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args
         }
     case glXDestroyPixmap_func:
         {
+            /* glXPixmap same as input Pixmap */
+            ClientGLXDrawable client_drawable = to_drawable(args[1]);
+            QGloSurface *qsurface = find_qsurface_from_client_drawable(process, client_drawable);
+            if ( qsurface &&
+                 qsurface != process->current_state->current_qsurface &&
+                 qsurface->glstate == NULL &&
+                 qsurface->type == SURFACE_PIXMAP )
+            {
+                glo_surface_destroy(qsurface->surface);
+                g_free(qsurface);
+            }
             break;
         }
     case glEGLImageTargetTexture2DOES_fake_func:
@@ -2063,10 +2087,93 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args
                 }
             }
             else
-                glo_surface_as_texture(qsurface->surface);
+                               glo_surface_as_texture(process->current_state->context, qsurface->surface);
 
+                       break;
+               }
+       case glXBindTexImageARB_fake_func:
+               {
+                       ClientGLXDrawable client_drawable = to_drawable(args[1]);
+                       QGloSurface *qsurface = find_qsurface_from_client_drawable(process, client_drawable);
+                       ret.i = 0;
+
+
+                       if ( qsurface )
+                       {
+                               add_pixmap_texture_mapping(process->current_state,
+                                               process->current_state->bindTexture2D,
+                                               client_drawable);
+                               glo_surface_as_texture(process->current_state->context, qsurface->surface);
+                               ret.i = 1;
+                       }
+                       else
+                               DEBUGF( "Not found pbuffer surface for BindTexImage!\n");
+
+                       break;
+               }
+       case glXReleaseTexImageARB_fake_func:
+               {
+                       ClientGLXDrawable client_drawable = to_drawable(args[1]);
+                       QGloSurface *qsurface = find_qsurface_from_client_drawable(process, client_drawable);
+
+                       if ( qsurface )
+                       {
+                               remove_pixmap_texture_mapping(process->current_state,
+                                               client_drawable);
+                               glo_surface_release_texture(qsurface->surface);
+                       }
+
+                       break;
+               }
+       case glXCreatePbuffer_func:
+               {
+                       int client_fbconfig = args[1];
+
+                       ret.i = 0;
+                       const GLXFBConfig *fbconfig = get_fbconfig(process, client_fbconfig);
+
+                       if (fbconfig) {
+
+                               /* Create a light-weight context just for creating surface */
+                               GloContext *context = __glo_context_create(fbconfig->formatFlags);
+
+                               QGloSurface *qsurface = calloc(1, sizeof(QGloSurface));
+
+                               /* get the width and height */
+                               int width, height;
+                               glo_geometry_get_from_glx((int*)args[2], &width, &height);
+
+                               DEBUGF( "glXCreatePbuffer: %dX%d.\n", width, height);
+                               qsurface->surface = glo_surface_create(width, height, context);
+                               /* Use GloSurface handler as no input client_drawable, and
+                                * keep only low 32bit of handler on x86_64 host.  */
+                               qsurface->client_drawable = (int)qsurface->surface;
+                               qsurface->type = SURFACE_PBUFFER;
+                               qsurface->status = SURFACE_PENDING;
+                               /*                qsurface->ref = 1;*/
+
+                               /* Keep this surface, will link it with context in MakeCurrent */
+                               keep_qsurface(process, qsurface);
+
+                               ret.i = qsurface->client_drawable;
+
+                       }
+                       break;
+               }
+       case glXDestroyPbuffer_func:
+               {
+            ClientGLXDrawable client_drawable = to_drawable(args[1]);
+            QGloSurface *qsurface = find_qsurface_from_client_drawable(process, client_drawable);
+            if ( qsurface &&
+                 qsurface != process->current_state->current_qsurface &&
+                 qsurface->glstate == NULL &&
+                 qsurface->type == SURFACE_PBUFFER )
+            {
+                glo_surface_destroy(qsurface->surface);
+                g_free(qsurface);
+            }
             break;
-        }
+               }
 
 /* Begin of texture stuff */
     case glBindTexture_func:
@@ -2102,7 +2209,7 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args
 
                     if ( qsurface )
                     {
-                        glo_surface_as_texture(qsurface->surface);
+                        glo_surface_as_texture(process->current_state->context, qsurface->surface);
                         fprintf(stderr, "edwin:bindtexture: drawable=0x%x,qsurface=%p.\n", drawable, qsurface);
                     }
                 }
index 3b30217..e29f0d9 100644 (file)
@@ -428,9 +428,9 @@ static const int glXBindTexImageATI_signature[] =
     { TYPE_NONE, 0, 3, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT };
 static const int glXReleaseTexImageATI_signature[] =
     { TYPE_NONE, 0, 3, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT };
-static const int glXBindTexImageARB_signature[] =
+static const int glXBindTexImageARB_fake_signature[] =
     { TYPE_INT, 0, 3, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT };
-static const int glXReleaseTexImageARB_signature[] =
+static const int glXReleaseTexImageARB_fake_signature[] =
     { TYPE_INT, 0, 3, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT };
 
 static const int glEGLImageTargetTexture2DOES_fake_signature[] =
index caddfdb..3aacef9 100644 (file)
  */
 
 /**
- * @file emulator.h
- * @brief - header of file these are config structures and defines in emulator
+ * @file maru_common.h
+ * @brief - header file that covers maru common features
  */
 
 #ifndef __MARU_COMMON_H__
 #define __MARU_COMMON_H__
 
-#include "config-host.h"
 #include <stddef.h>
 #include <stdint.h>
 #include <stdbool.h>
+#include <stdlib.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib/gprintf.h>
+
+#include "config-host.h"
+
+#if !defined(PATH_MAX)
+#if defined(MAX_PATH)
+#define PATH_MAX    MAX_PATH
+#else
+#define PATH_MAX    256
+#endif
+#endif
 
 // W/A for preserve larger continuous heap for RAM.
 extern void *preallocated_ptr;
index 4e9b23b..bebf480 100644 (file)
@@ -28,8 +28,8 @@
  */
 
 
-#ifndef MARU_DISPLAY_H_
-#define MARU_DISPLAY_H_
+#ifndef __MARU_DISPLAY_H__
+#define __MARU_DISPLAY_H__
 
 #include "console.h"
 
@@ -45,4 +45,4 @@ void maruskin_init(uint64 swt_handle, int lcd_size_width, int lcd_size_height, b
 DisplaySurface* get_qemu_display_surface(void);
 MaruScreenshot* get_maru_screenshot(void);
 
-#endif /* MARU_DISPLAY_H_ */
+#endif /* __MARU_DISPLAY_H__ */
index eb33eab..140680d 100644 (file)
 #include "maru_sdl_rotozoom.h"
 #include "maru_finger.h"
 #include "hw/maru_pm.h"
+#include "hw/maru_brightness.h"
 #include "debug_ch.h"
-//#include "SDL_opengl.h"
+#if defined(CONFIG_LINUX)
+#include <sys/shm.h>
+#endif
+/* #include "SDL_opengl.h" */
 
 #ifdef MANGLE_OPENGL_SYMBOLS
 #include "gl_mangled.h"
@@ -60,6 +64,10 @@ static int current_screen_height;
 
 static int sdl_initialized;
 static int sdl_alteration;
+extern int g_shmid;
+extern char *g_shared_memory;
+
+static int sdl_skip_update;
 
 #if 0
 static int sdl_opengl = 0; //0 : just SDL surface, 1 : using SDL with OpenGL
@@ -165,6 +173,7 @@ void qemu_ds_sdl_refresh(DisplayState *ds)
 
                 pthread_mutex_unlock(&sdl_mutex);
                 vga_hw_invalidate();
+                sdl_skip_update = 0;
                 break;
             }
 
@@ -173,7 +182,21 @@ void qemu_ds_sdl_refresh(DisplayState *ds)
         }
     }
 
+    /* If the LCD is turned off,
+       the screen does not update until the LCD is turned on */
+    if (sdl_skip_update && brightness_off) {
+        return;
+    }
+
+    /* Usually, continuously updated.
+       When the LCD is turned off,
+       once updates the screen for a black screen. */
     vga_hw_update();
+    if (brightness_off) {
+        sdl_skip_update = 1;
+    } else {
+        sdl_skip_update = 0;
+    }
 
 #ifdef TARGET_ARM
 #ifdef SDL_THREAD
@@ -466,7 +489,7 @@ static void qemu_update(void)
                         SDL_BlitSurface((SDL_Surface *)mts->finger_point_surface, NULL, surface_screen, &rect);
                     }
                 }
-            } //end  of draw multi-touch
+            } /* end of draw multi-touch */
         }
 
     SDL_UpdateRect(surface_screen, 0, 0, 0, 0);
@@ -490,7 +513,8 @@ static void* run_qemu_update(void* arg)
 }
 #endif
 
-void maruskin_sdl_init(uint64 swt_handle, int lcd_size_width, int lcd_size_height, bool is_resize)
+void maruskin_sdl_init(uint64 swt_handle,
+    int lcd_size_width, int lcd_size_height, bool is_resize)
 {
     gchar SDL_windowhack[32];
     SDL_SysWMinfo info;
@@ -554,6 +578,18 @@ void maruskin_sdl_quit(void)
     sdl_alteration = -1;
 
     SDL_Quit();
+
+#ifdef SDL_THREAD
+    pthread_cond_destroy(&sdl_cond);
+#endif
+    pthread_mutex_destroy(&sdl_mutex);
+
+#if defined(CONFIG_LINUX)
+    if (shmctl(g_shmid, IPC_RMID, 0) == -1) {
+        ERR("shmctl failed\n");
+        perror("maru_sdl.c: ");
+    }
+#endif
 }
 
 
@@ -565,7 +601,8 @@ void maruskin_sdl_resize(void)
     memset(&ev, 0, sizeof(ev));
     ev.resize.type = SDL_VIDEORESIZE;
 
-    //This function is thread safe, and can be called from other threads safely.
+    /* This function is thread safe,
+    and can be called from other threads safely. */
     SDL_PushEvent(&ev);
 }
 
index 9561408..d4a61eb 100644 (file)
 #include "mloop_event.h"
 #include "console.h"
 #include "emul_state.h"
-#include "tizen/src/debug_ch.h"
+#include "debug_ch.h"
 #include "monitor.h"
 #include "pci.h"
 #include "sysemu.h"
 
+#include "emulator.h"
 #include "guest_debug.h"
 #include "skin/maruskin_server.h"
 #include "hw/maru_virtio_touchscreen.h"
@@ -385,7 +386,7 @@ static void mloop_evhandle_ramdump(struct mloop_evpack* pack)
     char dump_fullpath[MAX_PATH];
     char dump_filename[MAX_PATH];
 
-    char* dump_path = g_path_get_dirname(get_logpath());
+    char* dump_path = g_path_get_dirname(get_log_path());
 
     sprintf(dump_filename, "0x%08x%s0x%08x%s", rm->ram_addr, "-",
         rm->ram_addr + size, "_RAM.dump");
index cd6c6f5..ddfbc25 100644 (file)
@@ -42,6 +42,7 @@ void mloop_evcmd_usbdisk(char *img);
 void mloop_evcmd_hostkbd(int on);
 
 int mloop_evcmd_get_usbkbd_status(void);
+int mloop_evcmd_get_hostkbd_status(void);
 
 void mloop_evcmd_set_usbkbd(void *dev);
 void mloop_evcmd_set_usbdisk(void *dev);
index 7841e91..54655c9 100644 (file)
@@ -1,21 +1,3 @@
-/*
- * 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.
- *
- */
-
 #ifndef _NS_EVENT_H_
 #define _NS_EVENT_H_
 
index c2f8724..9e71f07 100644 (file)
@@ -1,21 +1,3 @@
-/*
- * 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.
- *
- */
-
 #import <Cocoa/Cocoa.h>                                         
 #import "ns_event.h"
 
diff --git a/tizen/src/option.c b/tizen/src/option.c
deleted file mode 100644 (file)
index 50979e0..0000000
+++ /dev/null
@@ -1,641 +0,0 @@
-/* 
- * Emulator
- *
- * Copyright (C) 2011, 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: 
- * SeokYeon Hwang <syeon.hwang@samsung.com>
- * MunKyu Im <munkyu.im@samsung.com>
- * GiWoong Kim <giwoong.kim@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- * HyunJun Son
- *
- * 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
- *
- */
-
-/**
-  @file option.c
-  @brief    collection of dialog function
- */
-
-#include "option.h"
-#include "emulator.h"
-#include "maru_common.h"
-#if defined (CONFIG_LINUX)
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <net/if.h>
-#elif defined (CONFIG_WIN32)
-#include <windows.h>
-#include <winsock2.h>
-#include <iphlpapi.h>
-#include <winreg.h>
-#elif defined (CONFIG_DARWIN)
-#include <SystemConfiguration/SystemConfiguration.h>
-CFDictionaryRef proxySettings;
-#endif
-#include <curl/curl.h>
-
-#include "debug_ch.h"
-
-#define HTTP_PROTOCOL "http="
-#define HTTP_PREFIX "http://"
-#define HTTPS_PROTOCOL "https="
-#define FTP_PROTOCOL "ftp="
-#define SOCKS_PROTOCOL "socks="
-#define DIRECT "DIRECT"
-#define PROXY "PROXY"
-#define MAXPORTLEN 6
-MULTI_DEBUG_CHANNEL(tizen, option);
-#if defined(CONFIG_WIN32)
-BYTE *url;
-#endif
-const char *pactempfile = ".autoproxy"; 
-
-/**
-  @brief    get host DNS server address
-  @param    dns1: return value (first dns server address)
-  @param    dns2: return value (second dns server address)
-  @return always 0
- */
-int gethostDNS(char *dns1, char *dns2)
-{
-#ifndef _WIN32
-    FILE *resolv;
-    char buf[255];
-    memset(buf, 0, sizeof(char)*255);
-
-    resolv = fopen("/etc/resolv.conf", "r");
-    if (resolv <= 0) {
-        ERR( "Can't open \"/etc/resolv.conf.\"\n");
-        fclose(resolv);
-        return 1;
-    }
-
-    while(fscanf(resolv , "%s", buf) != EOF) {
-        if(strcmp(buf, "nameserver") == 0)
-        {
-            if(fscanf(resolv , "%s", dns1) <= 0) {
-                // do nothing...
-            }
-            break;
-        }
-    }
-
-    while(fscanf(resolv , "%s", buf) != EOF) {
-        if(strcmp(buf, "nameserver") == 0)
-        {
-            if(fscanf(resolv , "%s", dns2) <= 0) {
-                // do nothing...
-            }
-            break;
-        }
-    }
-
-    fclose(resolv);
-#else
-    PIP_ADAPTER_ADDRESSES pAdapterAddr;
-    PIP_ADAPTER_ADDRESSES pAddr;
-    PIP_ADAPTER_DNS_SERVER_ADDRESS pDnsAddr;
-    unsigned long nBufferLength = sizeof(IP_ADAPTER_ADDRESSES);
-    pAdapterAddr = (PIP_ADAPTER_ADDRESSES)malloc(nBufferLength);
-    memset(pAdapterAddr, 0x00, nBufferLength);
-
-    while (GetAdaptersAddresses(AF_INET, 0, NULL, pAdapterAddr, &nBufferLength)
-            == ERROR_BUFFER_OVERFLOW) {
-        free(pAdapterAddr);
-        pAdapterAddr = (PIP_ADAPTER_ADDRESSES)malloc(nBufferLength);
-        memset(pAdapterAddr, 0x00, nBufferLength);
-    }
-
-    pAddr = pAdapterAddr;
-    for (; pAddr != NULL; pAddr = pAddr->Next) {
-        pDnsAddr = pAddr->FirstDnsServerAddress;
-        for (; pDnsAddr != NULL; pDnsAddr = pDnsAddr->Next) {
-            struct sockaddr_in *pSockAddr = (struct sockaddr_in*)pDnsAddr->Address.lpSockaddr;
-            if(*dns1 == 0) {
-                strcpy(dns1, inet_ntoa(pSockAddr->sin_addr));
-                continue;
-            }
-            if(*dns2 == 0) {
-                strcpy(dns2, inet_ntoa(pSockAddr->sin_addr));
-                continue;
-            }
-        }
-    }
-    free(pAdapterAddr);
-#endif
-
-    // by caramis... change DNS address if localhost has DNS server or DNS cache.
-    if(!strncmp(dns1, "127.0.0.1", 9) || !strncmp(dns1, "localhost", 9)) {
-        strncpy(dns1, "10.0.2.2", 9);
-    }
-    if(!strncmp(dns2, "127.0.0.1", 9) || !strncmp(dns2, "localhost", 9)) {
-        strncpy(dns2, "10.0.2.2", 9);
-    }
-
-    return 0;
-}
-
-#if defined (CONFIG_DARWIN)
-static char *cfstring_to_cstring(CFStringRef str) {
-    if (str == NULL) {
-        return NULL;
-    }
-
-    CFIndex length = CFStringGetLength(str);
-    CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8);
-    char *buffer = (char *)malloc(maxSize);
-    if (CFStringGetCString(str, buffer, maxSize, kCFStringEncodingUTF8))
-        return buffer;
-    return NULL;
-}
-
-static int cfnumber_to_int(CFNumberRef num) {
-    if (!num)
-        return 0;
-
-    int value;
-    CFNumberGetValue(num, kCFNumberIntType, &value);
-    return value;
-}
-#endif
-
-static size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) 
-{     
-    size_t written;
-    written = fwrite(ptr, size, nmemb, stream);
-    return written;
-}  
-
-static void download_url(char *url) 
-{     
-    CURL *curl;     
-    FILE *fp;     
-    CURLcode res;     
-
-    curl = curl_easy_init();
-    if (curl) { 
-        fp = fopen(pactempfile,"wb");
-        curl_easy_setopt(curl, CURLOPT_URL, url);
-        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
-        //just in case network does not work.
-        curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 3000);
-        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
-        res = curl_easy_perform(curl);
-        if(res != 0) {
-            ERR("Fail to download pac file: %s\n", url);
-        }
-        curl_easy_cleanup(curl); 
-        fclose(fp);
-    }     
-
-    return; 
-} 
-
-#if defined (CONFIG_DARWIN)
-static void getmacproxy(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
-{
-    char *hostname;
-    int port;
-    CFNumberRef isEnable;
-    CFStringRef proxyHostname;
-    CFNumberRef proxyPort;
-    CFDictionaryRef proxySettings;
-    proxySettings = SCDynamicStoreCopyProxies(NULL);
-
-    isEnable  = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPEnable);
-    if (cfnumber_to_int(isEnable)) {        
-        // Get proxy hostname
-        proxyHostname = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPProxy);
-        hostname = cfstring_to_cstring(proxyHostname);
-        // Get proxy port
-        proxyPort = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPPort);
-        port = cfnumber_to_int(proxyPort);
-        // Save hostname & port
-        snprintf(http_proxy, MAXLEN, "%s:%d", hostname, port);
-
-        free(hostname);
-    } else {
-        INFO("http proxy is null\n");
-    }
-    
-    isEnable  = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPSEnable);
-    if (cfnumber_to_int(isEnable)) {        
-        // Get proxy hostname
-        proxyHostname = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPSProxy);
-        hostname = cfstring_to_cstring(proxyHostname);
-        // Get proxy port
-        proxyPort = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPSPort);
-        port = cfnumber_to_int(proxyPort);
-        // Save hostname & port
-        snprintf(https_proxy, MAXLEN, "%s:%d", hostname, port);
-
-        free(hostname);
-    } else {
-        INFO("https proxy is null\n");
-    }
-    
-    isEnable  = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesFTPEnable);
-    if (cfnumber_to_int(isEnable)) {        
-        // Get proxy hostname
-        proxyHostname = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesFTPProxy);
-        hostname = cfstring_to_cstring(proxyHostname);
-        // Get proxy port
-        proxyPort = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesFTPPort);
-        port = cfnumber_to_int(proxyPort);
-        // Save hostname & port
-        snprintf(ftp_proxy, MAXLEN, "%s:%d", hostname, port);
-
-        free(hostname);
-    } else {
-        INFO("ftp proxy is null\n");
-    }
-    
-    isEnable  = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesSOCKSEnable);
-    if (cfnumber_to_int(isEnable)) {        
-        // Get proxy hostname
-        proxyHostname = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesSOCKSProxy);
-        hostname = cfstring_to_cstring(proxyHostname);
-        // Get proxy port
-        proxyPort = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesSOCKSPort);
-        port = cfnumber_to_int(proxyPort);
-        // Save hostname & port
-        snprintf(socks_proxy, MAXLEN, "%s:%d", hostname, port);
-
-        free(hostname);
-    } else {
-        INFO("socks proxy is null\n");
-    }
-    CFRelease(proxySettings);
-}
-#endif
-
-static void remove_string(char *src, char *dst, const char *toremove)
-{
-    int len = strlen(toremove);
-    int i, j;
-    int max_len = strlen(src);
-
-    for(i = len, j = 0; i < max_len; i++)
-    {
-        dst[j++] = src[i];
-    }
-
-    dst[j] = '\0';
-}
-
-#if defined (CONFIG_LINUX)    
-static void getlinuxproxy(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
-{
-    char buf[MAXLEN] = {0,};
-    char buf_port[MAXPORTLEN] = {0,};
-    char buf_proxy[MAXLEN] = {0,};
-    char *buf_proxy_bak;
-    char *proxy;
-    FILE *output;
-    int MAXPROXYLEN = MAXLEN + MAXPORTLEN;
-
-    output = popen("gconftool-2 --get /system/http_proxy/host", "r");
-    if(fscanf(output, "%s", buf) > 0) {
-        snprintf(buf_proxy, MAXLEN, "%s", buf);
-    }
-    pclose(output);
-    
-    output = popen("gconftool-2 --get /system/http_proxy/port", "r");
-    if(fscanf(output, "%s", buf_port) <= 0) {
-        //for abnormal case: if can't find the key of http port, get from environment value.
-        buf_proxy_bak = getenv("http_proxy");
-        INFO("http_proxy from env: %s\n", buf_proxy_bak);
-        if(buf_proxy_bak != NULL) {
-            proxy = malloc(MAXLEN);
-            remove_string(buf_proxy_bak, proxy, HTTP_PREFIX);
-            strncpy(http_proxy, proxy, strlen(proxy)-1);
-            INFO("final http_proxy value: %s\n", http_proxy);
-            free(proxy);
-        }
-        else {
-            INFO("http_proxy is not set on env.\n");
-            pclose(output);
-            return;
-        }
-
-    }
-    else {
-        snprintf(http_proxy, MAXPROXYLEN, "%s:%s", buf_proxy, buf_port);
-        memset(buf_proxy, 0, MAXLEN);
-        INFO("http_proxy: %s\n", http_proxy);
-    }
-    pclose(output);
-
-    memset(buf, 0, MAXLEN);
-
-    output = popen("gconftool-2 --get /system/proxy/secure_host", "r");
-    if(fscanf(output, "%s", buf) > 0) {
-        snprintf(buf_proxy, MAXLEN, "%s", buf);
-    }
-    pclose(output);
-
-    output = popen("gconftool-2 --get /system/proxy/secure_port", "r");
-    if(fscanf(output, "%s", buf) > 0) {
-        snprintf(https_proxy, MAXPROXYLEN, "%s:%s", buf_proxy, buf);
-    }
-    pclose(output);
-    memset(buf, 0, MAXLEN);
-    memset(buf_proxy, 0, MAXLEN);
-    INFO("https_proxy : %s\n", https_proxy);
-
-    output = popen("gconftool-2 --get /system/proxy/ftp_host", "r");
-    if(fscanf(output, "%s", buf) > 0) {
-        snprintf(buf_proxy, MAXLEN, "%s", buf);
-    }
-    pclose(output);
-
-    output = popen("gconftool-2 --get /system/proxy/ftp_port", "r");
-    if(fscanf(output, "%s", buf) > 0) {
-        snprintf(ftp_proxy, MAXPROXYLEN, "%s:%s", buf_proxy, buf);
-    }
-    pclose(output);
-    memset(buf, 0, MAXLEN);
-    memset(buf_proxy, 0, MAXLEN);
-    INFO("ftp_proxy : %s\n", ftp_proxy);
-
-    output = popen("gconftool-2 --get /system/proxy/socks_host", "r");
-    if(fscanf(output, "%s", buf) > 0) {
-        snprintf(buf_proxy, MAXLEN, "%s", buf);
-    }
-    pclose(output);
-
-    output = popen("gconftool-2 --get /system/proxy/socks_port", "r");
-    if(fscanf(output, "%s", buf) > 0) {
-        snprintf(socks_proxy, MAXPROXYLEN, "%s:%s", buf_proxy, buf);
-    }
-    pclose(output);
-    INFO("socks_proxy : %s\n", socks_proxy);
-}
-#endif
-
-static int getautoproxy(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
-{
-    char type[MAXLEN];
-    char proxy[MAXLEN];
-    char line[MAXLEN];
-    FILE *fp_pacfile;
-    char *p = NULL;
-#if defined(CONFIG_LINUX)
-    FILE *output;
-    char buf[MAXLEN];
-
-    output = popen("gconftool-2 --get /system/proxy/autoconfig_url", "r");
-    if(fscanf(output, "%s", buf) > 0) {
-        INFO("pac address: %s\n", buf);
-        download_url(buf);
-    }
-    pclose(output);
-#elif defined(CONFIG_WIN32)    
-    INFO("pac address: %s\n", (char*)url);
-    download_url((char*)url);
-#elif defined(CONFIG_DARWIN)
-    CFStringRef pacURL = (CFStringRef)CFDictionaryGetValue(proxySettings,
-                               kSCPropNetProxiesProxyAutoConfigURLString);
-       if (pacURL) {
-               char url[MAXLEN] = {};
-               CFStringGetCString(pacURL, url, sizeof url, kCFStringEncodingASCII);
-                INFO("pac address: %s\n", (char*)url);
-               download_url(url);
-        }
-#endif
-    fp_pacfile = fopen(pactempfile, "r");
-    if(fp_pacfile != NULL) {
-        while(fgets(line, MAXLEN, fp_pacfile) != NULL) {
-            if( (strstr(line, "return") != NULL) && (strstr(line, "if") == NULL)) {
-                INFO("line found %s", line);
-                sscanf(line, "%*[^\"]\"%s %s", type, proxy);
-            }
-        }
-
-        if(g_str_has_prefix(type, DIRECT)) {
-            INFO("auto proxy is set to direct mode\n");
-            fclose(fp_pacfile);
-        }
-        else if(g_str_has_prefix(type, PROXY)) {
-            INFO("auto proxy is set to proxy mode\n");
-            INFO("type: %s, proxy: %s\n", type, proxy);
-            p = strtok(proxy, "\";");
-            if(p != NULL) {
-                INFO("auto proxy to set: %s\n",p);
-                strcpy(http_proxy, p);
-                strcpy(https_proxy, p);
-                strcpy(ftp_proxy, p);
-                strcpy(socks_proxy, p);
-            }
-            fclose(fp_pacfile);
-        }
-        else
-        {
-            ERR("pac file is not wrong! It could be the wrong pac address or pac file format\n");
-            fclose(fp_pacfile);
-        }
-    } 
-    else {
-        ERR("fail to get pacfile fp\n");
-       return -1;
-    }
-
-    remove(pactempfile);
-    return 0;
-}
-
-
-/**
-  @brief    get host proxy server address
-  @param    proxy: return value (proxy server address)
-  @return always 0
- */
-int gethostproxy(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
-{
-#if defined(CONFIG_LINUX) 
-    char buf[MAXLEN];
-    FILE *output;
-
-    output = popen("gconftool-2 --get /system/proxy/mode", "r");
-    if(fscanf(output, "%s", buf) > 0) {
-        //priority : auto > manual > none       
-        if (strcmp(buf, "auto") == 0) {
-            INFO("AUTO PROXY MODE\n");
-            getautoproxy(http_proxy, https_proxy, ftp_proxy, socks_proxy);
-        }
-        else if (strcmp(buf, "manual") == 0) {
-            INFO("MANUAL PROXY MODE\n");
-            getlinuxproxy(http_proxy, https_proxy, ftp_proxy, socks_proxy);
-        }
-        else if (strcmp(buf, "none") == 0) {
-            INFO("DIRECT PROXY MODE\n");
-        }
-    }
-    pclose(output);
-
-#elif defined(CONFIG_WIN32)
-    HKEY hKey;
-    int nRet;
-    LONG lRet;
-    BYTE *proxyenable, *proxyserver;
-    char *p;
-    char *real_proxy;
-
-    DWORD dwLength = 0;
-    nRet = RegOpenKeyEx(HKEY_CURRENT_USER,
-            "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
-            0, KEY_QUERY_VALUE, &hKey);
-    if (nRet != ERROR_SUCCESS) {
-        ERR("Failed to open registry from %s\n",
-                "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings");
-        return 0;
-    }
-    //check auto proxy key exists
-    lRet = RegQueryValueEx(hKey, "AutoConfigURL", 0, NULL, NULL, &dwLength);
-    if (lRet != ERROR_SUCCESS && dwLength == 0) {
-        ERR("Failed to query value from %s\n",
-                "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\AutoConfigURL");
-    }
-    else {
-        //if exists
-        url = (char*)malloc(dwLength);
-        if (url == NULL) {
-            ERR( "Failed to allocate a buffer\n");
-        }
-        else {
-            memset(url, 0x00, dwLength);
-            lRet = RegQueryValueEx(hKey, "AutoConfigURL", 0, NULL, url, &dwLength);
-            if (lRet == ERROR_SUCCESS && dwLength != 0) {
-                getautoproxy(http_proxy, https_proxy, ftp_proxy, socks_proxy);
-                RegCloseKey(hKey);      
-                return 0;
-            }
-        }
-    }
-    //check manual proxy key exists
-    lRet = RegQueryValueEx(hKey, "ProxyEnable", 0, NULL, NULL, &dwLength);
-    if (lRet != ERROR_SUCCESS && dwLength == 0) {
-        ERR(stderr, "Failed to query value from %s\n",
-                "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ProxyEnable");
-        RegCloseKey(hKey);
-        return 0;
-    }
-    proxyenable = (BYTE*)malloc(dwLength);
-    if (proxyenable == NULL) {
-        ERR( "Failed to allocate a buffer\n");
-        RegCloseKey(hKey);
-        return 0;
-    }
-
-    lRet = RegQueryValueEx(hKey, "ProxyEnable", 0, NULL, proxyenable, &dwLength);
-    if (lRet != ERROR_SUCCESS) {
-        free(proxyenable);
-        ERR("Failed to query value from %s\n",
-                "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ProxyEnable");
-        RegCloseKey(hKey);
-        return 0;
-    }
-    if (*(char*)proxyenable == 0) {
-        free(proxyenable);
-        RegCloseKey(hKey);      
-        return 0;
-    }
-
-    dwLength = 0;
-    lRet = RegQueryValueEx(hKey, "ProxyServer", 0, NULL, NULL, &dwLength);
-    if (lRet != ERROR_SUCCESS && dwLength == 0) {
-        ERR("Failed to query value from from %s\n",
-                "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings");
-        RegCloseKey(hKey);      
-        return 0;
-    }
-
-    proxyserver = (BYTE*)malloc(dwLength);
-    if (proxyserver == NULL) {
-        ERR( "Failed to allocate a buffer\n");
-        RegCloseKey(hKey);      
-        return 0;
-    }
-
-    memset(proxyserver, 0x00, dwLength);
-    lRet = RegQueryValueEx(hKey, "ProxyServer", 0, NULL, proxyserver, &dwLength);
-    if (lRet != ERROR_SUCCESS) {
-        free(proxyserver);
-        ERR( "Failed to query value from from %s\n",
-                "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings");
-        RegCloseKey(hKey);
-        return 0;
-    }
-    
-    if((char*)proxyserver != NULL) {
-        INFO("proxy value: %s\n", (char*)proxyserver);
-        real_proxy = malloc(MAXLEN);
-        
-        for(p = strtok((char*)proxyserver, ";"); p; p = strtok(NULL, ";")){
-            if(strstr(p, HTTP_PROTOCOL)) {
-                remove_string(p, real_proxy, HTTP_PROTOCOL);
-                strcpy(http_proxy, real_proxy);
-            }
-            else if(strstr(p, HTTPS_PROTOCOL)) {
-                remove_string(p, real_proxy, HTTPS_PROTOCOL);
-                strcpy(https_proxy, real_proxy);
-            }
-            else if(strstr(p, FTP_PROTOCOL)) {
-                remove_string(p, real_proxy, FTP_PROTOCOL);
-                strcpy(ftp_proxy, real_proxy);
-            }
-            else if(strstr(p, SOCKS_PROTOCOL)) {
-                remove_string(p, real_proxy, SOCKS_PROTOCOL);
-                strcpy(socks_proxy, real_proxy);
-            }
-            else {
-                INFO("all protocol uses the same proxy server: %s\n", p);
-                strcpy(http_proxy, p);
-                strcpy(https_proxy, p);
-                strcpy(ftp_proxy, p);
-                strcpy(socks_proxy, p);
-            }
-        }
-        free(real_proxy);
-    }
-    else {
-        INFO("proxy is null\n");
-        return 0;
-    }
-    RegCloseKey(hKey);
-#elif defined (CONFIG_DARWIN)
-    int ret;
-    proxySettings = SCDynamicStoreCopyProxies(NULL);
-    if(proxySettings) {
-        INFO("AUTO PROXY MODE\n");
-        ret = getautoproxy(http_proxy, https_proxy, ftp_proxy, socks_proxy); 
-        if(strlen(http_proxy) == 0 && ret < 0) {
-            INFO("MANUAL PROXY MODE\n");
-               getmacproxy(http_proxy, https_proxy, ftp_proxy, socks_proxy); 
-           }
-    }
-#endif
-    return 0;
-}
diff --git a/tizen/src/osutil-darwin.c b/tizen/src/osutil-darwin.c
new file mode 100644 (file)
index 0000000..8948496
--- /dev/null
@@ -0,0 +1,337 @@
+/*
+ * Emulator
+ *
+ * Copyright (C) 2012, 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * MunKyu Im <munkyu.im@samsung.com>
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ * HyunJun Son
+ *
+ * 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
+ *
+ */
+
+/**
+  @file     osutil-darwin.c
+  @brief    Collection of utilities for darwin
+ */
+
+#include "maru_common.h"
+#include "osutil.h"
+#include "emulator.h"
+#include "debug_ch.h"
+#include "maru_err_table.h"
+#include "sdb.h"
+
+#ifndef CONFIG_DARWIN
+#error
+#endif
+
+#include <string.h>
+#include <sys/shm.h>
+#include <sys/sysctl.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+
+MULTI_DEBUG_CHANNEL(qemu, osutil);
+
+extern int tizen_base_port;
+CFDictionaryRef proxySettings;
+
+static char *cfstring_to_cstring(CFStringRef str) {
+    if (str == NULL) {
+        return NULL;
+    }
+
+    CFIndex length = CFStringGetLength(str);
+    CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8);
+    char *buffer = (char *)malloc(maxSize);
+    if (CFStringGetCString(str, buffer, maxSize, kCFStringEncodingUTF8))
+        return buffer;
+    return NULL;
+}
+
+static int cfnumber_to_int(CFNumberRef num) {
+    if (!num)
+        return 0;
+
+    int value;
+    CFNumberGetValue(num, kCFNumberIntType, &value);
+    return value;
+}
+
+void check_vm_lock_os(void)
+{
+    /* TODO: */
+}
+
+void make_vm_lock_os(void)
+{
+    int shmid;
+    char *shared_memory;
+
+    shmid = shmget((key_t)SHMKEY, MAXLEN, 0666|IPC_CREAT);
+    if (shmid == -1) {
+        ERR("shmget failed\n");
+        perror("osutil-darwin: ");
+        return;
+    }
+
+    shared_memory = shmat(shmid, (char *)0x00, 0);
+    if (shared_memory == (void *)-1) {
+        ERR("shmat failed\n");
+        perror("osutil-darwin: ");
+        return;
+    }
+    sprintf(shared_memory, "%d", tizen_base_port + 2);
+    INFO("shared memory key: %d, value: %s\n", SHMKEY, (char *)shared_memory);
+    
+    if (shmdt(shared_memory) == -1) {
+        ERR("shmdt failed\n");
+        perror("osutil-darwin: ");
+    }
+}
+
+void set_bin_path_os(gchar * exec_argv)
+{
+    gchar *file_name = NULL;
+
+    if (!exec_argv) {
+        return;
+    }
+
+    char *data = g_strdup(exec_argv);
+    if (!data) {
+        ERR("Fail to strdup for paring a binary directory.\n");
+        return;
+    }
+
+    file_name = g_strrstr(data, "/");
+    if (!file_name) {
+        free(data);
+        return;
+    }
+
+    g_strlcpy(bin_path, data, strlen(data) - strlen(file_name) + 1);
+
+    g_strlcat(bin_path, "/", PATH_MAX);
+    free(data);
+}
+
+
+void print_system_info_os(void)
+{
+  INFO("* Mac\n");
+
+    /* uname */
+    INFO("* Host machine uname :\n");
+    char uname_cmd[MAXLEN] = "uname -a >> ";
+    strcat(uname_cmd, log_path);
+    if(system(uname_cmd) < 0) {
+        INFO("system function command '%s' \
+            returns error !", uname_cmd);
+    }
+
+    /* hw information */
+    int mib[2];
+    size_t len;
+    char *sys_info;
+    int sys_num = 0;
+
+    mib[0] = CTL_HW;
+    mib[1] = HW_MODEL;
+    sysctl(mib, 2, NULL, &len, NULL, 0);
+    sys_info = malloc(len * sizeof(char));
+    if (sysctl(mib, 2, sys_info, &len, NULL, 0) >= 0) {
+        INFO("* Machine model : %s\n", sys_info);
+    }
+    free(sys_info);
+
+    mib[0] = CTL_HW;
+    mib[1] = HW_MACHINE;
+    sysctl(mib, 2, NULL, &len, NULL, 0);
+    sys_info = malloc(len * sizeof(char));
+    if (sysctl(mib, 2, sys_info, &len, NULL, 0) >= 0) {
+        INFO("* Machine class : %s\n", sys_info);
+    }
+    free(sys_info);
+
+    mib[0] = CTL_HW;
+    mib[1] = HW_NCPU;
+    len = sizeof(sys_num);
+    if (sysctl(mib, 2, &sys_num, &len, NULL, 0) >= 0) {
+        INFO("* Number of processors : %d\n", sys_num);
+    }
+
+    mib[0] = CTL_HW;
+    mib[1] = HW_PHYSMEM;
+    len = sizeof(sys_num);
+    if (sysctl(mib, 2, &sys_num, &len, NULL, 0) >= 0) {
+        INFO("* Total memory : %llu bytes\n", sys_num);
+    }
+}
+
+static int get_auto_proxy(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
+{
+    char type[MAXLEN];
+    char proxy[MAXLEN];
+    char line[MAXLEN];
+    FILE *fp_pacfile;
+    char *p = NULL;
+
+    CFStringRef pacURL = (CFStringRef)CFDictionaryGetValue(proxySettings,
+                               kSCPropNetProxiesProxyAutoConfigURLString);
+       if (pacURL) {
+               char url[MAXLEN] = {};
+               CFStringGetCString(pacURL, url, sizeof url, kCFStringEncodingASCII);
+                INFO("pac address: %s\n", (char*)url);
+               download_url(url);
+        }
+
+    fp_pacfile = fopen(pac_tempfile, "r");
+    if(fp_pacfile != NULL) {
+        while(fgets(line, MAXLEN, fp_pacfile) != NULL) {
+            if( (strstr(line, "return") != NULL) && (strstr(line, "if") == NULL)) {
+                INFO("line found %s", line);
+                sscanf(line, "%*[^\"]\"%s %s", type, proxy);
+            }
+        }
+
+        if(g_str_has_prefix(type, DIRECT)) {
+            INFO("auto proxy is set to direct mode\n");
+            fclose(fp_pacfile);
+        }
+        else if(g_str_has_prefix(type, PROXY)) {
+            INFO("auto proxy is set to proxy mode\n");
+            INFO("type: %s, proxy: %s\n", type, proxy);
+            p = strtok(proxy, "\";");
+            if(p != NULL) {
+                INFO("auto proxy to set: %s\n",p);
+                strcpy(http_proxy, p);
+                strcpy(https_proxy, p);
+                strcpy(ftp_proxy, p);
+                strcpy(socks_proxy, p);
+            }
+            fclose(fp_pacfile);
+        }
+        else
+        {
+            ERR("pac file is not wrong! It could be the wrong pac address or pac file format\n");
+            fclose(fp_pacfile);
+        }
+    }
+    else {
+        ERR("fail to get pacfile fp\n");
+       return -1;
+    }
+
+    remove(pac_tempfile);
+    return 0;
+}
+
+static void get_proxy(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
+{
+    char *hostname;
+    int port;
+    CFNumberRef isEnable;
+    CFStringRef proxyHostname;
+    CFNumberRef proxyPort;
+    CFDictionaryRef proxySettings;
+    proxySettings = SCDynamicStoreCopyProxies(NULL);
+
+    isEnable  = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPEnable);
+    if (cfnumber_to_int(isEnable)) {
+        // Get proxy hostname
+        proxyHostname = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPProxy);
+        hostname = cfstring_to_cstring(proxyHostname);
+        // Get proxy port
+        proxyPort = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPPort);
+        port = cfnumber_to_int(proxyPort);
+        // Save hostname & port
+        snprintf(http_proxy, MAXLEN, "%s:%d", hostname, port);
+
+        free(hostname);
+    } else {
+        INFO("http proxy is null\n");
+    }
+
+    isEnable  = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPSEnable);
+    if (cfnumber_to_int(isEnable)) {
+        // Get proxy hostname
+        proxyHostname = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPSProxy);
+        hostname = cfstring_to_cstring(proxyHostname);
+        // Get proxy port
+        proxyPort = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPSPort);
+        port = cfnumber_to_int(proxyPort);
+        // Save hostname & port
+        snprintf(https_proxy, MAXLEN, "%s:%d", hostname, port);
+
+        free(hostname);
+    } else {
+        INFO("https proxy is null\n");
+    }
+
+    isEnable  = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesFTPEnable);
+    if (cfnumber_to_int(isEnable)) {
+        // Get proxy hostname
+        proxyHostname = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesFTPProxy);
+        hostname = cfstring_to_cstring(proxyHostname);
+        // Get proxy port
+        proxyPort = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesFTPPort);
+        port = cfnumber_to_int(proxyPort);
+        // Save hostname & port
+        snprintf(ftp_proxy, MAXLEN, "%s:%d", hostname, port);
+
+        free(hostname);
+    } else {
+        INFO("ftp proxy is null\n");
+    }
+
+    isEnable  = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesSOCKSEnable);
+    if (cfnumber_to_int(isEnable)) {
+        // Get proxy hostname
+        proxyHostname = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesSOCKSProxy);
+        hostname = cfstring_to_cstring(proxyHostname);
+        // Get proxy port
+        proxyPort = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesSOCKSPort);
+        port = cfnumber_to_int(proxyPort);
+        // Save hostname & port
+        snprintf(socks_proxy, MAXLEN, "%s:%d", hostname, port);
+
+        free(hostname);
+    } else {
+        INFO("socks proxy is null\n");
+    }
+    CFRelease(proxySettings);
+}
+
+void get_host_proxy_os(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
+{
+    int ret;
+    proxySettings = SCDynamicStoreCopyProxies(NULL);
+    if(proxySettings) {
+        INFO("AUTO PROXY MODE\n");
+        ret = get_auto_proxy(http_proxy, https_proxy, ftp_proxy, socks_proxy);
+        if(strlen(http_proxy) == 0 && ret < 0) {
+            INFO("MANUAL PROXY MODE\n");
+               get_proxy(http_proxy, https_proxy, ftp_proxy, socks_proxy);
+           }
+    }
+}
diff --git a/tizen/src/osutil-linux.c b/tizen/src/osutil-linux.c
new file mode 100644 (file)
index 0000000..0de15e5
--- /dev/null
@@ -0,0 +1,354 @@
+/* 
+ * Emulator
+ *
+ * Copyright (C) 2012, 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * MunKyu Im <munkyu.im@samsung.com>
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ * HyunJun Son
+ *
+ * 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
+ *
+ */
+
+/**
+  @file     osutil-linux.c
+  @brief    Collection of utilities for linux
+ */
+
+#include "maru_common.h"
+#include "osutil.h"
+#include "emulator.h"
+#include "debug_ch.h"
+#include "maru_err_table.h"
+#include "sdb.h"
+
+#ifndef CONFIG_LINUX
+#error
+#endif
+
+#include <string.h>
+#include <unistd.h>
+#include <sys/shm.h>
+#include <sys/ipc.h>
+#include <linux/version.h>
+#include <sys/utsname.h>
+#include <sys/sysinfo.h>
+
+MULTI_DEBUG_CHANNEL(emulator, osutil);
+
+extern char tizen_target_img_path[];
+extern int tizen_base_port;
+int g_shmid;
+char *g_shared_memory;
+
+void check_vm_lock_os(void)
+{
+    int shm_id;
+    void *shm_addr;
+    uint32_t port;
+    int val;
+    struct shmid_ds shm_info;
+
+    for (port = 26100; port < 26200; port += 10) {
+        shm_id = shmget((key_t)port, 0, 0);
+        if (shm_id != -1) {
+            shm_addr = shmat(shm_id, (void *)0, 0);
+            if ((void *)-1 == shm_addr) {
+                ERR("error occured at shmat()\n");
+                break;
+            }
+
+            val = shmctl(shm_id, IPC_STAT, &shm_info);
+            if (val != -1) {
+                INFO("count of process that use shared memory : %d\n",
+                    shm_info.shm_nattch);
+                if ((shm_info.shm_nattch > 0) &&
+                    g_strcmp0(tizen_target_img_path, (char *)shm_addr) == 0) {
+                    if (check_port_bind_listen(port + 1) > 0) {
+                        shmdt(shm_addr);
+                        continue;
+                    }
+                    shmdt(shm_addr);
+                    maru_register_exit_msg(MARU_EXIT_UNKNOWN,
+                                        "Can not execute this VM.\n"
+                                        "The same name is running now.");
+                    exit(0);
+                } else {
+                    shmdt(shm_addr);
+                }
+            }
+        }
+    }
+}
+
+void make_vm_lock_os(void)
+{
+
+    g_shmid = shmget((key_t)tizen_base_port, MAXLEN, 0666|IPC_CREAT);
+    if (g_shmid == -1) {
+        ERR("shmget failed\n");
+        return;
+    }
+
+    g_shared_memory = shmat(g_shmid, (char *)0x00, 0);
+    if (g_shared_memory == (void *)-1) {
+        ERR("shmat failed\n");
+        return;
+    }
+    g_sprintf(g_shared_memory, "%s", tizen_target_img_path);
+    INFO("shared memory key: %d value: %s\n",
+        tizen_base_port, (char *)g_shared_memory);
+}
+
+void set_bin_path_os(gchar * exec_argv)
+{
+    gchar link_path[PATH_MAX] = { 0, };
+    char *file_name = NULL;
+
+    ssize_t len = readlink("/proc/self/exe", link_path, sizeof(link_path) - 1);
+
+    if (len < 0 || len > sizeof(link_path)) {
+        perror("set_bin_path error : ");
+        return;
+    }
+
+    link_path[len] = '\0';
+
+    file_name = g_strrstr(link_path, "/");
+    g_strlcpy(bin_path, link_path, strlen(link_path) - strlen(file_name) + 1);
+
+    g_strlcat(bin_path, "/", PATH_MAX);
+}
+
+void print_system_info_os(void)
+{
+    INFO("* Linux\n");
+
+    /* depends on building */
+    INFO("* QEMU build machine linux kernel version : (%d, %d, %d)\n",
+            LINUX_VERSION_CODE >> 16,
+            (LINUX_VERSION_CODE >> 8) & 0xff,
+            LINUX_VERSION_CODE & 0xff);
+
+     /* depends on launching */
+    struct utsname host_uname_buf;
+    if (uname(&host_uname_buf) == 0) {
+        INFO("* Host machine uname : %s %s %s %s %s\n",
+            host_uname_buf.sysname, host_uname_buf.nodename,
+            host_uname_buf.release, host_uname_buf.version,
+            host_uname_buf.machine);
+    }
+
+    struct sysinfo sys_info;
+    if (sysinfo(&sys_info) == 0) {
+        INFO("* Total Ram : %llu kB, Free: %llu kB\n",
+            sys_info.totalram * (unsigned long long)sys_info.mem_unit / 1024,
+            sys_info.freeram * (unsigned long long)sys_info.mem_unit / 1024);
+    }
+
+    /* get linux distribution information */
+    INFO("* Linux distribution infomation :\n");
+    char lsb_release_cmd[MAXLEN] = "lsb_release -d -r -c >> ";
+    strcat(lsb_release_cmd, log_path);
+    if(system(lsb_release_cmd) < 0) {
+        INFO("system function command '%s' \
+            returns error !", lsb_release_cmd);
+    }
+
+    /* pci device description */
+    INFO("* PCI devices :\n");
+    char lspci_cmd[MAXLEN] = "lspci >> ";
+    strcat(lspci_cmd, log_path);
+    if(system(lspci_cmd) < 0) {
+        INFO("system function command '%s' \
+            returns error !", lspci_cmd);
+    }
+}
+
+static int get_auto_proxy(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
+{
+    char type[MAXLEN];
+    char proxy[MAXLEN];
+    char line[MAXLEN];
+    FILE *fp_pacfile;
+    char *p = NULL;
+    FILE *output;
+    char buf[MAXLEN];
+
+    output = popen("gconftool-2 --get /system/proxy/autoconfig_url", "r");
+    if(fscanf(output, "%s", buf) > 0) {
+        INFO("pac address: %s\n", buf);
+        download_url(buf);
+    }
+    pclose(output);
+    fp_pacfile = fopen(pac_tempfile, "r");
+    if(fp_pacfile != NULL) {
+        while(fgets(line, MAXLEN, fp_pacfile) != NULL) {
+            if( (strstr(line, "return") != NULL) && (strstr(line, "if") == NULL)) {
+                INFO("line found %s", line);
+                sscanf(line, "%*[^\"]\"%s %s", type, proxy);
+            }
+        }
+
+        if(g_str_has_prefix(type, DIRECT)) {
+            INFO("auto proxy is set to direct mode\n");
+            fclose(fp_pacfile);
+        }
+        else if(g_str_has_prefix(type, PROXY)) {
+            INFO("auto proxy is set to proxy mode\n");
+            INFO("type: %s, proxy: %s\n", type, proxy);
+            p = strtok(proxy, "\";");
+            if(p != NULL) {
+                INFO("auto proxy to set: %s\n",p);
+                strcpy(http_proxy, p);
+                strcpy(https_proxy, p);
+                strcpy(ftp_proxy, p);
+                strcpy(socks_proxy, p);
+            }
+            fclose(fp_pacfile);
+        }
+        else
+        {
+            ERR("pac file is not wrong! It could be the wrong pac address or pac file format\n");
+            fclose(fp_pacfile);
+        }
+    } 
+    else {
+        ERR("fail to get pacfile fp\n");
+       return -1;
+    }
+
+    remove(pac_tempfile);
+    return 0;
+}
+
+static void get_proxy(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
+{
+    char buf[MAXLEN] = {0,};
+    char buf_port[MAXPORTLEN] = {0,};
+    char buf_proxy[MAXLEN] = {0,};
+    char *buf_proxy_bak;
+    char *proxy;
+    FILE *output;
+    int MAXPROXYLEN = MAXLEN + MAXPORTLEN;
+
+    output = popen("gconftool-2 --get /system/http_proxy/host", "r");
+    if(fscanf(output, "%s", buf) > 0) {
+        snprintf(buf_proxy, MAXLEN, "%s", buf);
+    }
+    pclose(output);
+    
+    output = popen("gconftool-2 --get /system/http_proxy/port", "r");
+    if(fscanf(output, "%s", buf_port) <= 0) {
+        //for abnormal case: if can't find the key of http port, get from environment value.
+        buf_proxy_bak = getenv("http_proxy");
+        INFO("http_proxy from env: %s\n", buf_proxy_bak);
+        if(buf_proxy_bak != NULL) {
+            proxy = malloc(MAXLEN);
+            remove_string(buf_proxy_bak, proxy, HTTP_PREFIX);
+            strncpy(http_proxy, proxy, strlen(proxy)-1);
+            INFO("final http_proxy value: %s\n", http_proxy);
+            free(proxy);
+        }
+        else {
+            INFO("http_proxy is not set on env.\n");
+            pclose(output);
+            return;
+        }
+
+    }
+    else {
+        snprintf(http_proxy, MAXPROXYLEN, "%s:%s", buf_proxy, buf_port);
+        memset(buf_proxy, 0, MAXLEN);
+        INFO("http_proxy: %s\n", http_proxy);
+    }
+    pclose(output);
+
+    memset(buf, 0, MAXLEN);
+
+    output = popen("gconftool-2 --get /system/proxy/secure_host", "r");
+    if(fscanf(output, "%s", buf) > 0) {
+        snprintf(buf_proxy, MAXLEN, "%s", buf);
+    }
+    pclose(output);
+
+    output = popen("gconftool-2 --get /system/proxy/secure_port", "r");
+    if(fscanf(output, "%s", buf) > 0) {
+        snprintf(https_proxy, MAXPROXYLEN, "%s:%s", buf_proxy, buf);
+    }
+    pclose(output);
+    memset(buf, 0, MAXLEN);
+    memset(buf_proxy, 0, MAXLEN);
+    INFO("https_proxy : %s\n", https_proxy);
+
+    output = popen("gconftool-2 --get /system/proxy/ftp_host", "r");
+    if(fscanf(output, "%s", buf) > 0) {
+        snprintf(buf_proxy, MAXLEN, "%s", buf);
+    }
+    pclose(output);
+
+    output = popen("gconftool-2 --get /system/proxy/ftp_port", "r");
+    if(fscanf(output, "%s", buf) > 0) {
+        snprintf(ftp_proxy, MAXPROXYLEN, "%s:%s", buf_proxy, buf);
+    }
+    pclose(output);
+    memset(buf, 0, MAXLEN);
+    memset(buf_proxy, 0, MAXLEN);
+    INFO("ftp_proxy : %s\n", ftp_proxy);
+
+    output = popen("gconftool-2 --get /system/proxy/socks_host", "r");
+    if(fscanf(output, "%s", buf) > 0) {
+        snprintf(buf_proxy, MAXLEN, "%s", buf);
+    }
+    pclose(output);
+
+    output = popen("gconftool-2 --get /system/proxy/socks_port", "r");
+    if(fscanf(output, "%s", buf) > 0) {
+        snprintf(socks_proxy, MAXPROXYLEN, "%s:%s", buf_proxy, buf);
+    }
+    pclose(output);
+    INFO("socks_proxy : %s\n", socks_proxy);
+}
+
+
+void get_host_proxy_os(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
+{
+    char buf[MAXLEN];
+    FILE *output;
+
+    output = popen("gconftool-2 --get /system/proxy/mode", "r");
+    if(fscanf(output, "%s", buf) > 0) {
+        //priority : auto > manual > none       
+        if (strcmp(buf, "auto") == 0) {
+            INFO("AUTO PROXY MODE\n");
+            get_auto_proxy(http_proxy, https_proxy, ftp_proxy, socks_proxy);
+        }
+        else if (strcmp(buf, "manual") == 0) {
+            INFO("MANUAL PROXY MODE\n");
+            get_proxy(http_proxy, https_proxy, ftp_proxy, socks_proxy);
+        }
+        else if (strcmp(buf, "none") == 0) {
+            INFO("DIRECT PROXY MODE\n");
+        }
+    }
+    pclose(output);
+}
diff --git a/tizen/src/osutil-win32.c b/tizen/src/osutil-win32.c
new file mode 100644 (file)
index 0000000..3dbde81
--- /dev/null
@@ -0,0 +1,358 @@
+/* 
+ * Emulator
+ *
+ * Copyright (C) 2012, 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * MunKyu Im <munkyu.im@samsung.com>
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ * HyunJun Son
+ *
+ * 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
+ *
+ */
+
+/**
+  @file     osutil-win32.c
+  @brief    Collection of utilities for win32
+ */
+
+#include "maru_common.h"
+#include "osutil.h"
+#include "emulator.h"
+#include "debug_ch.h"
+#include "maru_err_table.h"
+#include "sdb.h"
+
+#ifndef CONFIG_WIN32
+#error
+#endif
+
+#include <windows.h>
+
+MULTI_DEBUG_CHANNEL (emulator, osutil);
+
+extern char tizen_target_img_path[];
+extern int tizen_base_port;
+
+static const char *pactempfile = ".autoproxy";
+
+void check_vm_lock_os(void)
+{
+    uint32_t port;
+    char *base_port = NULL;
+    char *pBuf;
+    HANDLE hMapFile;
+    for (port = 26100; port < 26200; port += 10) {
+        base_port = g_strdup_printf("%d", port);
+        hMapFile = OpenFileMapping(FILE_MAP_READ, TRUE, base_port);
+        if (hMapFile == NULL) {
+            INFO("port %s is not used.\n", base_port);
+            continue;
+        } else {
+             pBuf = (char *)MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 50);
+            if (pBuf == NULL) {
+                ERR("Could not map view of file (%d).\n", GetLastError());
+                CloseHandle(hMapFile);
+            }
+
+            if (strcmp(pBuf, tizen_target_img_path) == 0) {
+                maru_register_exit_msg(MARU_EXIT_UNKNOWN,
+                    "Can not execute this VM.\n"
+                    "The same name is running now.");
+                UnmapViewOfFile(pBuf);
+                CloseHandle(hMapFile);
+                free(base_port);
+                exit(0);
+            } else {
+                UnmapViewOfFile(pBuf);
+            }
+        }
+
+        CloseHandle(hMapFile);
+        free(base_port);
+    }
+}
+
+void make_vm_lock_os(void)
+{
+    HANDLE hMapFile;
+    char *pBuf;
+    char *port_in_use;
+    char *shared_memory;
+
+    shared_memory = g_strdup_printf("%s", tizen_target_img_path);
+    port_in_use =  g_strdup_printf("%d", tizen_base_port);
+    hMapFile = CreateFileMapping(
+                 INVALID_HANDLE_VALUE, /* use paging file */
+                 NULL,                 /* default security */
+                 PAGE_READWRITE,       /* read/write access */
+                 0,                /* maximum object size (high-order DWORD) */
+                 50,               /* maximum object size (low-order DWORD) */
+                 port_in_use);         /* name of mapping object */
+    if (hMapFile == NULL) {
+        ERR("Could not create file mapping object (%d).\n", GetLastError());
+        return;
+    }
+    pBuf = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 50);
+
+    if (pBuf == NULL) {
+        ERR("Could not map view of file (%d).\n", GetLastError());
+        CloseHandle(hMapFile);
+        return;
+    }
+
+    CopyMemory((PVOID)pBuf, shared_memory, strlen(shared_memory));
+    free(port_in_use);
+    free(shared_memory);
+}
+
+void set_bin_path_os(gchar * exec_argv)
+{
+    gchar link_path[PATH_MAX] = { 0, };
+    gchar *file_name = NULL;
+
+    if (!GetModuleFileName(NULL, link_path, PATH_MAX)) {
+        return;
+    }
+
+    file_name = g_strrstr(link_path, "\\");
+    g_strlcpy(bin_path, link_path, strlen(link_path) - strlen(file_name) + 1);
+
+    g_strlcat(bin_path, "\\", PATH_MAX);
+}
+
+void print_system_info_os(void)
+{
+    INFO("* Windows\n");
+
+    /* Retrieves information about the current os */
+    OSVERSIONINFO osvi;
+    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+    if (GetVersionEx(&osvi)) {
+        INFO("* MajorVersion : %d, MinorVersion : %d, BuildNumber : %d, "
+            "PlatformId : %d, CSDVersion : %s\n", osvi.dwMajorVersion,
+            osvi.dwMinorVersion, osvi.dwBuildNumber,
+            osvi.dwPlatformId, osvi.szCSDVersion);
+    }
+
+    /* Retrieves information about the current system */
+    SYSTEM_INFO sysi;
+    ZeroMemory(&sysi, sizeof(SYSTEM_INFO));
+
+    GetSystemInfo(&sysi);
+    INFO("* Processor type : %d, Number of processors : %d\n",
+            sysi.dwProcessorType, sysi.dwNumberOfProcessors);
+
+    MEMORYSTATUSEX memInfo;
+    memInfo.dwLength = sizeof(MEMORYSTATUSEX);
+    GlobalMemoryStatusEx(&memInfo);
+    INFO("* Total Ram : %llu kB, Free: %lld kB\n",
+            memInfo.ullTotalPhys / 1024, memInfo.ullAvailPhys / 1024);
+}
+
+static int get_auto_proxy(BYTE *url, char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
+{
+    char type[MAXLEN];
+    char proxy[MAXLEN];
+    char line[MAXLEN];
+    FILE *fp_pacfile;
+    char *p = NULL;
+
+    INFO("pac address: %s\n", (char*)url);
+    download_url((char*)url);
+
+    fp_pacfile = fopen(pactempfile, "r");
+    if(fp_pacfile != NULL) {
+        while(fgets(line, MAXLEN, fp_pacfile) != NULL) {
+            if( (strstr(line, "return") != NULL) && (strstr(line, "if") == NULL)) {
+                INFO("line found %s", line);
+                sscanf(line, "%*[^\"]\"%s %s", type, proxy);
+            }
+        }
+
+        if(g_str_has_prefix(type, DIRECT)) {
+            INFO("auto proxy is set to direct mode\n");
+            fclose(fp_pacfile);
+        }
+        else if(g_str_has_prefix(type, PROXY)) {
+            INFO("auto proxy is set to proxy mode\n");
+            INFO("type: %s, proxy: %s\n", type, proxy);
+            p = strtok(proxy, "\";");
+            if(p != NULL) {
+                INFO("auto proxy to set: %s\n",p);
+                strcpy(http_proxy, p);
+                strcpy(https_proxy, p);
+                strcpy(ftp_proxy, p);
+                strcpy(socks_proxy, p);
+            }
+            fclose(fp_pacfile);
+        }
+        else
+        {
+            ERR("pac file is not wrong! It could be the wrong pac address or pac file format\n");
+            fclose(fp_pacfile);
+        }
+    } 
+    else {
+        ERR("fail to get pacfile fp\n");
+        return -1;
+    }
+
+    remove(pactempfile);
+
+    return 0;
+}
+
+void get_host_proxy_os(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
+{
+    HKEY hKey;
+    int nRet;
+    LONG lRet;
+    BYTE *proxyenable, *proxyserver;
+    char *p;
+    char *real_proxy;
+    BYTE *url;
+
+    DWORD dwLength = 0;
+    nRet = RegOpenKeyEx(HKEY_CURRENT_USER,
+            "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
+            0, KEY_QUERY_VALUE, &hKey);
+    if (nRet != ERROR_SUCCESS) {
+        ERR("Failed to open registry from %s\n",
+                "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings");
+        return 0;
+    }
+    //check auto proxy key exists
+    lRet = RegQueryValueEx(hKey, "AutoConfigURL", 0, NULL, NULL, &dwLength);
+    if (lRet != ERROR_SUCCESS && dwLength == 0) {
+        ERR("Failed to query value from %s\n",
+                "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\AutoConfigURL");
+    }
+    else {
+        //if exists
+        url = (char*)malloc(dwLength);
+        if (url == NULL) {
+            ERR( "Failed to allocate a buffer\n");
+        }
+        else {
+            memset(url, 0x00, dwLength);
+            lRet = RegQueryValueEx(hKey, "AutoConfigURL", 0, NULL, url, &dwLength);
+            if (lRet == ERROR_SUCCESS && dwLength != 0) {
+                get_auto_proxy(url, http_proxy, https_proxy, ftp_proxy, socks_proxy);
+                RegCloseKey(hKey);      
+                return 0;
+            }
+        }
+    }
+    //check manual proxy key exists
+    lRet = RegQueryValueEx(hKey, "ProxyEnable", 0, NULL, NULL, &dwLength);
+    if (lRet != ERROR_SUCCESS && dwLength == 0) {
+        ERR(stderr, "Failed to query value from %s\n",
+                "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ProxyEnable");
+        RegCloseKey(hKey);
+        return 0;
+    }
+    proxyenable = (BYTE*)malloc(dwLength);
+    if (proxyenable == NULL) {
+        ERR( "Failed to allocate a buffer\n");
+        RegCloseKey(hKey);
+        return 0;
+    }
+
+    lRet = RegQueryValueEx(hKey, "ProxyEnable", 0, NULL, proxyenable, &dwLength);
+    if (lRet != ERROR_SUCCESS) {
+        free(proxyenable);
+        ERR("Failed to query value from %s\n",
+                "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ProxyEnable");
+        RegCloseKey(hKey);
+        return 0;
+    }
+    if (*(char*)proxyenable == 0) {
+        free(proxyenable);
+        RegCloseKey(hKey);      
+        return 0;
+    }
+
+    dwLength = 0;
+    lRet = RegQueryValueEx(hKey, "ProxyServer", 0, NULL, NULL, &dwLength);
+    if (lRet != ERROR_SUCCESS && dwLength == 0) {
+        ERR("Failed to query value from from %s\n",
+                "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings");
+        RegCloseKey(hKey);      
+        return 0;
+    }
+
+    proxyserver = (BYTE*)malloc(dwLength);
+    if (proxyserver == NULL) {
+        ERR( "Failed to allocate a buffer\n");
+        RegCloseKey(hKey);      
+        return 0;
+    }
+
+    memset(proxyserver, 0x00, dwLength);
+    lRet = RegQueryValueEx(hKey, "ProxyServer", 0, NULL, proxyserver, &dwLength);
+    if (lRet != ERROR_SUCCESS) {
+        free(proxyserver);
+        ERR( "Failed to query value from from %s\n",
+                "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings");
+        RegCloseKey(hKey);
+        return 0;
+    }
+    
+    if((char*)proxyserver != NULL) {
+        INFO("proxy value: %s\n", (char*)proxyserver);
+        real_proxy = malloc(MAXLEN);
+        
+        for(p = strtok((char*)proxyserver, ";"); p; p = strtok(NULL, ";")){
+            if(strstr(p, HTTP_PROTOCOL)) {
+                remove_string(p, real_proxy, HTTP_PROTOCOL);
+                strcpy(http_proxy, real_proxy);
+            }
+            else if(strstr(p, HTTPS_PROTOCOL)) {
+                remove_string(p, real_proxy, HTTPS_PROTOCOL);
+                strcpy(https_proxy, real_proxy);
+            }
+            else if(strstr(p, FTP_PROTOCOL)) {
+                remove_string(p, real_proxy, FTP_PROTOCOL);
+                strcpy(ftp_proxy, real_proxy);
+            }
+            else if(strstr(p, SOCKS_PROTOCOL)) {
+                remove_string(p, real_proxy, SOCKS_PROTOCOL);
+                strcpy(socks_proxy, real_proxy);
+            }
+            else {
+                INFO("all protocol uses the same proxy server: %s\n", p);
+                strcpy(http_proxy, p);
+                strcpy(https_proxy, p);
+                strcpy(ftp_proxy, p);
+                strcpy(socks_proxy, p);
+            }
+        }
+        free(real_proxy);
+    }
+    else {
+        INFO("proxy is null\n");
+        return 0;
+    }
+    RegCloseKey(hKey);
+}
diff --git a/tizen/src/osutil.c b/tizen/src/osutil.c
new file mode 100644 (file)
index 0000000..10877c6
--- /dev/null
@@ -0,0 +1,91 @@
+/* 
+ * Emulator
+ *
+ * Copyright (C) 2012, 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * MunKyu Im <munkyu.im@samsung.com>
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ * HyunJun Son
+ *
+ * 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
+ *
+ */
+
+/**
+  @file     osutil.c
+  @brief    Common functions for osutil
+ */
+
+#include "osutil.h"
+#include "debug_ch.h"
+
+#include <curl/curl.h>
+#include <string.h>
+
+MULTI_DEBUG_CHANNEL(emulator, osutil);
+
+const char *pac_tempfile = ".autoproxy"; 
+
+inline size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) 
+{     
+    size_t written;
+    written = fwrite(ptr, size, nmemb, stream);
+    return written;
+}  
+
+inline void download_url(char *url) 
+{     
+    CURL *curl;     
+    FILE *fp;     
+    CURLcode res;     
+
+    curl = curl_easy_init();
+    if (curl) { 
+        fp = fopen(pac_tempfile,"wb");
+        curl_easy_setopt(curl, CURLOPT_URL, url);
+        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
+        //just in case network does not work.
+        curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 3000);
+        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
+        res = curl_easy_perform(curl);
+        if(res != 0) {
+            ERR("Fail to download pac file: %s\n", url);
+        }
+        curl_easy_cleanup(curl); 
+        fclose(fp);
+    }     
+
+    return; 
+} 
+
+inline void remove_string(char *src, char *dst, const char *toremove)
+{
+    int len = strlen(toremove);
+    int i, j;
+    int max_len = strlen(src);
+
+    for(i = len, j = 0; i < max_len; i++)
+    {
+        dst[j++] = src[i];
+    }
+
+    dst[j] = '\0';
+}
diff --git a/tizen/src/osutil.h b/tizen/src/osutil.h
new file mode 100644 (file)
index 0000000..a0acb9b
--- /dev/null
@@ -0,0 +1,62 @@
+/* 
+ * Emulator
+ *
+ * Copyright (C) 2011, 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * MunKyu Im <munkyu.im@samsung.com>
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ * HyunJun Son
+ *
+ * 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 __OSUTIL_H__
+#define __OSUTIL_H__
+
+#include "maru_common.h"
+
+#define HTTP_PROTOCOL "http="
+#define HTTP_PREFIX "http://"
+#define HTTPS_PROTOCOL "https="
+#define FTP_PROTOCOL "ftp="
+#define SOCKS_PROTOCOL "socks="
+#define DIRECT "DIRECT"
+#define PROXY "PROXY"
+#define MAXPORTLEN 6
+
+extern const char *pac_tempfile; 
+
+void check_vm_lock_os(void);
+void make_vm_lock_os(void);
+
+void set_bin_path_os(gchar *);
+
+void print_system_info_os(void);
+
+void get_host_proxy_os(char *, char *, char *, char *);
+
+inline void download_url(char *);
+inline size_t write_data(void *, size_t, size_t, FILE *);
+inline void remove_string(char *, char *, const char *);
+
+#endif // __OS_UTIL_H__
+
index fa51d18..26bbea8 100644 (file)
 */\r
 \r
 \r
-#ifdef _WIN32\r
-#include <windows.h>\r
-#include <winsock2.h>\r
-#include <ws2tcpip.h>\r
-#else /* !_WIN32 */\r
-#include <sys/ioctl.h>\r
-#include <sys/socket.h>\r
-#include <netinet/in.h>\r
-#include <netinet/tcp.h>\r
-#include <netdb.h>\r
-#endif /* !_WIN32 */\r
-\r
 #include "emulator.h"\r
 #include "net/slirp.h"\r
 #include "qemu_socket.h"\r
 #include "nbd.h"\r
 #include "tizen/src/debug_ch.h"\r
 \r
-//DEFAULT_DEBUG_CHANNEL(qemu);\r
 MULTI_DEBUG_CHANNEL(qemu, sdb);\r
 \r
 extern char tizen_target_path[];\r
-\r
-/* QSOCKET_CALL is used to deal with the fact that EINTR happens pretty\r
- * easily in QEMU since we use SIGALRM to implement periodic timers\r
- */\r
-\r
-#ifdef _WIN32\r
-#  define  QSOCKET_CALL(_ret,_cmd)   \\r
-       do { _ret = (_cmd); } while ( _ret < 0 && WSAGetLastError() == WSAEINTR )\r
-#else\r
-#  define  QSOCKET_CALL(_ret,_cmd)   \\r
-       do { \\r
-               errno = 0; \\r
-               do { _ret = (_cmd); } while ( _ret < 0 && errno == EINTR ); \\r
-       } while (0);\r
-#endif\r
-\r
-#ifdef _WIN32\r
-\r
-#include <errno.h>\r
-\r
-static int  winsock_error;\r
-\r
-#define  WINSOCK_ERRORS_LIST \\r
-       EE(WSA_INVALID_HANDLE,EINVAL,"invalid handle") \\r
-EE(WSA_NOT_ENOUGH_MEMORY,ENOMEM,"not enough memory") \\r
-EE(WSA_INVALID_PARAMETER,EINVAL,"invalid parameter") \\r
-EE(WSAEINTR,EINTR,"interrupted function call") \\r
-EE(WSAEALREADY,EALREADY,"operation already in progress") \\r
-EE(WSAEBADF,EBADF,"bad file descriptor") \\r
-EE(WSAEACCES,EACCES,"permission denied") \\r
-EE(WSAEFAULT,EFAULT,"bad address") \\r
-EE(WSAEINVAL,EINVAL,"invalid argument") \\r
-EE(WSAEMFILE,EMFILE,"too many opened files") \\r
-EE(WSAEWOULDBLOCK,EWOULDBLOCK,"resource temporarily unavailable") \\r
-EE(WSAEINPROGRESS,EINPROGRESS,"operation now in progress") \\r
-EE(WSAEALREADY,EAGAIN,"operation already in progress") \\r
-EE(WSAENOTSOCK,EBADF,"socket operation not on socket") \\r
-EE(WSAEDESTADDRREQ,EDESTADDRREQ,"destination address required") \\r
-EE(WSAEMSGSIZE,EMSGSIZE,"message too long") \\r
-EE(WSAEPROTOTYPE,EPROTOTYPE,"wrong protocol type for socket") \\r
-EE(WSAENOPROTOOPT,ENOPROTOOPT,"bad protocol option") \\r
-EE(WSAEADDRINUSE,EADDRINUSE,"address already in use") \\r
-EE(WSAEADDRNOTAVAIL,EADDRNOTAVAIL,"cannot assign requested address") \\r
-EE(WSAENETDOWN,ENETDOWN,"network is down") \\r
-EE(WSAENETUNREACH,ENETUNREACH,"network unreachable") \\r
-EE(WSAENETRESET,ENETRESET,"network dropped connection on reset") \\r
-EE(WSAECONNABORTED,ECONNABORTED,"software caused connection abort") \\r
-EE(WSAECONNRESET,ECONNRESET,"connection reset by peer") \\r
-EE(WSAENOBUFS,ENOBUFS,"no buffer space available") \\r
-EE(WSAEISCONN,EISCONN,"socket is already connected") \\r
-EE(WSAENOTCONN,ENOTCONN,"socket is not connected") \\r
-EE(WSAESHUTDOWN,ESHUTDOWN,"cannot send after socket shutdown") \\r
-EE(WSAETOOMANYREFS,ETOOMANYREFS,"too many references") \\r
-EE(WSAETIMEDOUT,ETIMEDOUT,"connection timed out") \\r
-EE(WSAECONNREFUSED,ECONNREFUSED,"connection refused") \\r
-EE(WSAELOOP,ELOOP,"cannot translate name") \\r
-EE(WSAENAMETOOLONG,ENAMETOOLONG,"name too long") \\r
-EE(WSAEHOSTDOWN,EHOSTDOWN,"host is down") \\r
-EE(WSAEHOSTUNREACH,EHOSTUNREACH,"no route to host") \\r
-\r
-typedef struct {\r
-       int          winsock;\r
-       int          unix;\r
-       const char*  string;\r
-} WinsockError;\r
-\r
-static const WinsockError  _winsock_errors[] = {\r
-#define  EE(w,u,s)   { w, u, s },\r
-       WINSOCK_ERRORS_LIST\r
-#undef   EE\r
-       { -1, -1, NULL }\r
-};\r
-\r
-/* this function reads the latest winsock error code and updates\r
- * errno to a matching value. It also returns the new value of\r
- * errno.\r
- */\r
-static int _fix_errno( void )\r
-{\r
-       const WinsockError*  werr = _winsock_errors;\r
-       int                  unix = EINVAL;  /* generic error code */\r
-\r
-       winsock_error = WSAGetLastError();\r
-\r
-       for ( ; werr->string != NULL; werr++ ) {\r
-               if (werr->winsock == winsock_error) {\r
-                       unix = werr->unix;\r
-                       break;\r
-               }\r
-       }\r
-       errno = unix;\r
-       return -1;\r
-}\r
-\r
-#else\r
-static int _fix_errno( void )\r
-{\r
-       return -1;\r
-}\r
-\r
-#endif\r
-\r
-#define  SOCKET_CALL(cmd)  \\r
-       int  ret; \\r
-QSOCKET_CALL(ret, (cmd)); \\r
-if (ret < 0) \\r
-return _fix_errno(); \\r
-return ret; \\r
-\r
-int socket_send(int  fd, const void*  buf, int  buflen)\r
-{\r
-       SOCKET_CALL(send(fd, buf, buflen, 0))\r
-}\r
+extern int tizen_base_port;\r
 \r
 #ifdef _WIN32\r
 \r
-       static void\r
-socket_close_handler( void*  _fd )\r
+static void socket_close_handler( void*  _fd )\r
 {\r
        int   fd = (int)_fd;\r
        int   ret;\r
@@ -169,8 +43,7 @@ socket_close_handler( void*  _fd )
        closesocket( fd );\r
 }\r
 \r
-       void\r
-socket_close( int  fd )\r
+void socket_close( int  fd )\r
 {\r
        int  old_errno = errno;\r
 \r
@@ -185,8 +58,7 @@ socket_close( int  fd )
 \r
 #include <unistd.h>\r
 \r
-       void\r
-socket_close( int  fd )\r
+void socket_close( int  fd )\r
 {\r
        int  old_errno = errno;\r
 \r
@@ -341,9 +213,9 @@ int sdb_loopback_client(int port, int type)
 }\r
 \r
 void notify_sdb_daemon_start(void) {\r
-    \r
+\r
     int s;\r
-    /* \r
+    /*\r
      * send a simple message to the SDB host server to tell it we just started.\r
      * it should be listening on port 26099.\r
      */\r
@@ -362,12 +234,14 @@ void notify_sdb_daemon_start(void) {
     /* length is hex host:emulator:port: -> 0x13 = 20 */\r
     sprintf(tmp, "00%2xhost:emulator:%d:%s", 20 + strlen(targetname), tizen_base_port + 1, targetname);\r
     INFO("message to send to SDB server: %s\n", tmp);\r
-    if (socket_send(s, tmp, MAXPACKETLEN) < 0) {\r
+    if (send(s, tmp, MAXPACKETLEN,0) < 0) {\r
         ERR( "message sending to SDB server error!\n");\r
+        perror("sdb.c: ");\r
     }\r
 \r
-    if (s >= 0)\r
+    if (s >= 0){\r
         socket_close(s);\r
-   \r
+    }\r
+\r
     free(targetname);\r
 }\r
index 8c0e719..e85a69b 100644 (file)
 
 #include <errno.h>
 
-#define SDB_HOST_PORT 26099
-
 #ifdef _WIN32
-#  ifndef EINTR
-#    define EINTR        10004
-#  endif
-#  ifndef EAGAIN
-#    define EAGAIN       10035
-#  endif
-#  ifndef EWOULDBLOCK
-#    define EWOULDBLOCK  EAGAIN
-#  endif
-#  ifndef EINPROGRESS
-#    define EINPROGRESS  10036
-#  endif
-#  ifndef EALREADY
-#    define EALREADY     10037
-#  endif
-#  ifndef EDESTADDRREQ
-#    define EDESTADDRREQ 10039
-#  endif
-#  ifndef EMSGSIZE
-#    define EMSGSIZE     10040
-#  endif
-#  ifndef EPROTOTYPE
-#    define EPROTOTYPE   10041
-#  endif
-#  ifndef ENOPROTOOPT
-#    define ENOPROTOOPT  10042
-#  endif
-#  ifndef EAFNOSUPPORT
-#    define EAFNOSUPPORT 10047
-#  endif
-#  ifndef EADDRINUSE
-#    define EADDRINUSE   10048
-#  endif
-#  ifndef EADDRNOTAVAIL
-#    define EADDRNOTAVAIL 10049
-#  endif
-#  ifndef ENETDOWN
-#    define ENETDOWN     10050
-#  endif
-#  ifndef ENETUNREACH
-#    define ENETUNREACH  10051
-#  endif
-#  ifndef ENETRESET
-#    define ENETRESET    10052
-#  endif
-#  ifndef ECONNABORTED
-#    define ECONNABORTED 10053
-#  endif
-#  ifndef ECONNRESET
-#    define ECONNRESET   10054
-#  endif
-#  ifndef ENOBUFS
-#    define ENOBUFS      10055
-#  endif
-#  ifndef EISCONN
-#    define EISCONN      10056
-#  endif
-#  ifndef ENOTCONN
-#    define ENOTCONN     10057
-#  endif
-#  ifndef ESHUTDOWN
-#    define ESHUTDOWN     10058
-#  endif
-#  ifndef ETOOMANYREFS
-#    define ETOOMANYREFS  10059
-#  endif
-#  ifndef ETIMEDOUT
-#    define ETIMEDOUT     10060
-#  endif
-#  ifndef ECONNREFUSED
-#    define ECONNREFUSED  10061
-#  endif
-#  ifndef ELOOP
-#    define ELOOP         10062
-#  endif
-#  ifndef EHOSTDOWN
-#    define EHOSTDOWN     10064
-#  endif
-#  ifndef EHOSTUNREACH
-#    define EHOSTUNREACH  10065
-#  endif
-#endif /* _WIN32 */
+#include <windows.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else /* !_WIN32 */
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+#endif /* !_WIN32 */
+
+
+#define SDB_HOST_PORT 26099
 
 #define SDB_TCP_EMULD_INDEX  3    /* emulator daemon port */
 #define SDB_TCP_OPENGL_INDEX  4   /* opengl server port */
 #define SDB_UDP_SENSOR_INDEX  3   /* sensor server port */
 
-extern int tizen_base_port;
-
 void sdb_setup(void);
 int get_sdb_base_port(void);
 int inet_strtoip(const char*  str, uint32_t  *ip);
index f74021d..0880e75 100644 (file)
                        <class name="org.tizen.emulator.skin.EmulatorShmSkin" />
                </javah>
                <exec dir="native_src" executable="gcc" failifexecutionfails="false">
-                       <arg line="-shared" />
                        <arg line="-c" />
+                       <arg line="-fPIC" />
                        <arg line="share.c" />
                        <arg line="-o" />
-                       <arg line="libshared.so" />
+                       <arg line="shared.o" />
                        <arg line="-I${env.JAVA_JNI_H_INCLUDE_PATH}" />
                        <arg line="-I${env.JAVA_JNI_H_INCLUDE_PATH}/linux" />
-                       <arg line="-fPIC" />
+               </exec>
+               <exec dir="native_src" executable="gcc" failifexecutionfails="false">
+                       <arg line="shared.o" />
+                       <arg line="-shared" />
+                       <arg line="-o" />
+                       <arg line="libshared.so" />
                </exec>
                <delete>
                        <fileset dir="native_src" includes="**/*.h" />
index a67ea6b..a22fd03 100644 (file)
@@ -1,7 +1,7 @@
 /**
+ * Transmit the framebuffer from shared memory by JNI
  *
- *
- * Copyright ( C ) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Contact:
  * GiWoong Kim <giwoong.kim@samsung.com>
 #include "org_tizen_emulator_skin_EmulatorShmSkin.h"
 
 #define MAXLEN 512
-#define SHMKEY 26099
 
 void *shared_memory = (void *)0;
 int shmid;
 
 
 JNIEXPORT jint JNICALL Java_org_tizen_emulator_skin_EmulatorShmSkin_shmget
-  (JNIEnv *env, jobject obj, jint vga_ram_size)
+    (JNIEnv *env, jobject obj, jint shmkey, jint vga_ram_size)
 {
-    void *temp;
-    int keyval;
-    shmid = shmget((key_t)SHMKEY, (size_t)MAXLEN, 0666 | IPC_CREAT);
-    if (shmid == -1) {
-       fprintf(stderr, "share.c: shmget failed\n");
-        exit(1);
-    }
-    
-    temp = shmat(shmid, (char*)0x0, 0);
-    if (temp == (void *)-1) {
-        fprintf(stderr, "share.c: shmat failed\n");
-        exit(1);
-    }
-    keyval = atoi(temp);
-    shmdt(temp);
+    fprintf(stdout, "share.c: shared memory key = %d\n", shmkey);
+    fflush(stdout);
 
-    shmid = shmget((key_t)keyval, (size_t)vga_ram_size, 0666 | IPC_CREAT);
+    shmid = shmget((key_t)shmkey, (size_t)vga_ram_size, 0666 | IPC_CREAT);
     if (shmid == -1) {
+        fprintf(stderr, "share.c: shmget failed\n");
+        fflush(stderr);
         return 1;
     }
 
-    /* We now make the shared memory accessible to the program. */
+    /* We now make the shared memory accessible to the program */
     shared_memory = shmat(shmid, (void *)0, 0);
     if (shared_memory == (void *)-1) {
+        fprintf(stderr, "share.c: shmat failed\n");
+        fflush(stderr);
         return 2;
     }
 
@@ -76,29 +66,42 @@ JNIEXPORT jint JNICALL Java_org_tizen_emulator_skin_EmulatorShmSkin_shmget
 }
 
 JNIEXPORT jint JNICALL Java_org_tizen_emulator_skin_EmulatorShmSkin_shmdt
-  (JNIEnv *env, jobject obj)
+    (JNIEnv *env, jobject obj)
 {
     /* Lastly, the shared memory is detached */
     if (shmdt(shared_memory) == -1) {
+        fprintf(stderr, "share.c: shmdt failed\n");
+        fflush(stderr);
+        perror("share.c: ");
         return 1;
     }
 
+    /*
+    if (shmctl(shmid, IPC_RMID, 0) == -1) {
+        fprintf(stderr, "share.c: shmctl failed\n");
+        fflush(stderr);
+        perror("share.c: ");
+    }
+    */
+
     return 0;
 }
 
 JNIEXPORT jint JNICALL Java_org_tizen_emulator_skin_EmulatorShmSkin_getPixels
-  (JNIEnv *env, jobject obj, jintArray array)
+    (JNIEnv *env, jobject obj, jintArray array)
 {
     int i = 0;
     int len = (*env)->GetArrayLength(env, array);
     if (len <= 0) {
+        fprintf(stderr, "share.c: get length failed\n");
+        fflush(stderr);
         return -1;
     }
 
     int *framebuffer = (int *)shared_memory;
 
     jint value = 0xFFFFFFFF;
-    for(i = 0; i < len; i++) {
+    for (i = 0; i < len; i++) {
         value = framebuffer[i];
         (*env)->SetIntArrayRegion(env, array, i, 1, &value); 
     }
diff --git a/tizen/src/skin/client/resource/images/key-window/scroll_back.png b/tizen/src/skin/client/resource/images/key-window/scroll_back.png
new file mode 100644 (file)
index 0000000..5f8c377
Binary files /dev/null and b/tizen/src/skin/client/resource/images/key-window/scroll_back.png differ
diff --git a/tizen/src/skin/client/resource/images/key-window/scroll_button_down_hover.png b/tizen/src/skin/client/resource/images/key-window/scroll_button_down_hover.png
new file mode 100644 (file)
index 0000000..62f58d1
Binary files /dev/null and b/tizen/src/skin/client/resource/images/key-window/scroll_button_down_hover.png differ
diff --git a/tizen/src/skin/client/resource/images/key-window/scroll_button_down_nml.png b/tizen/src/skin/client/resource/images/key-window/scroll_button_down_nml.png
new file mode 100644 (file)
index 0000000..7ced278
Binary files /dev/null and b/tizen/src/skin/client/resource/images/key-window/scroll_button_down_nml.png differ
diff --git a/tizen/src/skin/client/resource/images/key-window/scroll_button_down_pushed.png b/tizen/src/skin/client/resource/images/key-window/scroll_button_down_pushed.png
new file mode 100644 (file)
index 0000000..68cc7f2
Binary files /dev/null and b/tizen/src/skin/client/resource/images/key-window/scroll_button_down_pushed.png differ
diff --git a/tizen/src/skin/client/resource/images/key-window/scroll_button_up_hover.png b/tizen/src/skin/client/resource/images/key-window/scroll_button_up_hover.png
new file mode 100644 (file)
index 0000000..a362b4e
Binary files /dev/null and b/tizen/src/skin/client/resource/images/key-window/scroll_button_up_hover.png differ
diff --git a/tizen/src/skin/client/resource/images/key-window/scroll_button_up_nml.png b/tizen/src/skin/client/resource/images/key-window/scroll_button_up_nml.png
new file mode 100644 (file)
index 0000000..29882e0
Binary files /dev/null and b/tizen/src/skin/client/resource/images/key-window/scroll_button_up_nml.png differ
diff --git a/tizen/src/skin/client/resource/images/key-window/scroll_button_up_pushed.png b/tizen/src/skin/client/resource/images/key-window/scroll_button_up_pushed.png
new file mode 100644 (file)
index 0000000..6c510c1
Binary files /dev/null and b/tizen/src/skin/client/resource/images/key-window/scroll_button_up_pushed.png differ
diff --git a/tizen/src/skin/client/resource/images/key-window/scroll_thumb.png b/tizen/src/skin/client/resource/images/key-window/scroll_thumb.png
new file mode 100644 (file)
index 0000000..b33ca1f
Binary files /dev/null and b/tizen/src/skin/client/resource/images/key-window/scroll_thumb.png differ
index 112e2a7..418f443 100644 (file)
                 <keyMap>
                     <region left="159" top="552" width="54" height="54"/>
                     <eventInfo>
-                        <keyCode>101</keyCode>
-                        <keyName>HOME</keyName>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
                     </eventInfo>
                     <tooltip>Home</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="362" top="487" width="15" height="70"/>
                     <eventInfo>
-                        <keyCode>103</keyCode>
-                        <keyName>POWER</keyName>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
                     </eventInfo>
                     <tooltip>Power</tooltip>
                 </keyMap>
@@ -31,7 +31,7 @@
                     <region left="362" top="63" width="15" height="70"/>
                     <eventInfo>
                         <keyCode>115</keyCode>
-                        <keyName>VOLUME_UP</keyName>
+                        <keyName>Volume +</keyName>
                     </eventInfo>
                     <tooltip>Volume +</tooltip>
                 </keyMap>
@@ -39,7 +39,7 @@
                     <region left="362" top="140" width="15" height="70"/>
                     <eventInfo>
                         <keyCode>114</keyCode>
-                        <keyName>VOLUME_DOWN</keyName>
+                        <keyName>Volume -</keyName>
                     </eventInfo>
                     <tooltip>Volume -</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="552" top="167" width="54" height="54"/>
                     <eventInfo>
-                        <keyCode>101</keyCode>
-                        <keyName>HOME</keyName>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
                     </eventInfo>
                     <tooltip>Home</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="486" top="3" width="70" height="15"/>
                     <eventInfo>
-                        <keyCode>103</keyCode>
-                        <keyName>POWER</keyName>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
                     </eventInfo>
                     <tooltip>Power</tooltip>
                 </keyMap>
@@ -74,7 +74,7 @@
                     <region left="63" top="3" width="70" height="15"/>
                     <eventInfo>
                         <keyCode>115</keyCode>
-                        <keyName>VOLUME_UP</keyName>
+                        <keyName>Volume +</keyName>
                     </eventInfo>
                     <tooltip>Volume +</tooltip>
                 </keyMap>
@@ -82,7 +82,7 @@
                     <region left="139" top="3" width="70" height="15"/>
                     <eventInfo>
                         <keyCode>114</keyCode>
-                        <keyName>VOLUME_DOWN</keyName>
+                        <keyName>Volume -</keyName>
                     </eventInfo>
                     <tooltip>Volume -</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="167" top="14" width="54" height="54"/>
                     <eventInfo>
-                        <keyCode>101</keyCode>
-                        <keyName>HOME</keyName>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
                     </eventInfo>
                     <tooltip>Home</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="3" top="64" width="15" height="70"/>
                     <eventInfo>
-                        <keyCode>103</keyCode>
-                        <keyName>POWER</keyName>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
                     </eventInfo>
                     <tooltip>Power</tooltip>
                 </keyMap>
                     <region left="3" top="488" width="15" height="70"/>
                     <eventInfo>
                         <keyCode>115</keyCode>
-                        <keyName>VOLUME_UP</keyName>
+                        <keyName>Volume +</keyName>
                     </eventInfo>
                     <tooltip>Volume +</tooltip>
                 </keyMap>
                     <region left="3" top="412" width="15" height="70"/>
                     <eventInfo>
                         <keyCode>114</keyCode>
-                        <keyName>VOLUME_DOWN</keyName>
+                        <keyName>Volume -</keyName>
                     </eventInfo>
                     <tooltip>Volume -</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="14" top="159" width="54" height="54"/>
                     <eventInfo>
-                        <keyCode>101</keyCode>
-                        <keyName>HOME</keyName>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
                     </eventInfo>
                     <tooltip>Home</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="64" top="362" width="70" height="15"/>
                     <eventInfo>
-                        <keyCode>103</keyCode>
-                        <keyName>POWER</keyName>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
                     </eventInfo>
                     <tooltip>Power</tooltip>
                 </keyMap>
                     <region left="488" top="362" width="70" height="15"/>
                     <eventInfo>
                         <keyCode>115</keyCode>
-                        <keyName>VOLUME_UP</keyName>
+                        <keyName>Volume +</keyName>
                     </eventInfo>
                     <tooltip>Volume +</tooltip>
                 </keyMap>
                     <region left="412" top="362" width="70" height="15"/>
                     <eventInfo>
                         <keyCode>114</keyCode>
-                        <keyName>VOLUME_DOWN</keyName>
+                        <keyName>Volume -</keyName>
                     </eventInfo>
                     <tooltip>Volume -</tooltip>
                 </keyMap>
index 6658fd0..34bd212 100644 (file)
                 <keyMap>
                     <region left="238" top="887" width="74" height="74"/>
                     <eventInfo>
-                        <keyCode>101</keyCode>
-                        <keyName>HOME</keyName>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
                     </eventInfo>
                     <tooltip>Home</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="541" top="819" width="20" height="74"/>
                     <eventInfo>
-                        <keyCode>103</keyCode>
-                        <keyName>POWER</keyName>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
                     </eventInfo>
                     <tooltip>Power</tooltip>
                 </keyMap>
@@ -31,7 +31,7 @@
                     <region left="541" top="81" width="20" height="74"/>
                     <eventInfo>
                         <keyCode>115</keyCode>
-                        <keyName>VOLUME_UP</keyName>
+                        <keyName>Volume +</keyName>
                     </eventInfo>
                     <tooltip>Volume +</tooltip>
                 </keyMap>
@@ -39,7 +39,7 @@
                     <region left="541" top="167" width="20" height="74"/>
                     <eventInfo>
                         <keyCode>114</keyCode>
-                        <keyName>VOLUME_DOWN</keyName>
+                        <keyName>Volume -</keyName>
                     </eventInfo>
                     <tooltip>Volume -</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="887" top="249" width="74" height="74"/>
                     <eventInfo>
-                        <keyCode>101</keyCode>
-                        <keyName>HOME</keyName>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
                     </eventInfo>
                     <tooltip>Home</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="818" top="2" width="74" height="20"/>
                     <eventInfo>
-                        <keyCode>103</keyCode>
-                        <keyName>POWER</keyName>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
                     </eventInfo>
                     <tooltip>Power</tooltip>
                 </keyMap>
@@ -74,7 +74,7 @@
                     <region left="80" top="2" width="74" height="20"/>
                     <eventInfo>
                         <keyCode>115</keyCode>
-                        <keyName>VOLUME_UP</keyName>
+                        <keyName>Volume +</keyName>
                     </eventInfo>
                     <tooltip>Volume +</tooltip>
                 </keyMap>
@@ -82,7 +82,7 @@
                     <region left="165" top="2" width="74" height="20"/>
                     <eventInfo>
                         <keyCode>114</keyCode>
-                        <keyName>VOLUME_DOWN</keyName>
+                        <keyName>Volume -</keyName>
                     </eventInfo>
                     <tooltip>Volume -</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="249" top="14" width="74" height="74"/>
                     <eventInfo>
-                        <keyCode>101</keyCode>
-                        <keyName>HOME</keyName>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
                     </eventInfo>
                     <tooltip>Home</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="2" top="84" width="20" height="74"/>
                     <eventInfo>
-                        <keyCode>103</keyCode>
-                        <keyName>POWER</keyName>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
                     </eventInfo>
                     <tooltip>Power</tooltip>
                 </keyMap>
                     <region left="2" top="821" width="20" height="74"/>
                     <eventInfo>
                         <keyCode>115</keyCode>
-                        <keyName>VOLUME_UP</keyName>
+                        <keyName>Volume +</keyName>
                     </eventInfo>
                     <tooltip>Volume +</tooltip>
                 </keyMap>
                     <region left="2" top="735" width="20" height="74"/>
                     <eventInfo>
                         <keyCode>114</keyCode>
-                        <keyName>VOLUME_DOWN</keyName>
+                        <keyName>Volume -</keyName>
                     </eventInfo>
                     <tooltip>Volume -</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="15" top="239" width="74" height="74"/>
                     <eventInfo>
-                        <keyCode>101</keyCode>
-                        <keyName>HOME</keyName>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
                     </eventInfo>
                     <tooltip>Home</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="84" top="539" width="74" height="20"/>
                     <eventInfo>
-                        <keyCode>103</keyCode>
-                        <keyName>POWER</keyName>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
                     </eventInfo>
                     <tooltip>Power</tooltip>
                 </keyMap>
                     <region left="822" top="539" width="74" height="20"/>
                     <eventInfo>
                         <keyCode>115</keyCode>
-                        <keyName>VOLUME_UP</keyName>
+                        <keyName>Volume +</keyName>
                     </eventInfo>
                     <tooltip>Volume +</tooltip>
                 </keyMap>
                     <region left="735" top="539" width="74" height="20"/>
                     <eventInfo>
                         <keyCode>114</keyCode>
-                        <keyName>VOLUME_DOWN</keyName>
+                        <keyName>Volume -</keyName>
                     </eventInfo>
                     <tooltip>Volume -</tooltip>
                 </keyMap>
index 16947ce..c2b2b0d 100644 (file)
                 <keyMap>
                     <region left="310" top="1139" width="84" height="84"/>
                     <eventInfo>
-                        <keyCode>101</keyCode>
-                        <keyName>HOME</keyName>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
                     </eventInfo>
                     <tooltip>Home</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="690" top="1055" width="24" height="88"/>
                     <eventInfo>
-                        <keyCode>103</keyCode>
-                        <keyName>POWER</keyName>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
                     </eventInfo>
                     <tooltip>Power</tooltip>
                 </keyMap>
@@ -31,7 +31,7 @@
                     <region left="690" top="101" width="24" height="88"/>
                     <eventInfo>
                         <keyCode>115</keyCode>
-                        <keyName>VOLUME_UP</keyName>
+                        <keyName>Volume +</keyName>
                     </eventInfo>
                     <tooltip>Volume +</tooltip>
                 </keyMap>
@@ -39,7 +39,7 @@
                     <region left="690" top="194" width="24" height="88"/>
                     <eventInfo>
                         <keyCode>114</keyCode>
-                        <keyName>VOLUME_DOWN</keyName>
+                        <keyName>Volume -</keyName>
                     </eventInfo>
                     <tooltip>Volume -</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="1138" top="321" width="84" height="84"/>
                     <eventInfo>
-                        <keyCode>101</keyCode>
-                        <keyName>HOME</keyName>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
                     </eventInfo>
                     <tooltip>Home</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="1054" top="1" width="88" height="24"/>
                     <eventInfo>
-                        <keyCode>103</keyCode>
-                        <keyName>POWER</keyName>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
                     </eventInfo>
                     <tooltip>Power</tooltip>
                 </keyMap>
@@ -74,7 +74,7 @@
                     <region left="99" top="1" width="88" height="24"/>
                     <eventInfo>
                         <keyCode>115</keyCode>
-                        <keyName>VOLUME_UP</keyName>
+                        <keyName>Volume +</keyName>
                     </eventInfo>
                     <tooltip>Volume +</tooltip>
                 </keyMap>
@@ -82,7 +82,7 @@
                     <region left="194" top="1" width="88" height="24"/>
                     <eventInfo>
                         <keyCode>114</keyCode>
-                        <keyName>VOLUME_DOWN</keyName>
+                        <keyName>Volume -</keyName>
                     </eventInfo>
                     <tooltip>Volume -</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="320" top="24" width="84" height="84"/>
                     <eventInfo>
-                        <keyCode>101</keyCode>
-                        <keyName>HOME</keyName>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
                     </eventInfo>
                     <tooltip>Home</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="1" top="106" width="24" height="88"/>
                     <eventInfo>
-                        <keyCode>103</keyCode>
-                        <keyName>POWER</keyName>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
                     </eventInfo>
                     <tooltip>Power</tooltip>
                 </keyMap>
                     <region left="1" top="1059" width="24" height="88"/>
                     <eventInfo>
                         <keyCode>115</keyCode>
-                        <keyName>VOLUME_UP</keyName>
+                        <keyName>Volume +</keyName>
                     </eventInfo>
                     <tooltip>Volume +</tooltip>
                 </keyMap>
                     <region left="1" top="964" width="24" height="88"/>
                     <eventInfo>
                         <keyCode>114</keyCode>
-                        <keyName>VOLUME_DOWN</keyName>
+                        <keyName>Volume -</keyName>
                     </eventInfo>
                     <tooltip>Volume -</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="23" top="310" width="84" height="84"/>
                     <eventInfo>
-                        <keyCode>101</keyCode>
-                        <keyName>HOME</keyName>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
                     </eventInfo>
                     <tooltip>Home</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="105" top="690" width="88" height="24"/>
                     <eventInfo>
-                        <keyCode>103</keyCode>
-                        <keyName>POWER</keyName>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
                     </eventInfo>
                     <tooltip>Power</tooltip>
                 </keyMap>
                     <region left="1058" top="690" width="88" height="24"/>
                     <eventInfo>
                         <keyCode>115</keyCode>
-                        <keyName>VOLUME_UP</keyName>
+                        <keyName>Volume +</keyName>
                     </eventInfo>
                     <tooltip>Volume +</tooltip>
                 </keyMap>
                     <region left="965" top="690" width="88" height="24"/>
                     <eventInfo>
                         <keyCode>114</keyCode>
-                        <keyName>VOLUME_DOWN</keyName>
+                        <keyName>Volume -</keyName>
                     </eventInfo>
                     <tooltip>Volume -</tooltip>
                 </keyMap>
index c54e83d..aa0c011 100644 (file)
                 <keyMap>
                     <region left="390" top="1401" width="84" height="84"/>
                     <eventInfo>
-                        <keyCode>101</keyCode>
-                        <keyName>HOME</keyName>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
                     </eventInfo>
                     <tooltip>Home</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="841" top="1309" width="24" height="96"/>
                     <eventInfo>
-                        <keyCode>103</keyCode>
-                        <keyName>POWER</keyName>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
                     </eventInfo>
                     <tooltip>Power</tooltip>
                 </keyMap>
@@ -31,7 +31,7 @@
                     <region left="841" top="108" width="24" height="96"/>
                     <eventInfo>
                         <keyCode>115</keyCode>
-                        <keyName>VOLUME_UP</keyName>
+                        <keyName>Volume +</keyName>
                     </eventInfo>
                     <tooltip>Volume +</tooltip>
                 </keyMap>
@@ -39,7 +39,7 @@
                     <region left="841" top="219" width="24" height="96"/>
                     <eventInfo>
                         <keyCode>114</keyCode>
-                        <keyName>VOLUME_DOWN</keyName>
+                        <keyName>Volume -</keyName>
                     </eventInfo>
                     <tooltip>Volume -</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="1400" top="392" width="84" height="84"/>
                     <eventInfo>
-                        <keyCode>101</keyCode>
-                        <keyName>HOME</keyName>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
                     </eventInfo>
                     <tooltip>Home</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="1308" top="2" width="96" height="24"/>
                     <eventInfo>
-                        <keyCode>103</keyCode>
-                        <keyName>POWER</keyName>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
                     </eventInfo>
                     <tooltip>Power</tooltip>
                 </keyMap>
@@ -74,7 +74,7 @@
                     <region left="108" top="2" width="96" height="24"/>
                     <eventInfo>
                         <keyCode>115</keyCode>
-                        <keyName>VOLUME_UP</keyName>
+                        <keyName>Volume +</keyName>
                     </eventInfo>
                     <tooltip>Volume +</tooltip>
                 </keyMap>
@@ -82,7 +82,7 @@
                     <region left="217" top="2" width="96" height="24"/>
                     <eventInfo>
                         <keyCode>114</keyCode>
-                        <keyName>VOLUME_DOWN</keyName>
+                        <keyName>Volume -</keyName>
                     </eventInfo>
                     <tooltip>Volume -</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="390" top="30" width="84" height="84"/>
                     <eventInfo>
-                        <keyCode>101</keyCode>
-                        <keyName>HOME</keyName>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
                     </eventInfo>
                     <tooltip>Home</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="2" top="110" width="24" height="96"/>
                     <eventInfo>
-                        <keyCode>103</keyCode>
-                        <keyName>POWER</keyName>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
                     </eventInfo>
                     <tooltip>Power</tooltip>
                 </keyMap>
                     <region left="2" top="1310" width="24" height="96"/>
                     <eventInfo>
                         <keyCode>115</keyCode>
-                        <keyName>VOLUME_UP</keyName>
+                        <keyName>Volume +</keyName>
                     </eventInfo>
                     <tooltip>Volume +</tooltip>
                 </keyMap>
                     <region left="2" top="1200" width="24" height="96"/>
                     <eventInfo>
                         <keyCode>114</keyCode>
-                        <keyName>VOLUME_DOWN</keyName>
+                        <keyName>Volume -</keyName>
                     </eventInfo>
                     <tooltip>Volume -</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="28" top="391" width="84" height="84"/>
                     <eventInfo>
-                        <keyCode>101</keyCode>
-                        <keyName>HOME</keyName>
+                        <keyCode>139</keyCode>
+                        <keyName>Home</keyName>
                     </eventInfo>
                     <tooltip>Home</tooltip>
                 </keyMap>
                 <keyMap>
                     <region left="109" top="841" width="96" height="24"/>
                     <eventInfo>
-                        <keyCode>103</keyCode>
-                        <keyName>POWER</keyName>
+                        <keyCode>116</keyCode>
+                        <keyName>Power</keyName>
                     </eventInfo>
                     <tooltip>Power</tooltip>
                 </keyMap>
                     <region left="1309" top="841" width="96" height="24"/>
                     <eventInfo>
                         <keyCode>115</keyCode>
-                        <keyName>VOLUME_UP</keyName>
+                        <keyName>Volume +</keyName>
                     </eventInfo>
                     <tooltip>Volume +</tooltip>
                 </keyMap>
                     <region left="1199" top="841" width="96" height="24"/>
                     <eventInfo>
                         <keyCode>114</keyCode>
-                        <keyName>VOLUME_DOWN</keyName>
+                        <keyName>Volume -</keyName>
                     </eventInfo>
                     <tooltip>Volume -</tooltip>
                 </keyMap>
index 0b98aec..82cee64 100644 (file)
@@ -8,14 +8,14 @@
             <keyMapList>
                 <keyMap>
                     <eventInfo>
-                        <keyCode>101</keyCode>
+                        <keyCode>139</keyCode>
                         <keyName>Home</keyName>
                     </eventInfo>
                     <tooltip>Home</tooltip>
                 </keyMap>
                 <keyMap>
                     <eventInfo>
-                        <keyCode>103</keyCode>
+                        <keyCode>116</keyCode>
                         <keyName>Power</keyName>
                     </eventInfo>
                     <tooltip>Power</tooltip>
index b7ebb41..ccc6c90 100644 (file)
@@ -53,7 +53,10 @@ public class EmulatorFingers {
        private static final int GREEN_MASK = 0x00FF0000;
        private static final int BLUE_MASK = 0xFF000000;
        private static final int COLOR_DEPTH = 32;
-       private Logger logger = SkinLogger.getSkinLogger( EmulatorFingers.class ).getLogger();
+
+       private Logger logger =
+                       SkinLogger.getSkinLogger(EmulatorFingers.class).getLogger();
+
        private int multiTouchEnable;
        private int maxTouchPoint;
        protected int fingerCnt;
@@ -69,18 +72,18 @@ public class EmulatorFingers {
        protected SocketCommunicator communicator;
        protected EmulatorSkin emulatorSkin;
        ArrayList<FingerPoint> FingerPointList;
-       
+
        EmulatorSkinState currentState;
-       
+
        EmulatorFingers(EmulatorSkinState currentState) {
                this.currentState = currentState;
                initMultiTouchState();
        }
-       
-        protected void setCommunicator(SocketCommunicator communicator) {
+
+       protected void setCommunicator(SocketCommunicator communicator) {
                 this.communicator = communicator;
         }
-       
+
        //private fingerPointSurface;
        protected class FingerPoint {
                int id;
@@ -88,14 +91,14 @@ public class EmulatorFingers {
                int originY;
                int x;
                int y;
-               
+
                FingerPoint(int originX, int originY, int x, int y) {
                        this.originX = originX;
                        this.originY = -originY;
                        this.x = x;
                        this.y = y;
                }
-               
+
                FingerPoint(int id, int originX, int originY, int x, int y) {
                        this.id = id;
                        this.originX = originX;
@@ -104,24 +107,26 @@ public class EmulatorFingers {
                        this.y = y;
                }
        }
-       
+
        public FingerPoint getFingerPointFromSlot(int index) {
-               if(index < 0 || index > this.fingerCntMax) {
+               if (index < 0 || index > this.fingerCntMax) {
                        return null;
                }
+
                return FingerPointList.get(index);
        }
-       
+
        public FingerPoint getFingerPointSearch(int x, int y) {
                int i;
                FingerPoint fingerPoint = null;
-               int fingerRegion = (this.fingerPointSize ) + 2;
+               int fingerRegion = (this.fingerPointSize) + 2;
                //logger.info("x: "+x+ "y: "+ y + " fingerRegion: " + fingerRegion);
-               for(i = this.fingerCnt -1; i >= 0; i--) {
+
+               for (i = this.fingerCnt - 1; i >= 0; i--) {
                        fingerPoint = getFingerPointFromSlot(i);
-                       
-                       if(fingerPoint != null) {
-                               if(x >= (fingerPoint.x - fingerRegion) &&
+
+                       if (fingerPoint != null) {
+                               if (x >= (fingerPoint.x - fingerRegion) &&
                                                x < (fingerPoint.x + fingerRegion) &&
                                                y >= (fingerPoint.y - fingerRegion) &&
                                                y < (fingerPoint.y + fingerRegion)) {
@@ -130,372 +135,408 @@ public class EmulatorFingers {
                                }
                        }
                }
+
                return null;
        }
-       
+
        protected void setEmulatorSkin(EmulatorSkin emulatorSkin) {
                this.emulatorSkin = emulatorSkin;
        }
-       
+
        public void initMultiTouchState() {
                this.multiTouchEnable = 0;
                this.fingerCntMax = this.currentState.getMaxTouchPoint();
-               if(this.fingerCntMax > MAX_FINGER_CNT) {
+
+               if (this.fingerCntMax > MAX_FINGER_CNT) {
                        this.fingerCntMax = MAX_FINGER_CNT;
                        setMaxTouchPoint(this.fingerCntMax);
                }
+
                logger.info("maxTouchPoint="+ this.fingerCntMax);
                this.fingerCnt = 0;
-               
+
                if (this.fingerSlot != null) {
                        this.fingerSlot = null;
                }
-               
+
                FingerPointList = new ArrayList<FingerPoint>();
                int i;
-               for(i = 0; i <= fingerCntMax; i++) {
+               for (i = 0; i <= fingerCntMax; i++) {
                        FingerPointList.add(new FingerPoint(-1, -1, -1, -1));
                } 
                this.fingerPointSize = 32;
-               this.fingerPointSizeHalf = this.fingerPointSize / 2 ;
-               
+               this.fingerPointSizeHalf = this.fingerPointSize / 2;
+
                this.fingerPointOutlineColor = new Color(Display.getCurrent(), 0xDD, 0xDD, 0xDD);
                this.fingerPointColor = new Color(Display.getCurrent(), 0x0F, 0x0F, 0x0F);
                PaletteData palette = new PaletteData(RED_MASK, GREEN_MASK, BLUE_MASK);
-               
-               this.imageData = new ImageData(fingerPointSize + 4, fingerPointSize + 4, COLOR_DEPTH, palette);
+
+               this.imageData = new ImageData(
+                               fingerPointSize + 4, fingerPointSize + 4, COLOR_DEPTH, palette);
                this.imageData.transparentPixel = 0;
                this.fingerSlotimage = new Image(Display.getCurrent(), imageData);
 
                GC gc = new GC(this.fingerSlotimage);
-               
+
                gc.setForeground(this.fingerPointOutlineColor);
-               gc.drawOval(0, 0, this.fingerPointSize+2 , this.fingerPointSize+2);
-               
+               gc.drawOval(0, 0, this.fingerPointSize + 2, this.fingerPointSize + 2);
+
                gc.setBackground(this.fingerPointColor);
-               gc.fillOval(2, 2 , this.fingerPointSize, this.fingerPointSize);
-               
+               gc.fillOval(2, 2, this.fingerPointSize, this.fingerPointSize);
+
                gc.dispose();
        }
-       
+
        public void setMultiTouchEnable(int multiTouchEnable) {
                this.multiTouchEnable = multiTouchEnable;
        }
-       
+
        public int getMultiTouchEnable() {
                return this.multiTouchEnable;
        }
-       
+
        protected int addFingerPoint(int originX, int originY, int x, int y) {
                if (this.fingerCnt == this.fingerCntMax) {
-                       logger.info("support multi-touch up to " + this.fingerCntMax +" fingers");
+                       logger.info("support multi-touch up to "
+                                       + this.fingerCntMax + " fingers");
                        return -1;
                }
                this.fingerCnt += 1;
-               
+
                FingerPointList.get(fingerCnt -1).id = this.fingerCnt;
                FingerPointList.get(fingerCnt -1).originX = originX;
                FingerPointList.get(fingerCnt -1).originY = originY;
                FingerPointList.get(fingerCnt -1).x = x;
                FingerPointList.get(fingerCnt -1).y = y;
                logger.info(this.fingerCnt + " finger touching");
-               
+
                return this.fingerCnt;
-               
        }
-       
+
        protected void drawImage(PaintEvent e, int currentAngle) {
                //by mq
-               for(int i=0; i < this.fingerCnt; i++) {
+               for (int i = 0; i < this.fingerCnt; i++) {
                        this.fingerSlot = this.getFingerPointFromSlot(i);       
                        e.gc.setAlpha(0x7E);
                //      logger.info("OriginX: "+ this.fingerSlot.originX + ",OriginY: " + (this.fingerSlot.originY));
                //      logger.info("x: "+ this.fingerSlot.x + ",y: " + (this.fingerSlot.y));
-                       
+
                        e.gc.drawImage(this.fingerSlotimage, 
                                        this.fingerSlot.originX - fingerPointSizeHalf - 2,
                                        this.fingerSlot.originY - fingerPointSizeHalf - 2);
                        e.gc.setAlpha(0xFF);
                }
        }
-       
-       public void maruFingerProcessing1(int touchType, int originX, int originY, int x, int y) {
+
+       public void maruFingerProcessing1(
+                       int touchType, int originX, int originY, int x, int y) {
                FingerPoint finger = null;
                MouseEventData mouseEventData;
-               if (touchType == MouseEventType.PRESS.value() || touchType == MouseEventType.DRAG.value()) { /* pressed */
-               if (grabFingerID > 0) {
-                   finger = getFingerPointFromSlot(grabFingerID - 1); 
-                   if (finger != null) {
-                       finger.originX = originX;
-                       finger.originY = originY;
-                       finger.x = x;
-                       finger.y = y;
-                       if (finger.id != 0) {
-                               logger.info(String.format("id %d finger multi-touch dragging = (%d, %d)", this.grabFingerID, x, y));
-                               mouseEventData = new MouseEventData(
+
+               if (touchType == MouseEventType.PRESS.value() ||
+                               touchType == MouseEventType.DRAG.value()) { /* pressed */
+                       if (grabFingerID > 0) {
+                               finger = getFingerPointFromSlot(grabFingerID - 1);
+                               if (finger != null) {
+                                       finger.originX = originX;
+                                       finger.originY = originY;
+                                       finger.x = x;
+                                       finger.y = y;
+
+                                       if (finger.id != 0) {
+                                               logger.info(String.format(
+                                                               "id %d finger multi-touch dragging = (%d, %d)",
+                                                               this.grabFingerID, x, y));
+
+                                               mouseEventData = new MouseEventData(
                                                                MouseButtonType.LEFT.value(), MouseEventType.PRESS.value(),
-                                                               originX, originY, x, y, grabFingerID -1);
-                                               communicator.sendToQEMU( SendCommand.SEND_MOUSE_EVENT, mouseEventData );                                
-                       }   
-                   }   
-                   return;
-               }
-               
-               if(this.fingerCnt == 0) {
-                       //first finger touch input
-                       if(addFingerPoint(originX, originY, x, y) == -1) {
-                               return;
-                       }
-          
+                                                               originX, originY, x, y, grabFingerID - 1);
+                                               communicator.sendToQEMU(SendCommand.SEND_MOUSE_EVENT, mouseEventData);
+                                       } 
+                               }
+
+                               return;
+                       }
+
+                       if (this.fingerCnt == 0)
+                       { /* first finger touch input */
+                               if (addFingerPoint(originX, originY, x, y) == -1) {
+                                       return;
+                               }
+
                                mouseEventData = new MouseEventData(
                                                MouseButtonType.LEFT.value(), MouseEventType.PRESS.value(),
                                                originX, originY, x, y, 0);
-                               communicator.sendToQEMU( SendCommand.SEND_MOUSE_EVENT, mouseEventData );
-               }
-               //check the position of previous touch event
-               else if ((finger = getFingerPointSearch(x, y)) != null) {
-                       //finger point is selected
-                       this.grabFingerID = finger.id;
-                       logger.info(String.format("id %d finger is grabbed\n", this.grabFingerID));
-               }
-               //Let's assume that this event is last finger touch input
-               else if (this.fingerCnt == this.fingerCntMax) {
-                       finger = getFingerPointFromSlot(this.fingerCntMax -1);
-                       if(finger != null) {
+                               communicator.sendToQEMU(SendCommand.SEND_MOUSE_EVENT, mouseEventData);
+                       }
+                       else if ((finger = getFingerPointSearch(x, y)) != null)
+                       { /* check the position of previous touch event */
+                               /* finger point is selected */
+                               this.grabFingerID = finger.id;
+                               logger.info(String.format("id %d finger is grabbed\n", this.grabFingerID));
+                       }
+                       else if (this.fingerCnt == this.fingerCntMax)
+                       { /* Let's assume that this event is last finger touch input */
+                               finger = getFingerPointFromSlot(this.fingerCntMax - 1);
+                               if (finger != null) {
                                mouseEventData = new MouseEventData(
                                                        MouseButtonType.LEFT.value(), MouseEventType.RELEASE.value(),
-                                                       originX, originY, finger.x, finger.y, this.fingerCntMax -1);
-                                       communicator.sendToQEMU( SendCommand.SEND_MOUSE_EVENT, mouseEventData );
-                               
+                                                       originX, originY, finger.x, finger.y, this.fingerCntMax - 1);
+                                       communicator.sendToQEMU(SendCommand.SEND_MOUSE_EVENT, mouseEventData);
+
                                        finger.originX = originX;
                                        finger.originY = originY;
                                        finger.x = x;
                                        finger.y = y;
-                                       if(finger.id != 0) {
+
+                                       if (finger.id != 0) {
                                                mouseEventData = new MouseEventData(
                                                                MouseButtonType.LEFT.value(), MouseEventType.PRESS.value(),
-                                                               originX, originY, x, y, this.fingerCntMax -1);
-                                               communicator.sendToQEMU( SendCommand.SEND_MOUSE_EVENT, mouseEventData );
-                                       
+                                                               originX, originY, x, y, this.fingerCntMax - 1);
+                                               communicator.sendToQEMU(SendCommand.SEND_MOUSE_EVENT, mouseEventData);
                                        }
-                       }
-               }
-               else { //one more finger
-                       addFingerPoint(originX, originY, x, y);
-                       mouseEventData = new MouseEventData(
+                               }
+                       }
+                       else
+                       { /* one more finger */
+                               addFingerPoint(originX, originY, x, y);
+                               mouseEventData = new MouseEventData(
                                                MouseButtonType.LEFT.value(), MouseEventType.PRESS.value(),
-                                               originX, originY, x, y, this.fingerCnt -1);
-                               communicator.sendToQEMU( SendCommand.SEND_MOUSE_EVENT, mouseEventData );
-                               
-               }   
-               }
-               else if (touchType == MouseEventType.RELEASE.value()) { /* released */
+                                               originX, originY, x, y, this.fingerCnt - 1);
+                               communicator.sendToQEMU(SendCommand.SEND_MOUSE_EVENT, mouseEventData);
+                       }
+               } else if (touchType == MouseEventType.RELEASE.value()) { /* released */
                        logger.info("mouse up for multi touch");
                        this.grabFingerID = 0;
                }
-
        }
-       
-       public void maruFingerProcessing2(int touchType, int originX, int originY, int x, int y) {
+
+       public void maruFingerProcessing2(
+                       int touchType, int originX, int originY, int x, int y) {
                FingerPoint finger = null;
                MouseEventData mouseEventData;
-               if (touchType == MouseEventType.PRESS.value() || touchType == MouseEventType.DRAG.value()) { /* pressed */
-                       if(this.grabFingerID > 0) {
+
+               if (touchType == MouseEventType.PRESS.value() ||
+                               touchType == MouseEventType.DRAG.value()) { /* pressed */
+                       if (this.grabFingerID > 0) {
                                finger = getFingerPointFromSlot(grabFingerID - 1);
-                               if(finger != null) {
+                               if (finger != null) {
                                        int originDistanceX = originX - finger.originX;
                                        int originDistanceY = originY - finger.originY;
                                        int distanceX = x - finger.x;
                                        int distanceY = y - finger.y;
-                                       
+
                                        int currrntScreenW = currentState.getCurrentResolutionWidth();
                                        int currrntScreenH = currentState.getCurrentResolutionHeight();
                                        int tempFingerX, tempFingerY;
-                                       
+
                                        int i;
                                        /* bounds checking */                                             
-                       for(i = 0; i < this.fingerCnt; i++) {   
-                           finger = getFingerPointFromSlot(i);                       
-                           if (finger != null) {                                         
-                               tempFingerX = finger.x + distanceX;                   
-                               tempFingerY = finger.y + distanceY;                   
-                               if (tempFingerX > currrntScreenW || tempFingerX < 0
-                                   || tempFingerY > currrntScreenH || tempFingerY < 0) {
-                                       logger.info(String.format("id %d finger is out of bounds (%d, %d)\n", i + 1, tempFingerX, tempFingerY));
-                                       return;                                               
-                               } 
-                           }
-                       }
-
-                       for(i = 0; i < this.fingerCnt; i++) {   
-                           finger = getFingerPointFromSlot(i);
-
-                           if (finger != null) {
-                               finger.originX += originDistanceX;
-                               finger.originY += originDistanceY;
-                               finger.x += distanceX;
-                               finger.y += distanceY;
-                               if (finger.id != 0) {
-                                       mouseEventData = new MouseEventData(
-                                                               MouseButtonType.LEFT.value(), MouseEventType.PRESS.value(),
-                                                               originX, originY, finger.x, finger.y, i);
-                                               communicator.sendToQEMU( SendCommand.SEND_MOUSE_EVENT, mouseEventData );        
-                                               //logger.info(String.format("id %d finger multi-touch dragging = (%d, %d)", i + 1, finger.x, finger.y));
-                               }
-                               try {
+                                       for (i = 0; i < this.fingerCnt; i++) {
+                                               finger = getFingerPointFromSlot(i);
+                                               if (finger != null) {
+                                                       tempFingerX = finger.x + distanceX;
+                                                       tempFingerY = finger.y + distanceY;
+
+                                                       if (tempFingerX > currrntScreenW || tempFingerX < 0 ||
+                                                                       tempFingerY > currrntScreenH || tempFingerY < 0) {
+                                                               logger.info(String.format(
+                                                                               "id %d finger is out of bounds (%d, %d)\n",
+                                                                               i + 1, tempFingerX, tempFingerY));
+                                                               return;
+                                                       }
+                                               }
+                                       }
+
+                                       for (i = 0; i < this.fingerCnt; i++) {
+                                               finger = getFingerPointFromSlot(i);
+                                               if (finger != null) {
+                                                       finger.originX += originDistanceX;
+                                                       finger.originY += originDistanceY;
+                                                       finger.x += distanceX;
+                                                       finger.y += distanceY;
+
+                                                       if (finger.id != 0) {
+                                                               mouseEventData = new MouseEventData(
+                                                                               MouseButtonType.LEFT.value(), MouseEventType.PRESS.value(),
+                                                                               originX, originY, finger.x, finger.y, i);
+                                                               communicator.sendToQEMU(SendCommand.SEND_MOUSE_EVENT, mouseEventData);
+
+                                                               /* logger.info(String.format(
+                                                                               "id %d finger multi-touch dragging = (%d, %d)",
+                                                                               i + 1, finger.x, finger.y));*/
+                                                       }
+
+                                                       try {
                                                                Thread.sleep(2);
                                                        } catch (InterruptedException e) {
                                                                e.printStackTrace();
-                                               
                                                        }
-                           }
-                       }
-                   }
-                   return;
-               }
-                       
+                                               }
+                                       }
+                               }
+
+                               return;
+                       }
+
                        if (this.fingerCnt == 0)
-                       { //first finger touch input                                              
+                       { /* first finger touch input */
                                if (this.addFingerPoint(originX, originY, x, y) == -1) {
-                               return;
-                       }
+                                       return;
+                               }
+
                                mouseEventData = new MouseEventData(
                                                MouseButtonType.LEFT.value(), MouseEventType.PRESS.value(),
                                                originX, originY, x, y, 0);
-                               communicator.sendToQEMU( SendCommand.SEND_MOUSE_EVENT, mouseEventData );                        
-                   }
-                   else if((finger = this.getFingerPointSearch(x, y)) != null) //check the position of previous touch event
-                   {
-                       //finger point is selected                                            
-                       this.grabFingerID = finger.id;          
+                               communicator.sendToQEMU(SendCommand.SEND_MOUSE_EVENT, mouseEventData);
+                       }
+                       else if ((finger = this.getFingerPointSearch(x, y)) != null)
+                       { /* check the position of previous touch event */
+                               /* finger point is selected */
+                               this.grabFingerID = finger.id;
                        logger.info(String.format("id %d finger is grabbed\n", this.grabFingerID));
-                  
-               }       
-               else if(this.fingerCnt == this.fingerCntMax) //Let's assume that this event is last finger touch input
-               {       
-                   //do nothing
-               }       
-               else //one more finger                                                    
-               {   
-                   addFingerPoint(originX, originY, x, y);                         
-                   mouseEventData = new MouseEventData(
+                       }
+                       else if (this.fingerCnt == this.fingerCntMax)
+                       {  /* Let's assume that this event is last finger touch input */
+                               /* do nothing */
+                       }
+                       else /* one more finger */
+                       {
+                               addFingerPoint(originX, originY, x, y);
+                               mouseEventData = new MouseEventData(
                                                MouseButtonType.LEFT.value(), MouseEventType.PRESS.value(),
-                                               originX, originY, x, y, this.fingerCnt -1);
-                               communicator.sendToQEMU( SendCommand.SEND_MOUSE_EVENT, mouseEventData );                                            
-                       }       
-               }else if (touchType == MouseEventType.RELEASE.value()) { /* released */
+                                               originX, originY, x, y, this.fingerCnt - 1);
+                               communicator.sendToQEMU(SendCommand.SEND_MOUSE_EVENT, mouseEventData);
+                       }
+               } else if (touchType == MouseEventType.RELEASE.value()) { /* released */
                        logger.info("mouse up for multi touch");
                        this.grabFingerID = 0;
-               }       
-
+               }
        }
-       
-       private Boolean CalculateOriginCoordinates(int ScaledLcdWitdh, int ScaledLcdHeight, double scaleFactor, int rotationType, FingerPoint finger) {
-           
+
+       private Boolean CalculateOriginCoordinates(
+                       int ScaledLcdWitdh, int ScaledLcdHeight,
+                       double scaleFactor, int rotationType, FingerPoint finger) {
+
                int pointX, pointY, rotatedPointX, rotatedPointY, flag;
-           flag = 0;
-//         logger.info("ScaledLcdWitdh:"+ScaledLcdWitdh+" ScaledLcdHeight:"+ScaledLcdHeight+ " scaleFactor:"+ scaleFactor+" rotationType:"+rotationType);
-           rotatedPointX = pointX = (int)(finger.x * scaleFactor);
-           rotatedPointY = pointY = (int)(finger.y * scaleFactor);
-//         logger.info("rotatedPointX:"+rotatedPointX+" rotatedPointY:"+rotatedPointY);
-           if (rotationType == RotationInfo.LANDSCAPE.id()) {
-               rotatedPointX = pointY;
-               rotatedPointY = ScaledLcdWitdh - pointX;
-           } else if (rotationType == RotationInfo.REVERSE_PORTRAIT.id()) {
-               rotatedPointX = ScaledLcdWitdh - pointX;
-               rotatedPointY = ScaledLcdHeight - pointY;
-           } else if (rotationType == RotationInfo.REVERSE_LANDSCAPE.id()) {
-               rotatedPointX = ScaledLcdHeight - pointY;
-               rotatedPointY = pointX;
-           } else {
-             //PORTRAIT: do nothing    
-           }
-               
-
-           if (finger.originX != rotatedPointX) {
-               logger.info("finger.originX: " +finger.originX);
-               finger.originX = rotatedPointX;
-               flag = 1;
-           }
-           if (finger.originY != rotatedPointY) {
-               logger.info("finger.originY: " +finger.originY);
-               finger.originY = rotatedPointY;
-               flag = 1;
-           }
-
-           if (flag != 0) {
-               return true;
-           }
-
-           return false;
+               flag = 0;
+
+               /* logger.info("ScaledLcdWitdh:" + ScaledLcdWitdh +
+                               " ScaledLcdHeight:" + ScaledLcdHeight +
+                               " scaleFactor:" + scaleFactor + " rotationType:" + rotationType); */
+
+               rotatedPointX = pointX = (int)(finger.x * scaleFactor);
+               rotatedPointY = pointY = (int)(finger.y * scaleFactor);
+
+               /* logger.info("rotatedPointX:" + rotatedPointX +
+                               " rotatedPointY:" + rotatedPointY); */
+
+               if (rotationType == RotationInfo.LANDSCAPE.id()) {
+                       rotatedPointX = pointY;
+                       rotatedPointY = ScaledLcdWitdh - pointX;
+               } else if (rotationType == RotationInfo.REVERSE_PORTRAIT.id()) {
+                       rotatedPointX = ScaledLcdWitdh - pointX;
+                       rotatedPointY = ScaledLcdHeight - pointY;
+               } else if (rotationType == RotationInfo.REVERSE_LANDSCAPE.id()) {
+                       rotatedPointX = ScaledLcdHeight - pointY;
+                       rotatedPointY = pointX;
+               } else {
+                       /* PORTRAIT: do nothing */
+               }
+
+               if (finger.originX != rotatedPointX) {
+                       logger.info("finger.originX: " +finger.originX);
+                       finger.originX = rotatedPointX;
+                       flag = 1;
+               }
+               if (finger.originY != rotatedPointY) {
+                       logger.info("finger.originY: " +finger.originY);
+                       finger.originY = rotatedPointY;
+                       flag = 1;
+               }
+
+               if (flag != 0) {
+                       return true;
+               }
+
+               return false;
        }
-       
-       public int rearrangeFingerPoints(int lcdWidth, int lcdHeight, double scaleFactor, int rotationType) {
-               int i = 0;                                                                    
-           int count = 0;                                                                
-           FingerPoint finger = null;                                                   
-                                                                                         
-           if (this.multiTouchEnable == 0) {                                            
-               return 0;                                                                 
-           }                                                                             
-           scaleFactor = scaleFactor/100;                                                                              
-           lcdWidth *= scaleFactor;                                                        
-           lcdHeight *= scaleFactor;                                                        
-                                                                                         
-           for (i = 0; i < this.fingerCnt; i++) {                                       
-               finger = getFingerPointFromSlot(i);                                   
-               if (finger != null && finger.id != 0) {                                  
-                   if (CalculateOriginCoordinates(lcdWidth, lcdHeight,                       
-                       scaleFactor, rotationType, finger) == true) {                    
-                       count++;                                                          
-                   }                                                                     
-               }                                                                         
-           }                                                                             
-                                                                                         
-           if (count != 0) {                                                             
-               this.grabFingerID = 0;                                                      
-           }                                                                             
-                                                                                         
-           return count;           
+
+       public int rearrangeFingerPoints(
+                       int lcdWidth, int lcdHeight, double scaleFactor, int rotationType) {
+               int i = 0;
+               int count = 0;
+               FingerPoint finger = null;
+
+               if (this.multiTouchEnable == 0) {
+                       return 0;
+               }
+
+               scaleFactor = scaleFactor / 100;
+               lcdWidth *= scaleFactor;
+               lcdHeight *= scaleFactor;
+
+               for (i = 0; i < this.fingerCnt; i++) {
+                       finger = getFingerPointFromSlot(i);
+                       if (finger != null && finger.id != 0) {
+                               if (CalculateOriginCoordinates(
+                                               lcdWidth, lcdHeight, scaleFactor, rotationType, finger) == true) {
+                                       count++;
+                               }
+                       }
+               }
+
+               if (count != 0) {
+                       this.grabFingerID = 0;
+               }
+
+               return count;
        }
-       
+
        public void clearFingerSlot() {
                int i = 0;
                FingerPoint finger = null;
-               for(i = 0; i < this.fingerCnt; i++) {
+
+               for (i = 0; i < this.fingerCnt; i++) {
                        finger = getFingerPointFromSlot(i);
-                       if(finger != null && finger.id != 0) {
-                               logger.info(String.format("clear %d, %d, %d", finger.x, finger.y, finger.id -1));
+                       if (finger != null && finger.id != 0) {
+                               logger.info(String.format(
+                                               "clear %d, %d, %d", finger.x, finger.y, finger.id - 1));
+
                                MouseEventData mouseEventData = new MouseEventData(
                                                MouseButtonType.LEFT.value(), MouseEventType.RELEASE.value(),
-                                               0, 0, finger.x, finger.y, finger.id -1);
-                               communicator.sendToQEMU( SendCommand.SEND_MOUSE_EVENT, mouseEventData );
+                                               0, 0, finger.x, finger.y, finger.id - 1);
+                               communicator.sendToQEMU(SendCommand.SEND_MOUSE_EVENT, mouseEventData);
                        }
+
                        finger.id = 0;
                        finger.originX = finger.originY = finger.x = finger.y = -1;
                }
+
                this.grabFingerID = 0;
                this.fingerCnt = 0;
                logger.info("clear multi touch");
        }
-       
+
        public void cleanup_multiTouchState() {
                this.multiTouchEnable = 0;
                clearFingerSlot();
                fingerSlotimage.dispose();
        }
-       
+
        public int getMaxTouchPoint() {
-               if(this.maxTouchPoint <= 0 ) {
+               if (this.maxTouchPoint <= 0) {
                        setMaxTouchPoint(1);
                }
+
                return this.maxTouchPoint;
        }
-       
+
        public void setMaxTouchPoint(int cnt) {
-               if(cnt <=0) {
-                       cnt =1;
+               if (cnt <=0) {
+                       cnt = 1;
                }
+
                this.maxTouchPoint = cnt;                       
        }
 }
index b1c76c9..149137c 100644 (file)
@@ -119,6 +119,18 @@ public class EmulatorSdlSkin extends EmulatorSkin {
        }
 
        @Override
+       public void displayOn() {
+               logger.info("display on");
+               /* do nothing */
+       }
+
+       @Override
+       public void displayOff() {
+               logger.info("display off");
+               /* do nothing */
+       }
+
+       @Override
        protected void openScreenShotWindow() {
                if (screenShotDialog != null) {
                        logger.info("screenshot window was already opened");
index 66415d8..6cd1bde 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * Emulator Skin Process
  *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Contact:
  * GiWoong Kim <giwoong.kim@samsung.com>
@@ -40,6 +40,7 @@ import org.eclipse.swt.graphics.PaletteData;
 import org.eclipse.swt.graphics.Transform;
 import org.eclipse.swt.widgets.Display;
 import org.tizen.emulator.skin.config.EmulatorConfig;
+import org.tizen.emulator.skin.config.EmulatorConfig.ArgsConstants;
 import org.tizen.emulator.skin.exception.ScreenShotException;
 import org.tizen.emulator.skin.image.ImageRegistry.IconName;
 import org.tizen.emulator.skin.info.SkinInformation;
@@ -57,7 +58,7 @@ public class EmulatorShmSkin extends EmulatorSkin {
        public static final int COLOR_DEPTH = 32;
 
        /* define JNI functions */
-       public native int shmget(int size);
+       public native int shmget(int shmkey, int size);
        public native int shmdt();
        public native int getPixels(int[] array);
 
@@ -74,6 +75,7 @@ public class EmulatorShmSkin extends EmulatorSkin {
 
                private volatile boolean stopRequest;
                private Runnable runnable;
+               private int intervalWait;
 
                public PollFBThread(int lcdWidth, int lcdHeight) {
                        this.display = Display.getDefault();
@@ -83,23 +85,37 @@ public class EmulatorShmSkin extends EmulatorSkin {
                        this.imageData = new ImageData(lcdWidth, lcdHeight, COLOR_DEPTH, paletteData);
                        this.framebuffer = new Image(Display.getDefault(), imageData);
 
+                       setWaitIntervalTime(30);
+
                        this.runnable = new Runnable() {
+                               @Override
                                public void run() {
                                        // logger.info("update display framebuffer");
-                                       if(lcdCanvas.isDisposed() == false) {
+                                       if (lcdCanvas.isDisposed() == false) {
                                                lcdCanvas.redraw();
                                        }
                                }
                        };
                }
 
+               public synchronized void setWaitIntervalTime(int ms) {
+                       intervalWait = ms;
+               }
+
+               public synchronized int getWaitIntervalTime() {
+                       return intervalWait;
+               }
+
+               @Override
                public void run() {
                        stopRequest = false;
 
+                       Image temp;
+
                        while (!stopRequest) {
-                               synchronized (this) {
+                               synchronized(this) {
                                        try {
-                                               this.wait(30); /* 30ms */
+                                               this.wait(intervalWait); /* ms */
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                                break;
@@ -113,7 +129,7 @@ public class EmulatorShmSkin extends EmulatorSkin {
                                        imageData.setPixels(0, i, lcdWidth, array, i * lcdWidth);
                                }
 
-                               Image temp = framebuffer;
+                               temp = framebuffer;
                                framebuffer = new Image(display, imageData);
                                temp.dispose();
 
@@ -131,6 +147,10 @@ public class EmulatorShmSkin extends EmulatorSkin {
 
                public void stopRequest() {
                        stopRequest = true;
+
+                       synchronized(pollThread) {
+                               pollThread.notify();
+                       }
                }
        }
 
@@ -149,15 +169,20 @@ public class EmulatorShmSkin extends EmulatorSkin {
                super.finger.setMultiTouchEnable(0);
                super.finger.clearFingerSlot();
                super.finger.cleanup_multiTouchState();
-       
+
                super.skinFinalize();
        }
 
        public long initLayout() {
                super.initLayout();
 
+               /* base + 1 = sdb port */
+               /* base + 2 = shared memory key */
+               int shmkey = config.getArgInt(ArgsConstants.NET_BASE_PORT) + 2;
+               logger.info("shmkey = " + shmkey);
+
                /* initialize shared memory */
-               int result = shmget(
+               int result = shmget(shmkey,
                                currentState.getCurrentResolutionWidth() *
                                currentState.getCurrentResolutionHeight());
                logger.info("shmget native function returned " + result);
@@ -168,7 +193,7 @@ public class EmulatorShmSkin extends EmulatorSkin {
                                currentState.getCurrentResolutionHeight());
 
                lcdCanvas.addPaintListener(new PaintListener() {
-                       public void paintControl(PaintEvent e) {
+                       public void paintControl(PaintEvent e) { //TODO: optimize
                                /* e.gc.setAdvanced(true);
                                if (!e.gc.getAdvanced()) {
                                        logger.info("Advanced graphics not supported");
@@ -176,18 +201,27 @@ public class EmulatorShmSkin extends EmulatorSkin {
 
                                int x = lcdCanvas.getSize().x;
                                int y = lcdCanvas.getSize().y;
+
+                               if (pollThread.getWaitIntervalTime() == 0) {
+                                       logger.info("draw black screen");
+
+                                       e.gc.drawRectangle(-1, -1, x + 1, y + 1);
+                                       return;
+                               }
+
                                if (currentState.getCurrentAngle() == 0) { /* portrait */
                                        e.gc.drawImage(pollThread.framebuffer,
                                                        0, 0, pollThread.lcdWidth, pollThread.lcdHeight,
                                                        0, 0, x, y);
-                                       
+
                                        if (finger.getMultiTouchEnable() == 1) {
                                                finger.rearrangeFingerPoints(currentState.getCurrentResolutionWidth(), 
                                                                currentState.getCurrentResolutionHeight(), 
                                                                currentState.getCurrentScale(), 
                                                                currentState.getCurrentRotationId());
                                        }
-                    finger.drawImage(e, currentState.getCurrentAngle());
+
+                                       finger.drawImage(e, currentState.getCurrentAngle());
                                        return;
                                }
 
@@ -210,15 +244,14 @@ public class EmulatorShmSkin extends EmulatorSkin {
                                        y = temp;
                                        transform.translate(x * -1, 0);
                                }
-                               
-                               //draw finger image
-                               //for when rotate while use multi touch
+
+                               /* draw finger image for when rotate while use multitouch */
                                if (finger.getMultiTouchEnable() == 1) {
                                        finger.rearrangeFingerPoints(currentState.getCurrentResolutionWidth(), 
                                                        currentState.getCurrentResolutionHeight(), 
                                                        currentState.getCurrentScale(), 
                                                        currentState.getCurrentRotationId());
-                               }       
+                               }
                                //save current transform as "oldtransform" 
                                e.gc.getTransform(oldtransform);
                                //set to new transfrom
@@ -228,7 +261,7 @@ public class EmulatorShmSkin extends EmulatorSkin {
                                                0, 0, x, y);
                                //back to old transform
                                e.gc.setTransform(oldtransform);
-                               
+
                                transform.dispose();
                                finger.drawImage(e, currentState.getCurrentAngle());
                        }
@@ -240,6 +273,35 @@ public class EmulatorShmSkin extends EmulatorSkin {
        }
 
        @Override
+       public void displayOn() {
+               logger.info("display on");
+
+               if (pollThread.isAlive()) {
+                       pollThread.setWaitIntervalTime(30);
+
+                       synchronized(pollThread) {
+                               pollThread.notify();
+                       }
+               }
+       }
+
+       @Override
+       public void displayOff() {
+               logger.info("display off");
+
+               if (pollThread.isAlive()) {
+                       pollThread.setWaitIntervalTime(0);
+
+                       shell.getDisplay().asyncExec(new Runnable() {
+                               @Override
+                               public void run() {
+                                       lcdCanvas.redraw();
+                               }
+                       });
+               }
+       }
+
+       @Override
        protected void openScreenShotWindow() {
                if (screenShotDialog != null) {
                        logger.info("screenshot window was already opened");
index 0cd3002..6744202 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * Emulator Skin Process
  *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Contact:
  * GiWoong Kim <giwoong.kim@samsung.com>
@@ -65,6 +65,7 @@ import org.eclipse.swt.widgets.Shell;
 import org.tizen.emulator.skin.comm.ICommunicator.KeyEventType;
 import org.tizen.emulator.skin.comm.ICommunicator.MouseButtonType;
 import org.tizen.emulator.skin.comm.ICommunicator.MouseEventType;
+import org.tizen.emulator.skin.comm.ICommunicator.RotationInfo;
 import org.tizen.emulator.skin.comm.ICommunicator.Scale;
 import org.tizen.emulator.skin.comm.ICommunicator.SendCommand;
 import org.tizen.emulator.skin.comm.sock.SocketCommunicator;
@@ -75,6 +76,7 @@ import org.tizen.emulator.skin.comm.sock.data.MouseEventData;
 import org.tizen.emulator.skin.config.EmulatorConfig;
 import org.tizen.emulator.skin.config.EmulatorConfig.ArgsConstants;
 import org.tizen.emulator.skin.config.EmulatorConfig.SkinPropertiesConstants;
+import org.tizen.emulator.skin.custom.ColorTag;
 import org.tizen.emulator.skin.custom.CustomProgressBar;
 import org.tizen.emulator.skin.custom.KeyWindow;
 import org.tizen.emulator.skin.dbi.ColorsType;
@@ -122,6 +124,33 @@ public class EmulatorSkin {
 
        }
 
+       public enum SkinBasicColor {
+               BLUE(0, 174, 239),
+               YELLOW(246, 226, 0),
+               LIME(0, 246, 12),
+               VIOLET(168, 43, 255),
+               ORANGE(246, 110, 0),
+               MAGENTA(245, 48, 233),
+               PURPLE(94, 73, 255),
+               GREEN(179, 246, 0),
+               RED(245, 48, 48),
+               CYON(29, 223, 221);
+
+               private int channelRed;
+               private int channelGreen;
+               private int channelBlue;
+
+               SkinBasicColor(int r, int g, int b) {
+                       channelRed = r;
+                       channelGreen = g;
+                       channelBlue = b;
+               }
+
+               public RGB color() {
+                       return new RGB(channelRed, channelGreen, channelBlue);
+               }
+       }
+
        private static Logger logger =
                        SkinLogger.getSkinLogger(EmulatorSkin.class).getLogger();
 
@@ -144,11 +173,11 @@ public class EmulatorSkin {
        private boolean isOnKbd;
 
        private Menu contextMenu;
+       public Color colorVM;
        private MenuItem keyWindowItem; /* key window menu */
        public KeyWindow keyWindow;
        public int recentlyDocked;
-       public Color colorPairTag;
-       public Canvas pairTagCanvas;
+       public ColorTag pairTag;
        public CustomProgressBar bootingProgress;
        public ScreenShotDialog screenShotDialog;
 
@@ -205,10 +234,7 @@ public class EmulatorSkin {
                this.displayCanvasStyle = displayCanvasStyle;
 
                /* generate a pair tag color of key window */
-               int red = (int) (Math.random() * 256);
-               int green = (int) (Math.random() * 256);
-               int blue = (int) (Math.random() * 256);
-               this.colorPairTag = new Color(shell.getDisplay(), new RGB(red, green, blue));
+               setColorVM();
 
                this.currentState = state;
        }
@@ -218,6 +244,22 @@ public class EmulatorSkin {
                this.finger.setCommunicator(this.communicator);
        }
 
+       private void setColorVM() {
+               int portNumber = config.getArgInt(ArgsConstants.NET_BASE_PORT) % 100;
+
+               if (portNumber >= 26200) {
+                       int red = (int) (Math.random() * 256);
+                       int green = (int) (Math.random() * 256);
+                       int blue = (int) (Math.random() * 256);
+                       this.colorVM = new Color(shell.getDisplay(), new RGB(red, green, blue));
+               } else {
+                       int vmIndex = (portNumber % 100) / 10;
+
+                       SkinBasicColor colors[] = SkinBasicColor.values();
+                       this.colorVM = new Color(shell.getDisplay(), colors[vmIndex].color());
+               }
+       }
+
        public long initLayout() {
                imageRegistry = ImageRegistry.getInstance();
 
@@ -316,8 +358,15 @@ public class EmulatorSkin {
                return (new Color(shell.getDisplay(), new RGB(255, 255, 255)));
        }
 
-       public SkinReopenPolicy open() {
+       public Color getColorVM() {
+               return colorVM;
+       }
+
+       public ImageRegistry getImageRegistry() {
+               return imageRegistry;
+       }
 
+       public SkinReopenPolicy open() {
                if (null == this.communicator) {
                        logger.severe("communicator is null.");
                        return null;
@@ -345,7 +394,6 @@ public class EmulatorSkin {
                }
 
                return new SkinReopenPolicy(reopenSkin, isAboutToReopen);
-
        }
 
        protected void skinFinalize() {
@@ -378,9 +426,9 @@ public class EmulatorSkin {
                                                        closeKeyWindow();
                                                }
 
-                                               /* dispose the color tag */
-                                               if (colorPairTag != null) {
-                                                       colorPairTag.dispose();
+                                               /* dispose the color */
+                                               if (colorVM != null) {
+                                                       colorVM.dispose();
                                                }
 
                                                /* save config only for emulator close */
@@ -445,24 +493,39 @@ public class EmulatorSkin {
 
                        @Override
                        public void shellIconified(ShellEvent event) {
-                               /* do nothing */
-                       }
-
-                       @Override
-                       public void shellDeiconified(ShellEvent event) {
-                               logger.info("deiconified");
+                               logger.info("iconified");
 
+                               /* synchronization of minimization */
                                shell.getDisplay().asyncExec(new Runnable() {
                                        @Override
                                        public void run() {
                                                if (isKeyWindow == true && keyWindow != null) {
-                                                       if (keyWindow.getShell().getMinimized() == true) {
-                                                               keyWindow.getShell().setMinimized(false);
+                                                       if (keyWindow.getShell().getMinimized() == false) {
+                                                               keyWindow.getShell().setVisible(false);
+                                                               /* the tool style window is exposed
+                                                               when even it was minimized */
+                                                               keyWindow.getShell().setMinimized(true);
                                                        }
                                                }
                                        }
                                });
                        }
+
+                       @Override
+                       public void shellDeiconified(ShellEvent event) {
+                               logger.info("deiconified");
+
+                               if (isKeyWindow == true && keyWindow != null) {
+                                       if (keyWindow.getShell().getMinimized() == true) {
+                                               keyWindow.getShell().setMinimized(false);
+                                               keyWindow.getShell().setVisible(true);
+                                       }
+                               }
+
+                               DisplayStateData lcdStateData = new DisplayStateData(
+                                               currentState.getCurrentScale(), currentState.getCurrentRotationId());
+                               communicator.sendToQEMU(SendCommand.CHANGE_LCD_STATE, lcdStateData);
+                       }
                };
 
                shell.addShellListener(shellListener);
@@ -928,7 +991,7 @@ public class EmulatorSkin {
        private synchronized boolean addPressedKey(KeyEventData pressData) {
                for (KeyEventData data : pressedKeyEventList) {
                        if (data.keycode == pressData.keycode &&
-                                       data.stateMask == pressData.stateMask &&
+                                       //data.stateMask == pressData.stateMask &&
                                        data.keyLocation == pressData.keyLocation) {
                                return false;
                        }
@@ -942,7 +1005,7 @@ public class EmulatorSkin {
 
                for (KeyEventData data : pressedKeyEventList) {
                        if (data.keycode == releaseData.keycode &&
-                                       data.stateMask == releaseData.stateMask &&
+                                       //data.stateMask == releaseData.stateMask &&
                                        data.keyLocation == releaseData.keyLocation) {
                                pressedKeyEventList.remove(data);
 
@@ -987,7 +1050,23 @@ public class EmulatorSkin {
        }
 
        protected void openScreenShotWindow() {
-               //TODO: abstract
+               /* abstract */
+       }
+
+       public void dispalyBrightness(boolean on) {
+               if (on == true) {
+                       displayOn();
+               } else {
+                       displayOff();
+               }
+       }
+
+       protected void displayOn() {
+               /* abstract */
+       }
+
+       protected void displayOff() {
+               /* abstract */
        }
 
        public boolean isSelectKeyWindow() {
@@ -999,7 +1078,7 @@ public class EmulatorSkin {
                        if (recreate == false) {
                                /* show the key window */
                                keyWindowItem.setSelection(isKeyWindow = true);
-                               pairTagCanvas.setVisible(true);
+                               pairTag.setVisible(true);
 
                                keyWindow.getShell().setVisible(true);
                                SkinUtil.setTopMost(keyWindow.getShell(), isOnTop);
@@ -1025,20 +1104,19 @@ public class EmulatorSkin {
                        return;
                }
 
-               keyWindow = new KeyWindow(this, shell, colorPairTag,
-                               communicator, keyMapList);
+               keyWindow = new KeyWindow(this, shell, communicator, keyMapList);
 
                keyWindowItem.setSelection(isKeyWindow = true);
                SkinUtil.setTopMost(keyWindow.getShell(), isOnTop);
 
-               pairTagCanvas.setVisible(true);
+               pairTag.setVisible(true);
 
                keyWindow.open(dockValue);
        }
 
        public void hideKeyWindow() {
                keyWindowItem.setSelection(isKeyWindow = false);
-               pairTagCanvas.setVisible(false);
+               pairTag.setVisible(false);
 
                if (keyWindow != null) {
                        keyWindow.getShell().setVisible(false);
@@ -1047,7 +1125,7 @@ public class EmulatorSkin {
 
        public void closeKeyWindow() {
                keyWindowItem.setSelection(isKeyWindow = false);
-               pairTagCanvas.setVisible(false);
+               pairTag.setVisible(false);
 
                if (keyWindow != null) {
                        keyWindow.getShell().close();
@@ -1262,6 +1340,33 @@ public class EmulatorSkin {
 
                }
 
+               /* temp : swap rotation menu names */
+               if (currentState.getCurrentResolutionWidth() >
+                               currentState.getCurrentResolutionHeight())
+               {
+                       for (MenuItem m : rotationList) {
+                               short rotationId = (Short) m.getData();
+
+                               if (rotationId == RotationInfo.PORTRAIT.id()) {
+                                       String landscape = SkinRotation.getRotation(
+                                                       RotationInfo.LANDSCAPE.id()).getName().value();
+                                       m.setText(landscape);
+                               } else if (rotationId == RotationInfo.LANDSCAPE.id()) {
+                                       String portrait = SkinRotation.getRotation(
+                                                       RotationInfo.PORTRAIT.id()).getName().value();
+                                       m.setText(portrait);
+                               } else if (rotationId == RotationInfo.REVERSE_PORTRAIT.id()) {
+                                       String landscapeReverse = SkinRotation.getRotation(
+                                                       RotationInfo.REVERSE_LANDSCAPE.id()).getName().value();
+                                       m.setText(landscapeReverse);
+                               } else if (rotationId == RotationInfo.REVERSE_LANDSCAPE.id()) {
+                                       String portraitReverse = SkinRotation.getRotation(
+                                                       RotationInfo.REVERSE_PORTRAIT.id()).getName().value();
+                                       m.setText(portraitReverse);
+                               }
+                       }
+               }
+
                SelectionAdapter selectionAdapter = new SelectionAdapter() {
                        @Override
                        public void widgetSelected(SelectionEvent e) {
@@ -1537,7 +1642,7 @@ public class EmulatorSkin {
                                        isOpen = true;
 
                                        logger.info("Open the about dialog");
-                                       AboutDialog dialog = new AboutDialog(shell);
+                                       AboutDialog dialog = new AboutDialog(shell, config);
                                        dialog.open();
                                        isOpen = false;
                                }
index facefd5..d93a1bd 100644 (file)
 
 package org.tizen.emulator.skin;
 
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileReader;
 import java.io.IOException;
 import java.net.Socket;
 import java.util.HashMap;
@@ -57,6 +59,7 @@ import org.tizen.emulator.skin.log.SkinLogger;
 import org.tizen.emulator.skin.log.SkinLogger.SkinLogLevel;
 import org.tizen.emulator.skin.util.IOUtil;
 import org.tizen.emulator.skin.util.JaxbUtil;
+import org.tizen.emulator.skin.util.SkinUtil;
 import org.tizen.emulator.skin.util.StringUtil;
 import org.tizen.emulator.skin.util.SwtUtil;
 
@@ -173,8 +176,11 @@ public class EmulatorSkinMain {
                        }
 
                        boolean skinPhoneShape = true;
-                       String skinInfoResolutionW = skinInfoProperties.getProperty(SkinInfoConstants.RESOLUTION_WIDTH);
-                       String skinInfoResolutionH = skinInfoProperties.getProperty(SkinInfoConstants.RESOLUTION_HEIGHT);
+                       String skinInfoResolutionW =
+                                       skinInfoProperties.getProperty(SkinInfoConstants.RESOLUTION_WIDTH);
+                       String skinInfoResolutionH =
+                                       skinInfoProperties.getProperty(SkinInfoConstants.RESOLUTION_HEIGHT);
+
                        if (skinInfoResolutionW.equalsIgnoreCase("all") ||
                                        skinInfoResolutionH.equalsIgnoreCase("all")) {
                                skinPhoneShape = false;
@@ -184,10 +190,10 @@ public class EmulatorSkinMain {
 
                        /* set emulator window skin property */
                        String skinPropFilePath = vmPath + File.separator + SKIN_PROPERTIES_FILE_NAME;
-                       Properties skinProperties = loadProperties( skinPropFilePath, true );
-                       if ( null == skinProperties ) {
-                               logger.severe( "Fail to load skin properties file." );
-                               System.exit( -1 );
+                       Properties skinProperties = loadProperties(skinPropFilePath, true);
+                       if (null == skinProperties) {
+                               logger.severe("Fail to load skin properties file.");
+                               System.exit(-1);
                        }
 
                        /* set emulator window config property */
@@ -219,9 +225,30 @@ public class EmulatorSkinMain {
                                System.exit(-1);
                        }
 
+                       /* collect configurations */
                        EmulatorConfig config = new EmulatorConfig(argsMap,
                                        dbiContents, skinProperties, skinPropFilePath, configProperties);
 
+                       /* load SDK version */
+                       String strVersion = "Undefined";
+                       String versionFilePath = SkinUtil.getSdkVersionFilePath();
+
+                       File file = new File(versionFilePath);
+                       if (file.exists() && file.isFile()) {
+                               BufferedReader reader = new BufferedReader(
+                                               new FileReader(versionFilePath));
+
+                               strVersion = reader.readLine();
+
+                               reader.close();
+                       } else {
+                               logger.info("cannot find version file" + versionFilePath);
+                       }
+
+                       logger.info("SDK version : " + strVersion);
+                       config.setSkinProperty(
+                                       EmulatorConfig.SkinInfoConstants.SDK_VERSION_NAME, strVersion);
+
                        /* load image resource */
                        ImageRegistry.getInstance().initialize(config);
 
index 9a6f3fb..30ca206 100644 (file)
@@ -263,6 +263,7 @@ public interface ICommunicator extends Runnable {
                DETAIL_INFO_DATA((short) 3),
                RAMDUMP_COMPLETE((short) 4),
                BOOTING_PROGRESS((short) 5),
+               BRIGHTNESS_VALUE((short) 6),
                SENSOR_DAEMON_START((short) 800),
                SHUTDOWN((short) 999);
 
index 14d20e7..5f3e734 100644 (file)
@@ -73,9 +73,10 @@ public class SocketCommunicator implements ICommunicator {
                private Timer timer;
                
                private DataTranfer() {
+                       /* do nothing */
                }
 
-               private void setData( byte[] data ) {
+               private void setData(byte[] data) {
                        this.receivedData = data;
                        isTransferState = false;
                }
@@ -116,10 +117,14 @@ public class SocketCommunicator implements ICommunicator {
        private DataTranfer screenShotDataTransfer;
        private DataTranfer detailInfoTransfer;
        private DataTranfer progressDataTransfer;
+       private DataTranfer brightnessDataTransfer;
 
        private Thread sendThread;
        private LinkedList<SkinSendData> sendQueue;
 
+       private ByteArrayOutputStream bao;
+       private DataOutputStream dataOutputStream;
+
        public SocketCommunicator(EmulatorConfig config, int uId, EmulatorSkin skin) {
 
                this.config = config;
@@ -138,6 +143,10 @@ public class SocketCommunicator implements ICommunicator {
                this.progressDataTransfer.sleep = SCREENSHOT_WAIT_INTERVAL;
                this.progressDataTransfer.maxWaitTime = SCREENSHOT_WAIT_LIMIT;
 
+               this.brightnessDataTransfer = new DataTranfer();
+               this.brightnessDataTransfer.sleep = SCREENSHOT_WAIT_INTERVAL;
+               this.brightnessDataTransfer.maxWaitTime = SCREENSHOT_WAIT_LIMIT;
+
                this.heartbeatCount = new AtomicInteger(0);
                //this.heartbeatExecutor = Executors.newSingleThreadScheduledExecutor();
                this.heartbeatTimer = new Timer();
@@ -154,6 +163,8 @@ public class SocketCommunicator implements ICommunicator {
                        logger.log( Level.SEVERE, e.getMessage(), e );
                }
 
+               this.bao = new ByteArrayOutputStream();
+               this.dataOutputStream = new DataOutputStream(bao);
        }
 
        public void setInitialData(long data) {
@@ -257,9 +268,8 @@ public class SocketCommunicator implements ICommunicator {
                        heartbeatTimer.schedule(heartbeatExecutor, 1, HEART_BEAT_INTERVAL * 1000);
                }
 
-               while ( true ) {
-
-                       if ( isTerminated ) {
+               while (true) {
+                       if (isTerminated) {
                                break;
                        }
 
@@ -269,16 +279,17 @@ public class SocketCommunicator implements ICommunicator {
                                short cmd = dis.readShort();
                                int length = dis.readInt();
 
-                               if ( logger.isLoggable( Level.FINE ) ) {
-                                       logger.fine( "[Socket] read - reqId:" + reqId + ", command:" + cmd + ", dataLength:" + length );
+                               if (logger.isLoggable(Level.FINE)) {
+                                       logger.fine("[Socket] read - reqId:" + reqId +
+                                                       ", command:" + cmd + ", dataLength:" + length);
                                }
 
                                ReceiveCommand command = null;
 
                                try {
-                                       command = ReceiveCommand.getValue( cmd );
-                               } catch ( IllegalArgumentException e ) {
-                                       logger.severe( "unknown command:" + cmd );
+                                       command = ReceiveCommand.getValue(cmd);
+                               } catch (IllegalArgumentException e) {
+                                       logger.severe("unknown command:" + cmd);
                                        continue;
                                }
 
@@ -309,7 +320,7 @@ public class SocketCommunicator implements ICommunicator {
                                        break;
                                }
                                case BOOTING_PROGRESS: {
-                                       logger.info("received BOOTING_PROGRESS from QEMU.");
+                                       //logger.info("received BOOTING_PROGRESS from QEMU.");
 
                                        resetDataTransfer(progressDataTransfer);
                                        receiveData(progressDataTransfer, length);
@@ -331,7 +342,7 @@ public class SocketCommunicator implements ICommunicator {
 
                                                        if (value == 100 | value == 0) {
                                                                /* this means progressbar will be
-                                                               dispose soon */
+                                                               disposed soon */
                                                                if (skin.bootingProgress != null) {
                                                                        skin.bootingProgress = null;
                                                                }
@@ -341,27 +352,53 @@ public class SocketCommunicator implements ICommunicator {
 
                                        break;
                                }
+                               case BRIGHTNESS_VALUE: {
+                                       //logger.info("received BRIGHTNESS_VALUE from QEMU.");
+
+                                       resetDataTransfer(brightnessDataTransfer);
+                                       receiveData(brightnessDataTransfer, length);
+
+                                       byte[] receivedData = getReceivedData(brightnessDataTransfer);
+                                       if (null != receivedData) {
+                                               String strValue = new String(receivedData, 0, length - 1);
+
+                                               int value = 1;
+                                               try {
+                                                       value = Integer.parseInt(strValue);
+                                               } catch (NumberFormatException e) {
+                                                       e.printStackTrace();
+                                               }
+
+                                               if (value == 0) {
+                                                       skin.dispalyBrightness(false);
+                                               } else {
+                                                       skin.dispalyBrightness(true);
+                                               }
+                                       }
+
+                                       break;
+                               }
                                case SENSOR_DAEMON_START: {
-                                       logger.info( "received SENSOR_DAEMON_START from QEMU." );
-                                       synchronized ( this ) {
+                                       logger.info("received SENSOR_DAEMON_START from QEMU.");
+                                       synchronized (this) {
                                                isSensorDaemonStarted = true;
                                        }
                                        break;
                                }
                                case SHUTDOWN: {
-                                       logger.info( "received RESPONSE_SHUTDOWN from QEMU." );
-                                       sendToQEMU( SendCommand.RESPONSE_SHUTDOWN, null );
+                                       logger.info("received RESPONSE_SHUTDOWN from QEMU.");
+                                       sendToQEMU(SendCommand.RESPONSE_SHUTDOWN, null);
                                        terminate();
                                        break;
                                }
                                default: {
-                                       logger.severe( "Unknown command from QEMU. command:" + cmd );
+                                       logger.severe("Unknown command from QEMU. command:" + cmd);
                                        break;
                                }
                                }
 
-                       } catch ( IOException e ) {
-                               logger.log( Level.SEVERE, e.getMessage(), e );
+                       } catch (IOException e) {
+                               logger.log(Level.SEVERE, e.getMessage(), e);
                                break;
                        }
 
@@ -483,68 +520,66 @@ public class SocketCommunicator implements ICommunicator {
        }
        
        @Override
-       public void sendToQEMU( SendCommand command, ISendData data ) {
-
-               synchronized ( sendQueue ) {
-                       if ( MAX_SEND_QUEUE_SIZE < sendQueue.size() ) {
-                               logger.warning( "Send queue size exceeded max value, do not push data into send queue." );
+       public void sendToQEMU(SendCommand command, ISendData data) {
+               synchronized(sendQueue) {
+                       if (MAX_SEND_QUEUE_SIZE < sendQueue.size()) {
+                               logger.warning(
+                                               "Send queue size exceeded max value, do not push data into send queue.");
                        } else {
-                               sendQueue.add( new SkinSendData( command, data ) );
+                               sendQueue.add(new SkinSendData(command, data));
                                sendQueue.notifyAll();
                        }
                }
-
        }
        
-       private void sendToQEMUInternal( SkinSendData sendData ) {
-
+       private void sendToQEMUInternal(SkinSendData sendData) {
                try {
 
-                       if( null == sendData ) {
+                       if (null == sendData) {
                                return;
                        }
                        
                        SendCommand command = sendData.getCommand();
                        ISendData data = sendData.getSendData();
-                       
-                       reqId = ( Integer.MAX_VALUE == reqId ) ? 0 : ++reqId;
-                       
-                       ByteArrayOutputStream bao = new ByteArrayOutputStream();
-                       DataOutputStream dataOutputStream = new DataOutputStream( bao );
 
-                       dataOutputStream.writeInt( uId );
-                       dataOutputStream.writeInt( reqId );
-                       dataOutputStream.writeShort( command.value() );
+                       reqId = (Integer.MAX_VALUE == reqId) ? 0 : ++reqId;
+
+                       dataOutputStream.writeInt(uId);
+                       dataOutputStream.writeInt(reqId);
+                       dataOutputStream.writeShort(command.value());
 
                        short length = 0;
-                       if ( null == data ) {
+                       if (null == data) {
                                length = 0;
-                               dataOutputStream.writeShort( length );
+                               dataOutputStream.writeShort(length);
                        } else {
                                byte[] byteData = data.serialize();
                                length = (short) byteData.length;
-                               dataOutputStream.writeShort( length );
-                               dataOutputStream.write( byteData );
+                               dataOutputStream.writeShort(length);
+                               dataOutputStream.write(byteData);
                        }
 
                        dataOutputStream.flush();
 
-                       dos.write( bao.toByteArray() );
+                       dos.write(bao.toByteArray());
                        dos.flush();
 
-                       if ( logger.isLoggable( Level.FINE ) ) {
-                               logger.fine( "[Socket] write - uid:" + uId + ", reqId:" + reqId + ", command:" + command.value()
-                                               + " - " + command.toString() + ", length:" + length );
+                       bao.reset();
+
+                       if (logger.isLoggable(Level.FINE)) {
+                               logger.fine("[Socket] write - uid:" + uId +
+                                               ", reqId:" + reqId + ", command:" + command.value()
+                                               + " - " + command.toString() + ", length:" + length);
                        }
 
-                       if ( 0 < length ) {
-                               if ( logger.isLoggable( Level.FINE ) ) {
-                                       logger.fine( "[Socket] data  - " + data.toString() );
+                       if (0 < length) {
+                               if (logger.isLoggable(Level.FINE)) {
+                                       logger.fine("[Socket] data  - " + data.toString());
                                }
                        }
 
-               } catch ( IOException e ) {
-                       logger.log( Level.SEVERE, e.getMessage(), e );
+               } catch (IOException e) {
+                       logger.log(Level.SEVERE, e.getMessage(), e);
                }
 
        }
@@ -644,6 +679,13 @@ public class SocketCommunicator implements ICommunicator {
 
                IOUtil.closeSocket(socket);
 
+               try {
+                       bao.close();
+                       dataOutputStream.close();
+               } catch (IOException e) {
+                       e.printStackTrace();
+               }
+
                synchronized (this) {
                        skin.shutdown();
                }
diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/comm/sock/data/DisplayStateData.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/comm/sock/data/DisplayStateData.java
new file mode 100644 (file)
index 0000000..a22ef4d
--- /dev/null
@@ -0,0 +1,65 @@
+/**
+ * 
+ *
+ * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ * HyunJun Son
+ *
+ * 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
+ *
+ */
+
+package org.tizen.emulator.skin.comm.sock.data;
+
+import java.io.IOException;
+
+/**
+ * 
+ *
+ */
+public class DisplayStateData extends AbstractSendData {
+       
+       int scale;
+       short rotation;
+       
+       public DisplayStateData(int scale, short rotation) {
+               this.scale = scale;
+               this.rotation = rotation;
+       }
+
+       @Override
+       protected void write() throws IOException {
+               writeInt(scale);
+               writeShort(rotation);
+       }
+
+       @Override
+       public String toString() {
+               StringBuilder builder = new StringBuilder();
+               builder.append("DisplayStateData [scale=");
+               builder.append(scale);
+               builder.append(", rotation=");
+               builder.append(rotation);
+               builder.append("]");
+               return builder.toString();
+       }
+
+}
index 489e4ad..3048bd4 100644 (file)
@@ -78,6 +78,7 @@ public class EmulatorConfig {
        }
 
        public interface SkinInfoConstants {
+               public static final String SDK_VERSION_NAME = "sdk.version-name";
                public static final String SKIN_NAME = "skin.name";
                public static final String RESOLUTION_WIDTH = "resolution.width";
                public static final String RESOLUTION_HEIGHT = "resolution.height";
@@ -102,14 +103,16 @@ public class EmulatorConfig {
        private Properties configProperties;
        private String skinPropertiesFilePath;
 
-       public EmulatorConfig( Map<String, String> args, EmulatorUI dbiContents, Properties skinProperties,
-                       String skinPropertiesFilePath, Properties configProperties ) {
+       public EmulatorConfig(Map<String, String> args,
+                       EmulatorUI dbiContents, Properties skinProperties,
+                       String skinPropertiesFilePath, Properties configProperties) {
                this.args = args;
                this.dbiContents = dbiContents;
                this.skinProperties = skinProperties;
                this.skinPropertiesFilePath = skinPropertiesFilePath;
                this.configProperties = configProperties;
-               if ( null == configProperties ) {
+
+               if (null == configProperties) {
                        this.configProperties = new Properties();
                }
        }
diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/custom/ColorTag.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/custom/ColorTag.java
new file mode 100644 (file)
index 0000000..1e4654d
--- /dev/null
@@ -0,0 +1,66 @@
+/**
+ *
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@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
+ *
+ */
+
+package org.tizen.emulator.skin.custom;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Shell;
+
+public class ColorTag extends Canvas {
+       private static final int COLORTAG_WIDTH = 8;
+       private static final int COLORTAG_HEIGHT = 8;
+
+       public ColorTag(final Shell parent, int style, final Color colorOval) {
+               super(parent, style);
+
+               setSize(COLORTAG_WIDTH, COLORTAG_HEIGHT);
+               setBackground(parent.getBackground());
+
+               addPaintListener(new PaintListener() {
+                       @Override
+                       public void paintControl(PaintEvent e) {
+                               e.gc.setBackground(colorOval);
+                               e.gc.setAntialias(SWT.ON);
+                               e.gc.fillOval(
+                                               0, 0, COLORTAG_WIDTH, COLORTAG_HEIGHT);
+                       }
+               });
+       }
+
+       public int getWidth() {
+               return getSize().x;
+       }
+
+       public int getHeight() {
+               return getSize().y;
+       }
+}
\ No newline at end of file
diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/custom/CustomButton.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/custom/CustomButton.java
new file mode 100644 (file)
index 0000000..782e488
--- /dev/null
@@ -0,0 +1,246 @@
+/**
+ * Image Button
+ *
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@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
+ *
+ */
+
+package org.tizen.emulator.skin.custom;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.MouseTrackAdapter;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+
+public class CustomButton extends Canvas {
+       /* state */
+       private int mouse = 0;
+       private boolean hit = false;
+
+       /* image - 0 : normal, 1 : hover, 2 : pushed */
+       private Image imageButton[];
+
+       private int width;
+       private int height;
+       private String text;
+       private int textPositionX;
+       private int textPositionY;
+       private static Color white;
+       private static Color gray;
+
+       public CustomButton(Composite parent, int style,
+                       Image imageNormal, Image imageHover, Image imagePushed) {
+               super(parent, style);
+
+               this.imageButton = new Image[3];
+               imageButton[0] = imageNormal;
+               imageButton[1] = imageHover;
+               imageButton[2] = imagePushed;
+
+               this.width = imageNormal.getImageData().width;
+               this.height = imageNormal.getImageData().height;
+
+               this.text = null;
+               textPositionX = width / 2;
+               textPositionY = height / 2;
+               white = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);
+               gray = Display.getCurrent().getSystemColor(SWT.COLOR_GRAY);
+
+               this.addPaintListener(new PaintListener() {
+                       @Override
+                       public void paintControl(PaintEvent e) {
+                               switch (mouse) {
+                               case 0: /* default state */
+                                       if (imageButton[0] != null) {
+                                               e.gc.drawImage(imageButton[0], 0, 0);
+                                       }
+
+                                       if (text != null) {
+                                               e.gc.setForeground(white);
+                                               e.gc.drawText(text,
+                                                               textPositionX, textPositionY, true);
+                                       }
+
+                                       break;
+                               case 1: /* mouse over */
+                                       if (imageButton[1] != null) {
+                                               e.gc.drawImage(imageButton[1], 0, 0);
+                                       }
+
+                                       if (text != null) {
+                                               e.gc.setForeground(white);
+                                               e.gc.drawText(text,
+                                                               textPositionX, textPositionY, true);
+                                       }
+
+                                       break;
+                               case 2: /* mouse down */
+                                       if (imageButton[2] != null) {
+                                               e.gc.drawImage(imageButton[2], 0, 0);
+                                       }
+
+                                       if (text != null) {
+                                               e.gc.setForeground(gray);
+                                               e.gc.drawText(text,
+                                                               textPositionX, textPositionY, true);
+                                       }
+
+                                       break;
+                               default:
+                                       break;
+                               }
+                       }
+               });
+
+               this.addMouseMoveListener(new MouseMoveListener() {
+                       @Override
+                       public void mouseMove(MouseEvent e) {
+                               if (!hit) {
+                                       return;
+                               }
+
+                               mouse = 2;
+
+                               if (e.x < 0 || e.y < 0 ||
+                                               e.x > getBounds().width || e.y > getBounds().height) {
+                                       mouse = 0;
+                               }
+
+                               redraw();
+                       }
+               });
+
+               this.addMouseTrackListener(new MouseTrackAdapter() {
+                       @Override
+                       public void mouseEnter(MouseEvent e) {
+                               mouse = 1;
+
+                               redraw();
+                       }
+
+                       @Override
+                       public void mouseExit(MouseEvent e) {
+                               mouse = 0;
+
+                               redraw();
+                       }
+               });
+
+               this.addMouseListener(new MouseAdapter() {
+                       @Override
+                       public void mouseDown(MouseEvent e) {
+                               hit = true;
+                               mouse = 2;
+
+                               redraw();
+                       }
+
+                       @Override
+                       public void mouseUp(MouseEvent e) {
+                               hit = false;
+                               mouse = 1;
+
+                               if (e.x < 0 || e.y < 0 ||
+                                               e.x > getBounds().width || e.y > getBounds().height) {
+                                       mouse = 0;
+                               }
+
+                               redraw();
+
+                               if (mouse == 1) {
+                                       notifyListeners(SWT.Selection, new Event());
+                               }
+                       }
+               });
+
+               this.addKeyListener(new KeyAdapter() {
+                       @Override
+                       public void keyPressed(KeyEvent e) {
+                               if (e.keyCode == '\r' || e.character == ' ') {
+                                       Event event = new Event();
+                                       notifyListeners(SWT.Selection, event);
+                               }
+                       }
+               });
+       }
+
+       public void setText(String textValue) {
+               /* checking whether the text value is appropriate */
+               if (textValue == null || textValue.isEmpty()) {
+                       return;
+               }
+
+               GC gc = new GC(this);
+               Point textSize = gc.textExtent(textValue);
+               Point originalSize = textSize;
+
+               while (textSize.x >= (width - 10)) {
+                       textValue = textValue.substring(0, textValue.length() - 1);
+                       textSize = gc.textExtent(textValue);
+               }
+
+               if (originalSize.x != textSize.x) {
+                       textValue = textValue.substring(0, textValue.length() - 1);
+                       textValue += "..";
+                       textSize = gc.textExtent(textValue);
+               }
+
+               gc.dispose();
+
+               /* set text */
+               text = textValue;
+
+               textPositionX -= textSize.x / 2;
+               if (textPositionX < 0) {
+                       textPositionX = 0;
+               }
+
+               textPositionY -= textSize.y / 2;
+               if (textPositionY < 0) {
+                       textPositionY = 0;
+               }
+       }
+
+       public String getText() {
+               return text;
+       }
+
+       public Point getImageSize() {
+               return new Point(imageButton[0].getImageData().width,
+                               imageButton[0].getImageData().height);
+       }
+}
\ No newline at end of file
diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/custom/CustomProgressBar.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/custom/CustomProgressBar.java
new file mode 100644 (file)
index 0000000..a07c3f8
--- /dev/null
@@ -0,0 +1,121 @@
+/**
+ *
+ *
+ * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@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
+ *
+ */
+
+package org.tizen.emulator.skin.custom;
+
+import java.util.logging.Logger;
+
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.tizen.emulator.skin.log.SkinLogger;
+
+public class CustomProgressBar extends Canvas {
+       public static final RGB PROGRESS_COLOR = new RGB(0, 173, 239);
+
+       private Logger logger =
+                       SkinLogger.getSkinLogger(CustomProgressBar.class).getLogger();
+
+       private Composite parent;
+       private int selection;
+
+       public CustomProgressBar(final Composite parent, int style) {
+               super(parent, style);
+
+               this.parent = parent;
+               this.selection = 0;
+
+               this.addPaintListener(new PaintListener() {
+                       @Override
+                       public void paintControl(PaintEvent e) {
+                               e.gc.setBackground(
+                                               new Color(parent.getDisplay(), PROGRESS_COLOR));
+
+                               Rectangle bounds = getBounds();
+                               int width = (bounds.width * selection) / 100; 
+                               e.gc.fillRectangle(0, 0, width, bounds.height);
+
+                               if (selection == -1) {
+                                       logger.info("progress : complete!");
+
+                                       parent.getDisplay().asyncExec(new Runnable() {
+                                               @Override
+                                               public void run() {
+                                                       dispose();
+                                               }
+                                       });
+                               }
+                       }
+               });
+
+               /* default is hidden */
+               parent.getDisplay().asyncExec(new Runnable() {
+                       @Override
+                       public void run() {
+                               setVisible(false);
+                       }
+               });
+       }
+
+       public void setSelection(int value) {
+               parent.getDisplay().asyncExec(new Runnable() {
+                       @Override
+                       public void run() {
+                               setVisible(true);
+                       }
+               });
+
+               if (value < 0) {
+                       value = 0;
+               } else if (value > 100) {
+                       value = 100;
+               }
+
+               selection = value;
+               logger.info("progress : " + selection);
+
+               parent.getDisplay().asyncExec(new Runnable() {
+                       @Override
+                       public void run() {
+                               redraw();
+
+                               if (selection == 100) {
+                                       selection = -1;
+                               }
+                       }
+               });
+       }
+
+       public int getSelection() {
+               return selection;
+       }
+}
diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/custom/CustomScrollBar.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/custom/CustomScrollBar.java
new file mode 100644 (file)
index 0000000..876c561
--- /dev/null
@@ -0,0 +1,226 @@
+/**
+ *
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@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
+ *
+ */
+
+package org.tizen.emulator.skin.custom;
+
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.logging.Logger;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.RowData;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.tizen.emulator.skin.log.SkinLogger;
+
+
+public class CustomScrollBar {
+       static final int SCROLL_SHIFT_LENGTH = 10;
+
+       private Logger logger = SkinLogger.getSkinLogger(
+                       CustomScrollBar.class).getLogger();
+
+       private Composite parent;
+       private Composite composite;
+       CustomScrolledComposite compositeScroll;
+
+       private int heightScrollBar;
+       private int maxShift;
+
+       private Image[] imagesArrowUp;
+       private Image[] imagesArrowDown;
+       private Image imageThumb;
+       private Image imageShaft;
+
+       private CustomButton buttonArrowUp;
+       private CustomButton buttonArrowDown;
+       private Canvas canvasShaft;
+       private CustomButton buttonThumb;
+
+       private int valueSelection;
+       private Timer timerScroller;
+       private TimerTask scroller;
+
+       CustomScrollBar(Composite parent, int style, int heightScrollBar,
+                       Image[] imagesArrowUp, Image[] imagesArrowDown,
+                       Image imageThumb, Image imageShaft) {
+               this.parent = parent;
+               this.composite = new Composite(parent, SWT.NONE);
+               this.compositeScroll = ((CustomScrolledComposite) parent.getParent());
+
+               RowLayout rowLayout = new RowLayout(SWT.VERTICAL);
+               rowLayout.marginLeft = rowLayout.marginRight = 0;
+               rowLayout.marginTop = rowLayout.marginBottom = 0;
+               rowLayout.marginWidth = rowLayout.marginHeight = 0;
+               rowLayout.spacing = 0;
+
+               composite.setLayout(rowLayout);
+
+               this.heightScrollBar = heightScrollBar;
+               this.maxShift = SCROLL_SHIFT_LENGTH;
+
+               this.imagesArrowUp = imagesArrowUp;
+               this.imagesArrowDown = imagesArrowDown;
+               this.imageThumb = imageThumb;
+               this.imageShaft = imageShaft;
+
+               //this.timerScroller = new Timer();
+
+               createContents();
+
+               addScrollBarListener();
+       }
+
+       protected void createContents() {
+               /* arrow up */
+               buttonArrowUp = new CustomButton(composite, SWT.NONE,
+                               imagesArrowUp[0], imagesArrowUp[1], imagesArrowUp[2]);
+
+               int width = buttonArrowUp.getImageSize().x;
+               int height = buttonArrowUp.getImageSize().y;
+
+               buttonArrowUp.setBackground(parent.getBackground());
+               buttonArrowUp.setLayoutData(new RowData(width, height));
+
+               /* shaft */
+               canvasShaft = new Canvas(composite, SWT.NONE);
+
+               final int widthShaft = width;
+               final int heightShaft = heightScrollBar - (height * 2);
+               canvasShaft.setLayoutData(new RowData(widthShaft, heightShaft));
+
+               canvasShaft.addPaintListener(new PaintListener() {
+                       @Override
+                       public void paintControl(PaintEvent e) {
+                               if (imageShaft != null) {
+                                       e.gc.drawImage(imageShaft, 0, 0,
+                                                       imageShaft.getImageData().width,
+                                                       imageShaft.getImageData().height,
+                                                       0, 0, widthShaft, heightShaft);
+                               }
+                       }
+               });
+
+               /* arrow down */
+               buttonArrowDown = new CustomButton(composite, SWT.NONE,
+                               imagesArrowDown[0], imagesArrowDown[1], imagesArrowDown[2]);
+
+               buttonArrowDown.setBackground(parent.getBackground());
+               buttonArrowDown.setLayoutData(new RowData(width, height));
+       }
+
+       class ScrollerTask extends TimerTask {
+               @Override
+               public void run() {
+                       int vSelection = getSelection();
+                       if (vSelection <= (173 - heightScrollBar - 1)) {
+                               setSelection(getSelection() + 1);
+                               logger.info("" + getSelection());
+
+//                             Display.getCurrent().asyncExec(new Runnable() {
+//                                     @Override
+//                                     public void run() {
+                               //compositeScroll.vScroll();
+//                                     }
+//                             });
+                       }
+               }
+       }
+
+       protected void addScrollBarListener() {
+               buttonArrowUp.addMouseListener(new MouseListener() {
+                       @Override
+                       public void mouseDown(MouseEvent e) {
+                               int shift = getSelection();
+
+                               if (shift > 0) {
+                                       setSelection(getSelection() - Math.min(maxShift, shift));
+                                       ((CustomScrolledComposite) parent.getParent()).vScroll();
+                               }
+                       }
+
+                       @Override
+                       public void mouseUp(MouseEvent e) {
+                               /* do nothing */
+                       }
+
+                       @Override
+                       public void mouseDoubleClick(MouseEvent e) {
+                               /* do nothing */
+                       }
+               });
+
+               buttonArrowDown.addMouseListener(new MouseListener() {
+                       @Override
+                       public void mouseDown(MouseEvent e) {
+                               int minHeightContents =
+                                               ((CustomScrolledComposite) parent.getParent()).getMinHeight();
+
+                               int shift = (minHeightContents - heightScrollBar) - getSelection();
+
+                               if (shift > 0) {
+                                       setSelection(getSelection() + Math.min(maxShift, shift));
+                                       ((CustomScrolledComposite) parent.getParent()).vScroll();
+                               }
+                       }
+
+                       @Override
+                       public void mouseUp(MouseEvent e) {
+                               timerScroller.cancel();
+                               timerScroller = new Timer();
+                       }
+
+                       @Override
+                       public void mouseDoubleClick(MouseEvent e) {
+                               /* do nothing */
+                       }
+               });
+
+//             buttonArrowDown.addDragDetectListener(new DragDetectListener() {
+//                     @Override
+//                     public void dragDetected( DragDetectEvent e ) {
+//                                     logger.info( "dragDetected:" + e.button );
+//                                     timerScroller.schedule(new ScrollerTask(), 1, 100);
+//                     }
+//             });
+       }
+
+       public int getSelection() {
+               return valueSelection;
+       }
+
+       public void setSelection(int selection) {
+               valueSelection = selection;
+       }
+}
diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/custom/CustomScrolledComposite.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/custom/CustomScrolledComposite.java
new file mode 100644 (file)
index 0000000..9f2c4ab
--- /dev/null
@@ -0,0 +1,178 @@
+/**
+ *
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@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
+ *
+ */
+
+package org.tizen.emulator.skin.custom;
+
+import java.util.logging.Logger;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Listener;
+import org.tizen.emulator.skin.log.SkinLogger;
+
+public class CustomScrolledComposite extends Composite {
+
+       private Logger logger =
+                       SkinLogger.getSkinLogger(CustomScrolledComposite.class).getLogger();
+
+       Control content;
+       Listener contentListener;
+       Listener filter;
+       Point sizeContent;
+
+       Composite compositeRight;
+       CustomScrollBar vBar;
+
+       private Image[] imagesArrowUp;
+       private Image[] imagesArrowDown;
+       private Image imageThumb;
+       private Image imageShaft;
+
+       public int minHeight = 0;
+       public int minWidth = 0;
+       public boolean expandHorizontal = false;
+       public boolean expandVertical = false;
+
+       private int value;
+
+       public CustomScrolledComposite(Composite parent, int style,
+                       Image[] imagesArrowUp, Image[] imagesArrowDown,
+                       Image imageThumb, Image imageShaft) {
+               super(parent, style);
+               super.setLayout(new ScrolledCompositeLayout());
+
+               compositeRight = new Composite(this, SWT.NONE);
+               compositeRight.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_YELLOW));
+
+               GridLayout compositeGridLayout = new GridLayout(1, false);
+               compositeGridLayout.marginLeft = compositeGridLayout.marginRight = 0;
+               compositeGridLayout.marginTop = compositeGridLayout.marginBottom = 0;
+               compositeGridLayout.marginWidth = compositeGridLayout.marginHeight = 0;
+               compositeGridLayout.horizontalSpacing = compositeGridLayout.verticalSpacing = 0;
+               compositeRight.setLayout(compositeGridLayout);
+
+               this.imagesArrowUp = imagesArrowUp;
+               this.imagesArrowDown = imagesArrowDown;
+               this.imageThumb = imageThumb;
+               this.imageShaft = imageShaft;
+
+               value = 0;
+       }
+
+       public CustomScrollBar getScrollBar() {
+               return vBar;
+       }
+
+       public void setContent(Control content, Point sizeContent) {
+               checkWidget();
+               if (this.content != null && !this.content.isDisposed()) {
+                       this.content.removeListener(SWT.Resize, contentListener);
+                       this.content.setBounds(new Rectangle(-200, -200, 0, 0));
+               }
+
+               this.content = content;
+               this.sizeContent = sizeContent;
+
+               if (this.content != null) {
+                       if (vBar == null) {
+                               compositeRight.setBackground(this.content.getBackground());
+                               vBar = new CustomScrollBar(compositeRight, SWT.NONE, sizeContent.y,
+                                               imagesArrowUp, imagesArrowDown, imageThumb, imageShaft);
+                       }
+
+                       content.setLocation(0, 0);
+
+                       layout(false);
+
+               }
+       }
+
+       public void setExpandHorizontal(boolean expand) {
+               checkWidget();
+               if (expand == expandHorizontal) return;
+               expandHorizontal = expand;
+               layout(false);
+       }
+
+       public void setExpandVertical(boolean expand) {
+               checkWidget();
+               if (expand == expandVertical) return;
+               expandVertical = expand;
+               layout(false);
+       }
+
+       public void setMinSize(Point size) {
+               if (size == null) {
+                       setMinSize(0, 0);
+               } else {
+                       setMinSize(size.x, size.y);
+               }
+       }
+
+       public void setMinSize(int width, int height) {
+               checkWidget();
+               if (width == minWidth && height == minHeight) {
+                       return;
+               }
+
+               minWidth = Math.max(0, width);
+               minHeight = Math.max(0, height);
+
+               logger.info("composite minWidth : " + minWidth +
+                               ", minHeight : " + minHeight);
+
+               layout(false);
+       }
+
+       public int getMinWidth() {
+               checkWidget();
+               return minWidth;
+       }
+
+       public int getMinHeight() {
+               checkWidget();
+               return minHeight;
+       }
+
+       public void vScroll() {
+               if (content == null) {
+                       return;
+               }
+
+               Point location = content.getLocation();
+               int vSelection = vBar.getSelection();
+
+               content.setLocation(location.x, -vSelection);
+       }
+}
\ No newline at end of file
diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/custom/CustomScrolledCompositeLayout.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/custom/CustomScrolledCompositeLayout.java
new file mode 100644 (file)
index 0000000..2b36253
--- /dev/null
@@ -0,0 +1,101 @@
+/**
+ *
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@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
+ *
+ */
+
+package org.tizen.emulator.skin.custom;
+
+import java.util.logging.Logger;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Layout;
+import org.tizen.emulator.skin.log.SkinLogger;
+
+class ScrolledCompositeLayout extends Layout {
+       static final int DEFAULT_WIDTH = 64;
+       static final int DEFAULT_HEIGHT = 64;
+
+       private Logger logger = SkinLogger.getSkinLogger(
+                       ScrolledCompositeLayout.class).getLogger();
+
+       private boolean inLayout = false;
+
+       protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
+               CustomScrolledComposite sc = (CustomScrolledComposite)composite;
+               Point size = new Point(DEFAULT_WIDTH, DEFAULT_HEIGHT);
+
+               if (sc.content != null) {
+                       Point preferredSize = sc.content.computeSize(wHint, hHint, flushCache);
+                       size.x = preferredSize.x;
+                       size.y = preferredSize.y;
+               }
+               size.x = Math.max(size.x, sc.minWidth);
+               size.y = Math.max(size.y, sc.minHeight);
+
+               if (wHint != SWT.DEFAULT) size.x = wHint;
+               if (hHint != SWT.DEFAULT) size.y = hHint;
+
+               return size;
+       }
+
+       protected boolean flushCache(Control control) {
+               return true;
+       }
+
+       protected void layout(Composite composite, boolean flushCache) {
+               if (inLayout) {
+                       return;
+               }
+
+               CustomScrolledComposite sc = (CustomScrolledComposite)composite;
+               if (sc.content == null) {
+                       return;
+               }
+
+               inLayout = true;
+               Rectangle contentRect = sc.content.getBounds();
+
+               Rectangle hostRect = sc.getClientArea();
+               if (sc.expandHorizontal) {
+                       contentRect.width = Math.max(sc.minWidth, hostRect.width);
+               }
+               if (sc.expandVertical) {
+                       contentRect.height = Math.max(sc.minHeight, hostRect.height);
+               }
+
+               sc.content.setBounds(contentRect);
+
+               Point size = sc.compositeRight.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+               sc.compositeRight.setBounds(
+                               contentRect.width - size.x, 0, size.x, contentRect.height);
+
+               inLayout = false;
+       }
+}
diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/custom/KeyWindow.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/custom/KeyWindow.java
new file mode 100644 (file)
index 0000000..0eb30aa
--- /dev/null
@@ -0,0 +1,474 @@
+/**
+ *
+ *
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@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
+ *
+ */
+
+package org.tizen.emulator.skin.custom;
+
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.events.ShellEvent;
+import org.eclipse.swt.events.ShellListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.graphics.Region;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.tizen.emulator.skin.EmulatorSkin;
+import org.tizen.emulator.skin.comm.ICommunicator.KeyEventType;
+import org.tizen.emulator.skin.comm.ICommunicator.SendCommand;
+import org.tizen.emulator.skin.comm.sock.SocketCommunicator;
+import org.tizen.emulator.skin.comm.sock.data.KeyEventData;
+import org.tizen.emulator.skin.dbi.KeyMapType;
+import org.tizen.emulator.skin.image.ImageRegistry.KeyWindowImageName;
+import org.tizen.emulator.skin.layout.SkinPatches;
+import org.tizen.emulator.skin.util.SwtUtil;
+
+public class KeyWindow extends SkinWindow {
+       private static final String PATCH_IMAGES_PATH = "images/key-window/";
+       private static final int SHELL_MARGIN_BOTTOM = 3;
+       private static final int PAIRTAG_CIRCLE_SIZE = 8;
+       private static final int PAIRTAG_MARGIN_BOTTOM = 6;
+       private static final int BUTTON_DEFAULT_CNT = 4;
+       private static final int BUTTON_VERTICAL_SPACING = 7;
+       private static final int SCROLLBAR_HORIZONTAL_SPACING = 4;
+       private static final int SCROLLBAR_SIZE_WIDTH = 14;
+
+       private EmulatorSkin skin;
+       private SkinPatches frameMaker;
+
+       private int widthBase;
+       private int heightBase;
+       private int widthScrollbar;
+       private int cntHiddenButton;
+
+       private Image imageNormal; /* ImageButton image */
+       private Image imageHover; /* hovered ImageButton image */
+       private Image imagePushed; /* pushed ImageButton image */
+       private Image imageFrame; /* nine-patch image */
+
+       private Color colorFrame;
+       private SocketCommunicator communicator;
+       private List<KeyMapType> keyMapList;
+
+       private ShellListener shellListener;
+       private PaintListener shellPaintListener;
+       private MouseMoveListener shellMouseMoveListener;
+       private MouseListener shellMouseListener;
+
+       private boolean isGrabbedShell;
+       private Point grabPosition;
+
+       public KeyWindow(EmulatorSkin skin, Shell parent,
+                       SocketCommunicator communicator, List<KeyMapType> keyMapList) {
+               super(parent, SWT.RIGHT | SWT.CENTER);
+
+               this.skin = skin;
+               this.shell = new Shell(Display.getDefault(),
+                               SWT.NO_TRIM | SWT.RESIZE | SWT.TOOL);
+               this.frameMaker = new SkinPatches(PATCH_IMAGES_PATH);
+
+               this.keyMapList = keyMapList; //TODO: null
+               this.communicator = communicator;
+               this.grabPosition = new Point(0, 0);
+
+               shell.setText(parent.getText());
+               shell.setImage(parent.getImage());
+
+               /* load image for HW key button */
+               imageNormal = skin.getImageRegistry().getKeyWindowImageData(
+                               KeyWindowImageName.KEYBUTTON_NORMAL);
+               imageHover = skin.getImageRegistry().getKeyWindowImageData(
+                               KeyWindowImageName.KEYBUTTON_HOVER);
+               imagePushed = skin.getImageRegistry().getKeyWindowImageData(
+                               KeyWindowImageName.KEYBUTTON_PUSHED);
+
+               /* calculate the key window size */
+               widthBase = imageNormal.getImageData().width;
+               heightBase = (imageNormal.getImageData().height * BUTTON_DEFAULT_CNT) +
+                               (BUTTON_VERTICAL_SPACING * (BUTTON_DEFAULT_CNT - 1));
+
+               widthScrollbar = SCROLLBAR_SIZE_WIDTH + SCROLLBAR_HORIZONTAL_SPACING;
+               int heightHeaderPart = (PAIRTAG_CIRCLE_SIZE + PAIRTAG_MARGIN_BOTTOM);
+               int heightTailPart = SHELL_MARGIN_BOTTOM;
+
+               /* make a frame image */
+               this.cntHiddenButton = 0; //keyMapList.size() - BUTTON_DEFAULT_CNT;
+
+               this.imageFrame = frameMaker.getPatchedImage(
+                               widthBase + ((cntHiddenButton > 0) ? widthScrollbar : 0),
+                               heightBase + heightHeaderPart + heightTailPart);
+               this.colorFrame = new Color(shell.getDisplay(), new RGB(38, 38, 38));
+
+               shell.setBackground(colorFrame);
+
+               createContents();
+               trimPatchedShell(shell, imageFrame);
+
+               addKeyWindowListener();
+
+               shell.setSize(imageFrame.getImageData().width,
+                               imageFrame.getImageData().height);
+       }
+
+       protected void createContents() {
+               GridLayout shellGridLayout = new GridLayout(1, false);
+               shellGridLayout.marginLeft = shellGridLayout.marginRight = frameMaker.getPatchWidth();
+               shellGridLayout.marginTop = frameMaker.getPatchHeight();
+               shellGridLayout.marginBottom = frameMaker.getPatchHeight() + SHELL_MARGIN_BOTTOM;
+               shellGridLayout.marginWidth = shellGridLayout.marginHeight = 0;
+               shellGridLayout.horizontalSpacing = shellGridLayout.verticalSpacing = 0;
+
+               shell.setLayout(shellGridLayout);
+
+               /* make a pair tag circle */
+               ColorTag pairTagCanvas = new ColorTag(shell, SWT.NONE, skin.getColorVM());
+               pairTagCanvas.setLayoutData(new GridData(PAIRTAG_CIRCLE_SIZE,
+                               PAIRTAG_CIRCLE_SIZE + PAIRTAG_MARGIN_BOTTOM));
+
+               /* make a region of HW keys */
+               if (cntHiddenButton > 0) {
+                       /* added custom scrollbar */
+
+                       Image imagesScrollArrowUp[] = new Image[3];
+                       Image imagesScrollArrowDown[] = new Image[3];
+
+                       imagesScrollArrowUp[0] = skin.getImageRegistry().getKeyWindowImageData(
+                                       KeyWindowImageName.SCROLL_UPBUTTON_NORMAL);
+                       imagesScrollArrowUp[1] = skin.getImageRegistry().getKeyWindowImageData(
+                                       KeyWindowImageName.SCROLL_UPBUTTON_HOVER);
+                       imagesScrollArrowUp[2] = skin.getImageRegistry().getKeyWindowImageData(
+                                       KeyWindowImageName.SCROLL_UPBUTTON_PUSHED);
+
+                       imagesScrollArrowDown[0] = skin.getImageRegistry().getKeyWindowImageData(
+                                       KeyWindowImageName.SCROLL_DOWNBUTTON_NORMAL);
+                       imagesScrollArrowDown[1] = skin.getImageRegistry().getKeyWindowImageData(
+                                       KeyWindowImageName.SCROLL_DOWNBUTTON_HOVER);
+                       imagesScrollArrowDown[2] = skin.getImageRegistry().getKeyWindowImageData(
+                                       KeyWindowImageName.SCROLL_DOWNBUTTON_PUSHED);
+
+                       CustomScrolledComposite compositeScroll =
+                                       new CustomScrolledComposite(shell, SWT.NONE,
+                                                       imagesScrollArrowUp, imagesScrollArrowDown,
+                                                       skin.getImageRegistry().getKeyWindowImageData(
+                                                                       KeyWindowImageName.SCROLL_THUMB),
+                                                       skin.getImageRegistry().getKeyWindowImageData(
+                                                                       KeyWindowImageName.SCROLL_SHAFT));
+                       compositeScroll.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true, 1, 1));
+
+                       Composite compositeBase = new Composite(compositeScroll, SWT.NONE);
+
+                       createHwKeys(compositeBase);
+
+                       Point sizeContent = compositeBase.computeSize(
+                                       widthBase + widthScrollbar, heightBase);
+                       compositeScroll.setContent(compositeBase, sizeContent);
+                       compositeScroll.setExpandHorizontal(true);
+                       compositeScroll.setExpandVertical(true);
+
+                       sizeContent.y += (imageNormal.getImageData().height * cntHiddenButton) +
+                                       (BUTTON_VERTICAL_SPACING * cntHiddenButton);
+                       compositeScroll.setMinSize(sizeContent);
+               } else {
+                       ScrolledComposite compositeScroll = new ScrolledComposite(shell, SWT.V_SCROLL);
+                       compositeScroll.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true, 1, 1));
+
+                       Composite compositeBase = new Composite(compositeScroll, SWT.NONE);
+                       createHwKeys(compositeBase);
+
+                       compositeScroll.setContent(compositeBase);
+                       compositeScroll.setExpandHorizontal(true);
+                       compositeScroll.setExpandVertical(true);
+                       compositeScroll.setMinSize(compositeBase.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+               }
+       }
+
+       protected void createHwKeys(Composite composite) {
+               composite.setBackground(colorFrame);
+
+               GridLayout compositeGridLayout = new GridLayout(1, false);
+               compositeGridLayout.marginLeft = compositeGridLayout.marginRight = 0;
+               compositeGridLayout.marginTop = compositeGridLayout.marginBottom = 0;
+               compositeGridLayout.marginWidth = compositeGridLayout.marginHeight = 0;
+               compositeGridLayout.horizontalSpacing = 0;
+               compositeGridLayout.verticalSpacing = BUTTON_VERTICAL_SPACING;
+               composite.setLayout(compositeGridLayout);
+
+               /* attach HW keys */
+               if (keyMapList != null && keyMapList.isEmpty() == false) {
+                       for (KeyMapType keyEntry : keyMapList) {
+                               CustomButton HWKeyButton = new CustomButton(composite,
+                                               SWT.NO_FOCUS, imageNormal, imageHover, imagePushed);
+                               HWKeyButton.setText(keyEntry.getEventInfo().getKeyName());
+                               HWKeyButton.setToolTipText(keyEntry.getTooltip());
+                               HWKeyButton.setBackground(colorFrame);
+                               HWKeyButton.setLayoutData(new GridData(imageNormal.getImageData().width,
+                                                               imageNormal.getImageData().height));
+
+                               final int keycode = keyEntry.getEventInfo().getKeyCode();
+                               HWKeyButton.addMouseListener(new MouseListener() {
+                                       @Override
+                                       public void mouseDown(MouseEvent e) {
+                                               KeyEventData keyEventData = new KeyEventData(
+                                                               KeyEventType.PRESSED.value(), keycode, 0, 0);
+                                               communicator.sendToQEMU(SendCommand.SEND_HARD_KEY_EVENT, keyEventData);
+                                       }
+
+                                       @Override
+                                       public void mouseUp(MouseEvent e) {
+                                               KeyEventData keyEventData = new KeyEventData(
+                                                               KeyEventType.RELEASED.value(), keycode, 0, 0);
+                                               communicator.sendToQEMU(SendCommand.SEND_HARD_KEY_EVENT, keyEventData);
+                                       }
+
+                                       @Override
+                                       public void mouseDoubleClick(MouseEvent e) {
+                                               /* do nothing */
+                                       }
+                               });
+                       }
+               }
+       }
+
+       public static void trimPatchedShell(Shell shell, Image image) {
+               if (null == image) {
+                       return;
+               }
+               ImageData imageData = image.getImageData();
+
+               int width = imageData.width;
+               int height = imageData.height;
+
+               Region region = new Region();
+               region.add(new Rectangle(0, 0, width, height));
+
+               int r = shell.getDisplay().getSystemColor(SWT.COLOR_MAGENTA).getRed();
+               int g = shell.getDisplay().getSystemColor(SWT.COLOR_MAGENTA).getGreen();
+               int b = shell.getDisplay().getSystemColor(SWT.COLOR_MAGENTA).getBlue();
+               int colorKey;
+
+               if (SwtUtil.isWindowsPlatform()) {
+                       colorKey = r << 24 | g << 16 | b << 8;
+               } else {
+                       colorKey = r << 16 | g << 8 | b;
+               }
+
+               for (int i = 0; i < width; i++) {
+                       for (int j = 0; j < height; j++) {
+                               int colorPixel = imageData.getPixel(i, j);
+                               if (colorPixel == colorKey /* magenta */) {
+                                       region.subtract(i, j, 1, 1);
+                               }
+                       }
+               }
+
+               shell.setRegion(region);
+       }
+
+       private void addKeyWindowListener() {
+               shellPaintListener = new PaintListener() {
+                       @Override
+                       public void paintControl(final PaintEvent e) {
+                               if (imageFrame != null) {
+                                       e.gc.drawImage(imageFrame, 0, 0);
+                               }
+                       }
+               };
+
+               shell.addPaintListener(shellPaintListener);
+
+               shellListener = new ShellListener() {
+                       @Override
+                       public void shellClosed(ShellEvent event) {
+                               logger.info("Key Window is closed");
+
+                               if (skin.pairTag != null) {
+                                       skin.pairTag.setVisible(false);
+                               }
+                               skin.keyWindow = null;
+
+                               if (null != shellPaintListener) {
+                                       shell.removePaintListener(shellPaintListener);
+                               }
+
+                               if (null != shellListener) {
+                                       shell.removeShellListener(shellListener);
+                               }
+
+                               if (null != shellMouseMoveListener) {
+                                       shell.removeMouseMoveListener(shellMouseMoveListener);
+                               }
+
+                               if (null != shellMouseListener) {
+                                       shell.removeMouseListener(shellMouseListener);
+                               }
+
+                               colorFrame.dispose();
+
+                               frameMaker.freePatches();
+                       }
+
+                       @Override
+                       public void shellActivated(ShellEvent event) {
+                               logger.info("activate");
+
+                               if (SwtUtil.isMacPlatform() == true) {
+                                       parent.moveAbove(shell);
+                               } else {
+                                       shell.getDisplay().asyncExec(new Runnable() {
+                                               @Override
+                                               public void run() {
+                                                       parent.setActive();
+                                               }
+                                       });
+                               }
+                       }
+
+                       @Override
+                       public void shellDeactivated(ShellEvent event) {
+                               logger.info("deactivate");
+
+                               /* do nothing */
+                       }
+
+                       @Override
+                       public void shellIconified(ShellEvent event) {
+                               /* do nothing */
+                       }
+
+                       @Override
+                       public void shellDeiconified(ShellEvent event) {
+                               logger.info("deiconified");
+
+                               shell.getDisplay().asyncExec(new Runnable() {
+                                       @Override
+                                       public void run() {
+                                               if (parent.getMinimized() == true) {
+                                                       parent.setMinimized(false);
+                                               }
+                                       }
+                               });
+                       }
+               };
+
+               shell.addShellListener(shellListener);
+
+               shellMouseMoveListener = new MouseMoveListener() {
+                       @Override
+                       public void mouseMove(MouseEvent e) {
+                               if (isGrabbedShell == true && e.button == 0/* left button */) {
+                                       if (getDockPosition() != SWT.NONE) {
+                                               dock(SWT.NONE, false, false);
+                                               shell.moveAbove(parent);
+                                       }
+
+                                       /* move a window */
+                                       Point previousLocation = shell.getLocation();
+                                       int x = previousLocation.x + (e.x - grabPosition.x);
+                                       int y = previousLocation.y + (e.y - grabPosition.y);
+
+                                       shell.setLocation(x, y);
+                                       return;
+                               }
+                       }
+               };
+
+               shell.addMouseMoveListener(shellMouseMoveListener);
+
+               shellMouseListener = new MouseListener() {
+                       @Override
+                       public void mouseUp(MouseEvent e) {
+                               if (e.button == 1) { /* left button */
+                                       isGrabbedShell = false;
+                                       grabPosition.x = grabPosition.y = 0;
+
+                                       /* Let me check whether the key window was landed
+                                        * on docking area. */
+                                       Rectangle parentBounds = parent.getBounds();
+                                       Rectangle childBounds = shell.getBounds();
+
+                                       int heightOneThird = parentBounds.height / 3;
+
+                                       /* right-middle */
+                                       Rectangle attachBounds1 = new Rectangle(
+                                                       (parentBounds.x + parentBounds.width) - 5,
+                                                       parentBounds.y + heightOneThird,
+                                                       30, heightOneThird);
+                                       /* right-top */
+                                       Rectangle attachBounds2 = new Rectangle(
+                                                       (parentBounds.x + parentBounds.width) - 5,
+                                                       parentBounds.y,
+                                                       30, heightOneThird);
+                                       /* right-bottom */
+                                       Rectangle attachBounds3 = new Rectangle(
+                                                       (parentBounds.x + parentBounds.width) - 5,
+                                                       parentBounds.y + (heightOneThird * 2),
+                                                       30, heightOneThird);
+
+                                       if (childBounds.intersects(attachBounds1) == true) {
+                                               dock(SWT.RIGHT | SWT.CENTER, false, true);
+                                       } else if (childBounds.intersects(attachBounds2) == true) {
+                                               dock(SWT.RIGHT | SWT.TOP, false, true);
+                                       } else if (childBounds.intersects(attachBounds3) == true) {
+                                               dock(SWT.RIGHT | SWT.BOTTOM, false, true);
+                                       } else {
+                                               dock(SWT.NONE, false, true);
+                                       }
+                               }
+                       }
+
+                       @Override
+                       public void mouseDown(MouseEvent e) {
+                               if (1 == e.button) { /* left button */
+                                       isGrabbedShell = true;
+                                       grabPosition.x = e.x;
+                                       grabPosition.y = e.y;
+                               }
+                       }
+
+                       @Override
+                       public void mouseDoubleClick(MouseEvent e) {
+                               /* do nothing */
+                       }
+               };
+
+               shell.addMouseListener(shellMouseListener);
+       }
+}
diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/custom/SkinWindow.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/custom/SkinWindow.java
new file mode 100644 (file)
index 0000000..19e0874
--- /dev/null
@@ -0,0 +1,130 @@
+/**
+ *
+ *
+ * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@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
+ *
+ */
+
+package org.tizen.emulator.skin.custom;
+
+import java.util.logging.Logger;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.tizen.emulator.skin.log.SkinLogger;
+
+public class SkinWindow {
+       protected Logger logger = SkinLogger.getSkinLogger(
+                       SkinWindow.class).getLogger();
+
+       protected Shell shell;
+       protected Shell parent;
+       private int dockPosition;
+
+       public SkinWindow(Shell parent, int dockPosition) {
+               this.parent = parent;
+               this.dockPosition = dockPosition;
+       }
+
+       public Shell getShell() {
+               return shell;
+       }
+
+       public void open(int dockValue) {
+               if (shell.isDisposed()) {
+                       return;
+               }
+
+               dock(dockValue, true, true);
+
+               shell.open();
+       }
+
+       public void dock(int dockValue,
+                       boolean correction, boolean enableLogger) {
+               int x = 0;
+               int y = 0;
+
+               Rectangle monitorBounds = Display.getDefault().getBounds();
+               Rectangle parentBounds = parent.getBounds();
+               Rectangle childBounds = shell.getBounds();
+
+               if (enableLogger == true) {
+                       logger.info("host monitor display bounds : " + monitorBounds);
+                       logger.info("current parent shell bounds : " + parentBounds);
+                       logger.info("current child shell bounds : " + childBounds);
+               }
+
+               dockPosition = dockValue;
+
+               if (dockPosition == SWT.NONE){
+                       logger.info("undock");
+                       /* do nothing */
+
+                       return;
+               } else if (dockPosition == (SWT.RIGHT | SWT.TOP)) {
+                       x = parentBounds.x + parentBounds.width;
+                       y = parentBounds.y;
+
+                       /* correction of location */
+                       /*if ((x + childBounds.width) >
+                                       (monitorBounds.x + monitorBounds.width)) {
+                               x = parentBounds.x - childBounds.width;
+                       }*/
+               } else if (dockPosition == (SWT.RIGHT | SWT.BOTTOM)) {
+                       x = parentBounds.x + parentBounds.width;
+                       y = parentBounds.y + parentBounds.height - childBounds.height;
+
+                       /* correction of location */
+                       /*int shift = (monitorBounds.x + monitorBounds.width) -
+                                       (x + childBounds.width);
+                       if (shift < 0) {
+                               x += shift;
+                               parent.setLocation(parentBounds.x + shift, parentBounds.y);
+                       }*/
+               } else { /* SWT.RIGHT | SWT.CENTER */
+                       x = parentBounds.x + parentBounds.width;
+                       y = parentBounds.y + (parentBounds.height / 2) -
+                                       (childBounds.height / 2);
+               }
+
+               /* correction of location */
+               if (correction == true) {
+                       int shift = (monitorBounds.x + monitorBounds.width) -
+                                       (x + childBounds.width);
+                       if (shift < 0) {
+                               x += shift;
+                               parent.setLocation(parentBounds.x + shift, parentBounds.y);
+                       }
+               }
+
+               shell.setLocation(x, y);
+       }
+
+       public int getDockPosition() {
+               return dockPosition;
+       }
+}
index 0077773..c95ba24 100644 (file)
@@ -52,6 +52,7 @@ import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Link;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Text;
+import org.tizen.emulator.skin.config.EmulatorConfig;
 import org.tizen.emulator.skin.log.SkinLogger;
 import org.tizen.emulator.skin.util.IOUtil;
 import org.tizen.emulator.skin.util.StringUtil;
@@ -67,12 +68,17 @@ public class AboutDialog extends SkinDialog {
 
        public static final String URL_TIZEN_ORG = "https://developer.tizen.org";
 
+       private Logger logger =
+                       SkinLogger.getSkinLogger(AboutDialog.class).getLogger();
+
        private Image aboutImage;
+       private EmulatorConfig config;
 
-       private Logger logger = SkinLogger.getSkinLogger(AboutDialog.class).getLogger();
 
-       public AboutDialog(Shell parent) {
+       public AboutDialog(Shell parent, EmulatorConfig config) {
                super(parent, "About Tizen Emulator", SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
+
+               this.config = config;
        }
 
        private GridLayout getNopaddedGridLayout(int numColumns, boolean makeColumnEqualWidth) {
@@ -160,10 +166,13 @@ public class AboutDialog extends SkinDialog {
 
                /* SDK version */
                Text versionText = new Text(compositeRight, SWT.NONE);
-               String version = getValue(properties, PROP_KEY_VERSION);
+               /*String version = getValue(properties, PROP_KEY_VERSION);
                if (version.isEmpty()) {
                        version = "Not identified";
-               }
+               }*/
+               String version = config.getSkinProperty(
+                               EmulatorConfig.SkinInfoConstants.SDK_VERSION_NAME);
+
                versionText.setText("Version : " + version);
                versionText.setEditable(false);
                versionText.setBackground(white);
index 7e77c00..d7623f8 100644 (file)
@@ -63,14 +63,15 @@ public class ImageRegistry {
        public static final String SKINS_FOLDER = "skins";
        public static final String GENERAL_FOLDER = "emul-general";
        public static final String ICON_FOLDER = "icons";
-       
+       public static final String IMAGES_FOLDER = "images";
+       public static final String KEYWINDOW_FOLDER = "key-window";
+
        public enum ImageType {
                IMG_TYPE_MAIN,
                IMG_TYPE_PRESSED
        }
-       
+
        public enum IconName {
-               
                DETAIL_INFO("detail_info.png"),
                ROTATE("rotate.png"),
                SCALE("scale.png"),
@@ -104,12 +105,38 @@ public class ImageRegistry {
                }
                
        }
-       
+
+       public enum KeyWindowImageName {
+               KEYBUTTON_NORMAL("keybutton_nml.png"),
+               KEYBUTTON_HOVER("keybutton_hover.png"),
+               KEYBUTTON_PUSHED("keybutton_pushed.png"),
+
+               SCROLL_UPBUTTON_NORMAL("scroll_button_up_nml.png"),
+               SCROLL_UPBUTTON_HOVER("scroll_button_up_hover.png"),
+               SCROLL_UPBUTTON_PUSHED("scroll_button_up_pushed.png"),
+               SCROLL_DOWNBUTTON_NORMAL("scroll_button_down_nml.png"),
+               SCROLL_DOWNBUTTON_HOVER("scroll_button_down_hover.png"),
+               SCROLL_DOWNBUTTON_PUSHED("scroll_button_down_pushed.png"),
+               SCROLL_THUMB("scroll_thumb.png"),
+               SCROLL_SHAFT("scroll_back.png");
+
+               private String name;
+
+               private KeyWindowImageName(String name) {
+                       this.name = name;
+               }
+
+               public String getName() {
+                       return this.name;
+               }
+       }
+
        private Display display;
        private EmulatorUI dbiContents;
 
        private Map<String, Image> skinImageMap;
        private Map<String, Image> iconMap;
+       private Map<String, Image> keyWindowImageMap;
 
        private String argSkinPath;
 
@@ -140,6 +167,7 @@ public class ImageRegistry {
                this.dbiContents = config.getDbiContents();
                this.skinImageMap = new HashMap<String, Image>();
                this.iconMap = new HashMap<String, Image>();
+               this.keyWindowImageMap = new HashMap<String, Image>();
 
                init(this.argSkinPath);
 
@@ -243,13 +271,12 @@ public class ImageRegistry {
                return id + ":" + imageType.ordinal();
        }
 
-       public Image getIcon( IconName name ) {
+       public Image getIcon(IconName name) {
 
-               if ( 0 != iconMap.size() ) {
+               if (0 != iconMap.size()) {
+                       Image image = iconMap.get(name.getName());
 
-                       Image image = iconMap.get( name.getName() );
                        return image;
-
                } else {
 
                        // load all of the icons at once.
@@ -257,7 +284,7 @@ public class ImageRegistry {
                        ClassLoader classLoader = this.getClass().getClassLoader();
                        IconName[] values = IconName.values();
 
-                       for ( IconName iconName : values ) {
+                       for (IconName iconName : values) {
 
                                String icoNname = iconName.getName();
 
@@ -265,53 +292,93 @@ public class ImageRegistry {
 
                                InputStream is = null;
                                try {
-                                       is = classLoader.getResourceAsStream( iconPath );
-                                       if ( null != is ) {
-                                               logger.fine( "load icon:" + iconPath );
-                                               iconMap.put( icoNname, new Image( display, is ) );
+                                       is = classLoader.getResourceAsStream(iconPath);
+                                       if (null != is) {
+                                               logger.fine("load icon:" + iconPath);
+                                               iconMap.put(icoNname, new Image(display, is));
                                        } else {
-                                               logger.severe( "missing icon:" + iconPath );
+                                               logger.severe("missing icon:" + iconPath);
                                        }
                                } finally {
-                                       IOUtil.close( is );
+                                       IOUtil.close(is);
                                }
 
                        }
 
-                       return iconMap.get( name.getName() );
-
+                       return iconMap.get(name.getName());
                }
-
        }
 
-       public void dispose() {
+       public Image getKeyWindowImageData(KeyWindowImageName name) {
+               if (0 != keyWindowImageMap.size()) {
+                       Image image = keyWindowImageMap.get(name.getName());
+
+                       return image;
+               } else {
+                       ClassLoader classLoader = this.getClass().getClassLoader();
+                       KeyWindowImageName[] values = KeyWindowImageName.values();
 
-               if ( null != skinImageMap ) {
+                       for (KeyWindowImageName value : values) {
 
+                               String imageName = value.getName();
+
+                               String imagePath = IMAGES_FOLDER + "/" +
+                                               KEYWINDOW_FOLDER + "/" + imageName;
+
+                               InputStream is = null;
+                               try {
+                                       is = classLoader.getResourceAsStream(imagePath);
+                                       if (null != is) {
+                                               logger.fine("load keywindow images:" + imagePath);
+                                               keyWindowImageMap.put(imageName, new Image(display, is));
+                                       } else {
+                                               logger.severe("missing image:" + imagePath);
+                                       }
+                               } finally {
+                                       IOUtil.close(is);
+                               }
+
+                       }
+
+                       return keyWindowImageMap.get(name.getName());
+               }
+       }
+
+       public void dispose() {
+               /* skin image */
+               if (null != skinImageMap) {
                        Collection<Image> images = skinImageMap.values();
 
                        Iterator<Image> imageIterator = images.iterator();
 
-                       while ( imageIterator.hasNext() ) {
+                       while (imageIterator.hasNext()) {
                                Image image = imageIterator.next();
                                image.dispose();
                        }
-
                }
 
-               if ( null != iconMap ) {
-
+               /* icon */
+               if (null != iconMap) {
                        Collection<Image> icons = iconMap.values();
 
                        Iterator<Image> iconIterator = icons.iterator();
 
-                       while ( iconIterator.hasNext() ) {
+                       while (iconIterator.hasNext()) {
                                Image image = iconIterator.next();
                                image.dispose();
                        }
-
                }
 
+               /* key window image */
+               if (null != keyWindowImageMap) {
+                       Collection<Image> images = keyWindowImageMap.values();
+
+                       Iterator<Image> imagesIterator = images.iterator();
+
+                       while (imagesIterator.hasNext()) {
+                               Image image = imagesIterator.next();
+                               image.dispose();
+                       }
+               }
        }
-       
 }
index 2fbb281..fe317df 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * 
  *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Contact:
  * GiWoong Kim <giwoong.kim@samsung.com>
@@ -51,6 +51,7 @@ import org.tizen.emulator.skin.comm.ICommunicator.RotationInfo;
 import org.tizen.emulator.skin.config.EmulatorConfig;
 import org.tizen.emulator.skin.config.EmulatorConfig.ArgsConstants;
 import org.tizen.emulator.skin.config.EmulatorConfig.SkinPropertiesConstants;
+import org.tizen.emulator.skin.custom.ColorTag;
 import org.tizen.emulator.skin.custom.CustomButton;
 import org.tizen.emulator.skin.custom.CustomProgressBar;
 import org.tizen.emulator.skin.image.ImageRegistry;
@@ -68,8 +69,6 @@ public class GeneralPurposeSkinComposer implements ISkinComposer {
 
        private static final int PAIR_TAG_POSITION_X = 26;
        private static final int PAIR_TAG_POSITION_Y = 13;
-       private static final int PAIR_TAG_POSITION_WIDTH = 8;
-       private static final int PAIR_TAG_POSITION_HEIGHT = 8;
 
        private Logger logger = SkinLogger.getSkinLogger(
                        GeneralPurposeSkinComposer.class).getLogger();
@@ -109,6 +108,8 @@ public class GeneralPurposeSkinComposer implements ISkinComposer {
 
        @Override
        public Canvas compose(int style) {
+               shell.setBackground(backgroundColor);
+
                displayCanvas = new Canvas(shell, style);
 
                int vmIndex = config.getArgInt(ArgsConstants.NET_BASE_PORT) % 100;
@@ -141,7 +142,7 @@ public class GeneralPurposeSkinComposer implements ISkinComposer {
                shell.setLocation(x, y);
 
                String emulatorName = SkinUtil.makeEmulatorName(config);
-               shell.setText(emulatorName);
+               shell.setText("Emulator - " + emulatorName);
 
                displayCanvas.setBackground(
                                shell.getDisplay().getSystemColor(SWT.COLOR_BLACK));
@@ -189,21 +190,9 @@ public class GeneralPurposeSkinComposer implements ISkinComposer {
                });
 
                /* make a pair tag circle */
-               skin.pairTagCanvas = new Canvas(shell, SWT.NO_FOCUS);
-               skin.pairTagCanvas.setBackground(backgroundColor);
-
-               skin.pairTagCanvas.addPaintListener(new PaintListener() {
-                       @Override
-                       public void paintControl(PaintEvent e) {
-                               if (skin.colorPairTag != null) {
-                                       e.gc.setBackground(skin.colorPairTag);
-                                       e.gc.setAntialias(SWT.ON);
-                                       e.gc.fillOval(
-                                                       0, 0, PAIR_TAG_POSITION_WIDTH, PAIR_TAG_POSITION_HEIGHT);
-                               }
-                       }
-               });
-               skin.pairTagCanvas.setVisible(false);
+               skin.pairTag =
+                               new ColorTag(shell, SWT.NO_FOCUS, skin.getColorVM());
+               skin.pairTag.setVisible(false);
 
                /* create a progress bar for booting status */
                skin.bootingProgress = new CustomProgressBar(shell, SWT.NONE);
@@ -269,11 +258,6 @@ public class GeneralPurposeSkinComposer implements ISkinComposer {
                                        displayBounds.y + displayBounds.height + 1, displayBounds.width, 2);
                }
 
-               /* arrange the pair tag */
-               skin.pairTagCanvas.setBounds(
-                               PAIR_TAG_POSITION_X, PAIR_TAG_POSITION_Y,
-                               PAIR_TAG_POSITION_WIDTH, PAIR_TAG_POSITION_HEIGHT);
-
                /* set window size */
                if (currentState.getCurrentImage() != null) {
                        ImageData imageData = currentState.getCurrentImage().getImageData();
@@ -287,6 +271,29 @@ public class GeneralPurposeSkinComposer implements ISkinComposer {
                        shell.setSize(imageData.width, imageData.height);
                }
 
+               /* arrange the pair tag */
+               int rotationType = currentState.getCurrentRotationId();
+               if (rotationType == RotationInfo.PORTRAIT.id()) {
+                       skin.pairTag.setBounds(
+                                       PAIR_TAG_POSITION_X, PAIR_TAG_POSITION_Y,
+                                       skin.pairTag.getWidth(), skin.pairTag.getHeight());
+               } else if (rotationType == RotationInfo.LANDSCAPE.id()) {
+                       skin.pairTag.setBounds(
+                                       PAIR_TAG_POSITION_Y,
+                                       shell.getSize().y - PAIR_TAG_POSITION_X - skin.pairTag.getHeight(),
+                                       skin.pairTag.getWidth(), skin.pairTag.getHeight());
+               } else if (rotationType == RotationInfo.REVERSE_PORTRAIT.id()) {
+                       skin.pairTag.setBounds(
+                                       shell.getSize().x - PAIR_TAG_POSITION_X - skin.pairTag.getWidth(),
+                                       shell.getSize().y - PAIR_TAG_POSITION_Y - skin.pairTag.getHeight(),
+                                       skin.pairTag.getWidth(), skin.pairTag.getHeight());
+               } else if (rotationType == RotationInfo.REVERSE_LANDSCAPE.id()) {
+                       skin.pairTag.setBounds(
+                                       shell.getSize().x - PAIR_TAG_POSITION_Y - skin.pairTag.getWidth(),
+                                       PAIR_TAG_POSITION_X,
+                                       skin.pairTag.getWidth(), skin.pairTag.getHeight());
+               }
+
                /* custom window shape */
                trimPatchedShell(shell, currentState.getCurrentImage());
 
@@ -499,8 +506,8 @@ public class GeneralPurposeSkinComposer implements ISkinComposer {
                        toggleButton.dispose();
                }
 
-               if (skin.pairTagCanvas != null) {
-                       skin.pairTagCanvas.dispose();
+               if (skin.pairTag != null) {
+                       skin.pairTag.dispose();
                }
 
                if (backgroundColor != null) {
index 7fd6b9e..21eeeea 100644 (file)
@@ -136,7 +136,7 @@ public class PhoneShapeSkinComposer implements ISkinComposer {
                shell.setLocation(x, y);
 
                String emulatorName = SkinUtil.makeEmulatorName(config);
-               shell.setText(emulatorName);
+               shell.setText("Emulator - " + emulatorName);
 
                lcdCanvas.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK));
 
index 7d97323..b4d0a51 100644 (file)
@@ -124,6 +124,10 @@ public class SkinUtil {
                return sdbPath;
        }
 
+       public static String getSdkVersionFilePath() {
+               return ".." + File.separator + "etc" + File.separator + "version";
+       }
+
        public static List<KeyMapType> getHWKeyMapList(short rotationId) {
                RotationType rotation = SkinRotation.getRotation(rotationId);
                if (rotation == null) {
index 4dacfe7..c795033 100644 (file)
@@ -49,7 +49,6 @@
 
 MULTI_DEBUG_CHANNEL(qemu, skin_client);
 
-
 #define SKIN_SERVER_READY_TIME 3 // second
 #define SKIN_SERVER_SLEEP_TIME 10 // milli second
 
@@ -64,6 +63,10 @@ extern char tizen_target_path[];
 static int skin_argc;
 static char** skin_argv;
 
+#ifdef CONFIG_WIN32
+static char* JAVA_EXEFILE_PATH = NULL;
+#endif
+
 static void* run_skin_client(void* arg)
 {
     char cmd[JAVA_MAX_COMMAND_LENGTH] = { 0, };
@@ -90,7 +93,7 @@ static void* run_skin_client(void* arg)
     char buf_tizen_base_port[16];
     sprintf(buf_skin_server_port, "%d", skin_server_port);
     sprintf(buf_uid, "%d", uid);
-    sprintf(buf_tizen_base_port, "%d", tizen_base_port);
+    sprintf(buf_tizen_base_port, "%d", get_emul_vm_base_port());
 
 #ifdef CONFIG_WIN32
     // find java path in 64bit windows
@@ -114,11 +117,12 @@ static void* run_skin_client(void* arg)
     char* bin_dir = get_bin_path();
 #endif
     INFO("bin directory : %s\n", bin_dir);
+
     int maxtouchpoint = get_emul_max_touch_point();
     int len_maxtouchpoint;
-    if(maxtouchpoint > 9) {
+    if (maxtouchpoint > 9) {
         len_maxtouchpoint = 2;
-    }else {
+    } else {
         len_maxtouchpoint = 1;
     }
 
@@ -146,16 +150,16 @@ static void* run_skin_client(void* arg)
         OPT_SVR_PORT, skin_server_port,
         OPT_UID, uid,
         OPT_VM_PATH, vm_path,
-        OPT_NET_BASE_PORT, tizen_base_port,
+        OPT_NET_BASE_PORT, get_emul_vm_base_port(),
         OPT_MAX_TOUCHPOINT, maxtouchpoint,
-        argv );
+        argv);
 
     INFO("command for swt : %s\n", cmd);
 
 #ifdef CONFIG_WIN32
     // for 64bit windows
     free(JAVA_EXEFILE_PATH);
-    JAVA_EXEFILE_PATH=0;
+    JAVA_EXEFILE_PATH = NULL;
 
     //WinExec( cmd, SW_SHOW );
     {
@@ -257,10 +261,11 @@ int start_skin_client(int argc, char* argv[])
         } else {
             count++;
             INFO("sleep for ready. count:%d\n", count);
+
 #ifdef CONFIG_WIN32
-        Sleep(SKIN_SERVER_SLEEP_TIME);
+            Sleep(SKIN_SERVER_SLEEP_TIME);
 #else
-        usleep(1000 * SKIN_SERVER_SLEEP_TIME);
+            usleep(1000 * SKIN_SERVER_SLEEP_TIME);
 #endif
         }
 
index 9c3707d..4c42cc6 100644 (file)
@@ -49,7 +49,6 @@
 #define  MY_KEY_WOW64_64KEY 0x0100
 int is_wow64(void);
 int get_java_path(char**);
-static char* JAVA_EXEFILE_PATH = 0;
 #else
 #define JAVA_EXEFILE_PATH "java"
 #endif
index b722dc9..37c7520 100644 (file)
@@ -88,6 +88,10 @@ enum JAVA_KEYCODE {
 #define KEY_MAX 0777
 
 #define KEY_F0 0410
+
+#ifdef KEY_F
+#undef KEY_F
+#endif
 #define KEY_F(n) (KEY_F0 + (n))
 
 #define KEY_DOWN 0402
index ce4cf99..b6ade33 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * operation for emulator skin
  *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Contact:
  * GiWoong Kim <giwoong.kim@samsung.com>
@@ -36,6 +36,7 @@
 #include "maruskin_operation.h"
 #include "hw/maru_brightness.h"
 #include "maru_display.h"
+#include "emulator.h"
 #include "debug_ch.h"
 #include "sdb.h"
 #include "nbd.h"
 #include "target-i386/hax-i386.h"
 #endif
 
+#if defined(CONFIG_USE_SHM) && defined(TARGET_I386)
+#include <sys/shm.h>
+int g_shmid;
+#endif
+
 MULTI_DEBUG_CHANNEL(qemu, skin_operation);
 
-#define RESUME_KEY_SEND_INTERVAL 500 // milli-seconds
-#define CLOSE_POWER_KEY_INTERVAL 1200 // milli-seconds
-#define DATA_DELIMITER "#" // in detail info data
-#define TIMEOUT_FOR_SHUTDOWN 10 // seconds
+
+#define RESUME_KEY_SEND_INTERVAL 500 /* milli-seconds */
+#define CLOSE_POWER_KEY_INTERVAL 1200 /* milli-seconds */
+#define DATA_DELIMITER "#" /* in detail info data */
+#define TIMEOUT_FOR_SHUTDOWN 10 /* seconds */
 
 static int requested_shutdown_qemu_gracefully = 0;
 
@@ -71,10 +78,16 @@ static int pressing_origin_x = -1, pressing_origin_y = -1;
 extern pthread_mutex_t mutex_screenshot;
 extern pthread_cond_t cond_screenshot;
 
+extern int tizen_base_port;
+
 static void* run_timed_shutdown_thread(void* args);
-static void send_to_emuld(const char* request_type, int request_size, const char* send_buf, int buf_size);
+static void send_to_emuld(const char* request_type,
+    int request_size, const char* send_buf, int buf_size);
+
 
-void start_display(uint64 handle_id, int lcd_size_width, int lcd_size_height, double scale_factor, short rotation_type)
+void start_display(uint64 handle_id,
+    int lcd_size_width, int lcd_size_height,
+    double scale_factor, short rotation_type)
 {
     INFO("start_display handle_id:%ld, lcd size:%dx%d, scale_factor:%f, rotation_type:%d\n",
         (long)handle_id, lcd_size_width, lcd_size_height, scale_factor, rotation_type);
@@ -273,7 +286,7 @@ void do_hardkey_event(int event_type, int keycode)
         }
     }
 
-    mloop_evcmd_hwkey(event_type, keycode);
+    maru_hwkey_event(event_type, keycode);
 }
 
 void do_scale_event(double scale_factor)
@@ -348,14 +361,21 @@ QemuSurfaceInfo* get_screenshot_info(void)
     info->pixel_data = (unsigned char*) g_malloc0( length );
     if ( !info->pixel_data ) {
         g_free( info );
-        ERR( "Fail to malloc for pixel data.\n");
+        ERR("Fail to malloc for pixel data.\n");
         return NULL;
     }
 
+    /* If the LCD is turned off, return empty buffer.
+       Because the empty buffer is seen as a black. */
+    if (brightness_off) {
+        info->pixel_data_length = length;
+        return info;
+    }
+
     pthread_mutex_lock(&mutex_screenshot);
     MaruScreenshot* maru_screenshot = get_maru_screenshot();
-    if ( !maru_screenshot || maru_screenshot->isReady != 1) {
-        ERR( "maru screenshot is NULL or not ready.\n" );
+    if (!maru_screenshot || maru_screenshot->isReady != 1) {
+        ERR("maru screenshot is NULL or not ready.\n");
         memset(info->pixel_data, 0x00, length);
     } else {
         maru_screenshot->pixel_data = info->pixel_data;
@@ -419,7 +439,7 @@ DetailInfo* get_detail_info(int qemu_argc, char** qemu_argv)
 
     /* collect log path information */
 #define LOGPATH_TEXT "log_path="
-    char* log_path = get_log_path();
+    const char* log_path = get_log_path();
     int log_path_len = strlen(LOGPATH_TEXT) + strlen(log_path) + delimiter_len;
     total_len += (log_path_len + 1);
 
@@ -473,6 +493,7 @@ void free_detail_info(DetailInfo* detail_info)
 void do_open_shell(void)
 {
     INFO("open shell\n");
+
     /* do nothing */
 }
 
@@ -518,48 +539,60 @@ void request_close(void)
 
 }
 
-void shutdown_qemu_gracefully( void ) {
-
+void shutdown_qemu_gracefully(void)
+{
     requested_shutdown_qemu_gracefully = 1;
 
     pthread_t thread_id;
-    if( 0 > pthread_create( &thread_id, NULL, run_timed_shutdown_thread, NULL ) ) {
-        ERR( "!!! Fail to create run_timed_shutdown_thread. shutdown qemu right now !!!\n"  );
+    if (0 > pthread_create(
+        &thread_id, NULL, run_timed_shutdown_thread, NULL)) {
+
+        ERR("!!! Fail to create run_timed_shutdown_thread. shutdown qemu right now !!!\n");
         qemu_system_shutdown_request();
     }
 
 }
 
-int is_requested_shutdown_qemu_gracefully( void ) {
+int is_requested_shutdown_qemu_gracefully(void)
+{
     return requested_shutdown_qemu_gracefully;
 }
 
-static void* run_timed_shutdown_thread( void* args ) {
-
-    send_to_emuld( "system\n\n\n\n", 10, "shutdown", 8 );
+static void* run_timed_shutdown_thread(void* args)
+{
+    send_to_emuld("system\n\n\n\n", 10, "shutdown", 8);
 
-    int sleep_interval_time = 1000; // milli-seconds
+    int sleep_interval_time = 1000; /* milli-seconds */
 
     int i;
-    for ( i = 0; i < TIMEOUT_FOR_SHUTDOWN; i++ ) {
+    for (i = 0; i < TIMEOUT_FOR_SHUTDOWN; i++) {
 #ifdef CONFIG_WIN32
-        Sleep( sleep_interval_time );
+        Sleep(sleep_interval_time);
 #else
-        usleep( sleep_interval_time * 1000 );
+        usleep(sleep_interval_time * 1000);
 #endif
-        // do not use logger to help user see log in console
-        fprintf( stdout, "Wait for shutdown qemu...%d\n", ( i + 1 ) );
+        /* do not use logger to help user see log in console */
+        fprintf(stdout, "Wait for shutdown qemu...%d\n", (i + 1));
+    }
+
+    INFO("Shutdown qemu !!!\n");
+
+#if defined(CONFIG_USE_SHM) && defined(TARGET_I386)
+    if (shmctl(g_shmid, IPC_RMID, 0) == -1) {
+        ERR("shmctl failed\n");
+        perror("maruskin_operation.c:g_shmid: ");
     }
+#endif
 
-    INFO( "Shutdown qemu !!!\n" );
     qemu_system_shutdown_request();
 
     return NULL;
 
 }
 
-static void send_to_emuld( const char* request_type, int request_size, const char* send_buf, int buf_size ) {
-
+static void send_to_emuld(const char* request_type,
+    int request_size, const char* send_buf, int buf_size)
+{
     int s = tcp_socket_outgoing( "127.0.0.1", (uint16_t) ( tizen_base_port + SDB_TCP_EMULD_INDEX ) );
 
     if ( s < 0 ) {
@@ -568,9 +601,15 @@ static void send_to_emuld( const char* request_type, int request_size, const cha
         return;
     }
 
-    socket_send( s, (char*)request_type, request_size );
-    socket_send( s, &buf_size, 4 );
-    socket_send( s, (char*)send_buf, buf_size );
+    if(send( s, (char*)request_type, request_size, 0 ) < 0) {
+        ERR("failed to send to emuld\n");
+    }
+    if(send( s, &buf_size, 4, 0 ) < 0) {
+        ERR("failed to send to emuld\n");
+    }
+    if(send( s, (char*)send_buf, buf_size, 0 ) < 0) {
+        ERR("failed to send to emuld\n");
+    }
 
     INFO( "send to emuld [req_type:%s, send_data:%s, send_size:%d] 127.0.0.1:%d/tcp \n",
         request_type, send_buf, buf_size, tizen_base_port + SDB_TCP_EMULD_INDEX );
index 66d1ce2..17458a8 100644 (file)
@@ -123,13 +123,11 @@ enum {
     SEND_DETAIL_INFO = 3,
     SEND_RAMDUMP_COMPLETE = 4,
     SEND_BOOTING_PROGRESS = 5,
+    SEND_BRIGHTNESS_VALUE = 6,
     SEND_SENSOR_DAEMON_START = 800,
     SEND_SHUTDOWN = 999,
 };
 
-pthread_mutex_t mutex_screenshot = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t cond_screenshot = PTHREAD_COND_INITIALIZER;
-
 static int seq_req_id = 0;
 
 static uint16_t svr_port = 0;
@@ -145,7 +143,11 @@ static int is_started_heartbeat = 0;
 static int stop_heartbeat = 0;
 static int recv_heartbeat_count = 0;
 static pthread_t thread_id_heartbeat;
+
+static pthread_mutex_t mutex_send_data = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t mutex_recv_heartbeat_count = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t mutex_screenshot = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t cond_screenshot = PTHREAD_COND_INITIALIZER;
 
 static int skin_argc = 0;
 static char** skin_argv = NULL;
@@ -267,6 +269,8 @@ void shutdown_skin_server(void)
         }
     }
 
+    pthread_mutex_destroy(&mutex_send_data);
+    pthread_mutex_destroy(&mutex_recv_heartbeat_count);
 }
 
 void notify_sensor_daemon_start(void)
@@ -336,6 +340,27 @@ void notify_booting_progress(int progress_value)
     }
 }
 
+void notify_brightness(bool on)
+{
+    char brightness_data[2] = { 0, };
+    int brightness_value = 1;
+
+    if (on == FALSE) {
+        brightness_value = 0;
+    }
+
+    snprintf(brightness_data, 2, "%d", brightness_value);
+    TRACE("brightness value = %s\n", brightness_data);
+
+    if (client_sock) {
+        if (0 > send_skin_data(client_sock,
+            SEND_BRIGHTNESS_VALUE, (unsigned char *)brightness_data, 2, 0)) {
+
+            ERR("fail to send SEND_BRIGHTNESS_VALUE to skin.\n");
+        }
+    }
+}
+
 int is_ready_skin_server(void)
 {
     return ready_server;
@@ -1094,8 +1119,13 @@ static int send_skin_header_only(int sockfd, short send_cmd, int print_log)
 
     make_header(sockfd, send_cmd, 0, headerbuf, print_log);
 
+    /* send */
+    pthread_mutex_lock(&mutex_send_data);
+
     int send_count = send(sockfd, headerbuf, SEND_HEADER_SIZE, 0);
 
+    pthread_mutex_unlock(&mutex_send_data);
+
     return send_count;
 }
 
@@ -1105,21 +1135,28 @@ static int send_skin_data(int sockfd,
 
     char headerbuf[SEND_HEADER_SIZE] = { 0, };
 
+    if (data == NULL) {
+        ERR("send data is NULL.\n");
+        return -1;
+    }
+
     make_header(sockfd, send_cmd, length, headerbuf, 1);
 
-    int header_cnt = send(sockfd, headerbuf, SEND_HEADER_SIZE, 0);
+    /* send */
+    pthread_mutex_lock(&mutex_send_data);
 
+    int header_cnt = send(sockfd, headerbuf, SEND_HEADER_SIZE, 0);
     if (0 > header_cnt) {
         ERR("send header for data is NULL.\n");
-        return header_cnt;
-    }
+        pthread_mutex_unlock(&mutex_send_data);
 
-    if (!data) {
-        ERR("send data is NULL.\n");
-        return -1;
+        return header_cnt;
     }
 
     int send_cnt = send_n(sockfd, data, length, big_data);
+
+    pthread_mutex_unlock(&mutex_send_data);
+
     TRACE("send_n result:%d\n", send_cnt);
 
     return send_cnt;
index ee5e13a..5920797 100644 (file)
 #ifndef MARUSKIN_SERVER_H_
 #define MARUSKIN_SERVER_H_
 
+#include <stdbool.h>
+
 int start_skin_server(int argc, char** argv, int qemu_argc, char** qemu_argv);
 void shutdown_skin_server(void);
 
 void notify_sensor_daemon_start(void);
 void notify_ramdump_completed(void);
 void notify_booting_progress(int progress_value);
+void notify_brightness(bool on);
+
 int is_ready_skin_server(void);
 int get_skin_server_port(void);
 
diff --git a/vl.c b/vl.c
old mode 100644 (file)
new mode 100755 (executable)
index 4dce5cc..ea8395f
--- a/vl.c
+++ b/vl.c
@@ -181,14 +181,12 @@ int qemu_main(int argc, char **argv, char **envp);
 #include "ui/qemu-spice.h"
 
 #ifdef CONFIG_MARU
-#include "tizen/src/emulator.h"
 #include "tizen/src/maru_common.h"
-#include "tizen/src/maru_display.h"
-#include "tizen/src/option.h"
-#include "tizen/src/sdb.h"
+#include "tizen/src/emulator.h"
+#include "tizen/src/maru_err_table.h"
 #include "tizen/src/emul_state.h"
+#include "tizen/src/maru_display.h"
 #include "tizen/src/skin/maruskin_operation.h"
-#include "tizen/src/maru_err_table.h"
 #endif
 
 //#define DEBUG_NET
@@ -199,8 +197,10 @@ int qemu_main(int argc, char **argv, char **envp);
 #define MAX_VIRTIO_CONSOLES 1
 
 #ifdef CONFIG_MARU
-#define MARUCAM_DEV_NAME "maru_camera_pci"
 int skin_disabled = 0;
+//virtio-gl
+extern int enable_gl;
+extern int enable_yagl;
 #endif
 
 static const char *data_dir;
@@ -261,20 +261,6 @@ uint8_t *boot_splash_filedata;
 int boot_splash_filedata_size;
 uint8_t qemu_extra_params_fw[2];
 
-//virtio-gl
-#define VIRTIOGL_DEV_NAME "virtio-gl-pci"
-#if defined(CONFIG_MARU)
-extern int gl_acceleration_capability_check(void);
-int enable_gl = 0;
-int capability_check_gl = 0;
-#endif
-#if defined(CONFIG_MARU)
-#define WEBCAM_INFO_IGNORE 0x00
-#define WEBCAM_INFO_WRITE 0x04
-extern int marucam_device_check(int log_flag);
-int is_webcam_enabled = 0;
-#endif
-
 
 typedef struct FWBootEntry FWBootEntry;
 
@@ -1978,24 +1964,10 @@ static int device_init_func(QemuOpts *opts, void *opaque)
 {
     DeviceState *dev;
 
-#ifdef CONFIG_GL_BACKEND
-#if defined(CONFIG_MARU)
-       // virtio-gl pci device
-       if (!enable_gl) {
-               // ignore virtio-gl-pci device, even if users set it in option.
-               const char *driver = qemu_opt_get(opts, "driver");
-               if (driver && (strcmp (driver, VIRTIOGL_DEV_NAME) == 0)) {
-                       return 0;
-               }
-       }
-#endif
-#endif
-#if defined(CONFIG_MARU)
-    if (!is_webcam_enabled) {
-        const char *driver = qemu_opt_get(opts, "driver");
-        if (driver && (strcmp (driver, MARUCAM_DEV_NAME) == 0)) {
-            return 0;
-        }
+#ifdef CONFIG_MARU
+    if(maru_device_check(opts) == -1) {
+        return 0;
+
     }
 #endif
        
@@ -2436,34 +2408,13 @@ static void free_and_trace(gpointer mem)
     free(mem);
 }
 
-// virtio-gl pci device lookup
-typedef struct {
-    const char *device_name;
-    int found;
-} device_opt_finding_t;
-
-static int find_device_opt (QemuOpts *opts, void *opaque)
-{
-    device_opt_finding_t *devp = (device_opt_finding_t *) opaque;
-    if (devp->found == 1) {
-        return 0;
-    }
-
-    const char *str = qemu_opt_get (opts, "driver");
-    if (strcmp (str, devp->device_name) == 0) {
-        devp->found = 1;
-    }
-    return 0;
-}
-
-int use_qemu_display = 0; //0:use tizen qemu sdl, 1:use original qemu sdl
-
 int qemu_init_main_loop(void)
 {
     return main_loop_init();
 }
 
 #ifdef CONFIG_MARU
+int use_qemu_display = 0; //0:use tizen qemu sdl, 1:use original qemu sdl
 // W/A for preserve larger continuous heap for RAM.
 void *preallocated_ptr = 0;
 #endif
@@ -2475,7 +2426,6 @@ int main(int argc, char **argv, char **envp)
     const char *icount_option = NULL;
     const char *initrd_filename;
     const char *kernel_filename, *kernel_cmdline;
-    char* tmp_cmdline = NULL;
     char boot_devices[33] = "cad"; /* default to HD->floppy->CD-ROM */
     DisplayState *ds;
     DisplayChangeListener *dcl;
@@ -2505,13 +2455,6 @@ int main(int argc, char **argv, char **envp)
     const char *trace_events = NULL;
     const char *trace_file = NULL;
 
-#ifdef CONFIG_MARU
-    #define MIDBUF  128
-    char http_proxy[MIDBUF] ={0},https_proxy[MIDBUF] = {0,},
-       ftp_proxy[MIDBUF] = {0,}, socks_proxy[MIDBUF] = {0,},   
-     dns1[MIDBUF] = {0}, dns2[MIDBUF] = {0};
-#endif
-
     atexit(qemu_run_exit_notifiers);
     error_set_progname(argv[0]);
 
@@ -2744,28 +2687,7 @@ int main(int argc, char **argv, char **envp)
                 qemu_opts_set(qemu_find_opts("machine"), 0, "initrd", optarg);
                 break;
             case QEMU_OPTION_append:
-#ifdef CONFIG_MARU
-                gethostproxy(http_proxy, https_proxy, ftp_proxy, socks_proxy);
-                gethostDNS(dns1, dns2);
-                
-                check_shdmem();
-                socket_init();
-                tizen_base_port = get_sdb_base_port();
-                make_shdmem();
-
-                sdb_setup();
-
-                tmp_cmdline = g_strdup_printf("%s sdb_port=%d,"
-                       " http_proxy=%s https_proxy=%s ftp_proxy=%s socks_proxy=%s" 
-                       " dns1=%s dns2=%s", optarg, tizen_base_port, 
-                       http_proxy, https_proxy, ftp_proxy, socks_proxy,
-                       dns1, dns2);
-                qemu_opts_set(qemu_find_opts("machine"), 0, "append",
-                        tmp_cmdline);
-                fprintf(stdout, "kernel command : %s\n", tmp_cmdline);
-#else
                 qemu_opts_set(qemu_find_opts("machine"), 0, "append", optarg);
-#endif
                 break;
             case QEMU_OPTION_dtb:
                 qemu_opts_set(qemu_find_opts("machine"), 0, "dtb", optarg);
@@ -3210,10 +3132,8 @@ int main(int argc, char **argv, char **envp)
                 qemu_opts_parse(olist, "accel=kvm", 0);
                 break;
            case QEMU_OPTION_enable_gl:
-#ifdef CONFIG_GL_BACKEND
-#if defined(CONFIG_MARU)
+#if defined(CONFIG_MARU) && defined(CONFIG_GL_BACKEND)
                 enable_gl = 1;
-#endif
 #else
                 fprintf(stderr, "Virtio GL support is disabled, ignoring -enable-gl\n");
 #endif
@@ -3512,36 +3432,6 @@ int main(int argc, char **argv, char **envp)
         exit(0);
     }
 
-#ifdef CONFIG_GL_BACKEND
-#if defined(CONFIG_MARU)
-    if (enable_gl) {
-        capability_check_gl = gl_acceleration_capability_check();
-
-        if (capability_check_gl != 0) {
-            enable_gl = 0;
-            fprintf (stderr, "Warn: GL acceleration was disabled due to the fail of GL check!\n");
-        }
-        
-        if (enable_gl) {
-            device_opt_finding_t devp = {VIRTIOGL_DEV_NAME, 0};
-            qemu_opts_foreach(qemu_find_opts("device"), find_device_opt, &devp, 0);
-            if (devp.found == 0) {
-                if (!qemu_opts_parse(qemu_find_opts("device"), VIRTIOGL_DEV_NAME, 1)) {
-                    exit(1);
-                }
-            }
-        }
-    }
-
-       // To check host gl driver capability and notify to guest.
-       gchar *tmp = tmp_cmdline;
-       tmp_cmdline = g_strdup_printf("%s gles=%d", tmp, enable_gl);
-       qemu_opts_set(qemu_find_opts("machine"), 0, "append", tmp_cmdline);
-       fprintf(stdout, "kernel command : %s\n", tmp_cmdline);
-       g_free(tmp);
-
-#endif
-#endif
 
     /* Open the logfile at this point, if necessary. We can't open the logfile
      * when encountering either of the logging options (-d or -D) because the
@@ -3694,30 +3584,6 @@ int main(int argc, char **argv, char **envp)
         kernel_cmdline = "";
     }
 
-#if defined(CONFIG_MARU)
-    is_webcam_enabled = marucam_device_check(WEBCAM_INFO_WRITE);
-    if (!is_webcam_enabled) {
-        fprintf (stderr, "[Webcam] <WARNING> Webcam support was disabled "
-                         "due to the fail of webcam capability check!\n");
-    }
-
-    gchar const *tmp_cam_kcmd = kernel_cmdline;
-    kernel_cmdline = g_strdup_printf("%s enable_cam=%d", tmp_cam_kcmd, is_webcam_enabled);
-//    g_free(tmp_cam_kcmd);
-
-    if (is_webcam_enabled) {
-        device_opt_finding_t devp = {MARUCAM_DEV_NAME, 0};
-        qemu_opts_foreach(qemu_find_opts("device"), find_device_opt, &devp, 0);
-        if (devp.found == 0) {
-            if (!qemu_opts_parse(qemu_find_opts("device"), MARUCAM_DEV_NAME, 1)) {
-                fprintf(stderr, "Failed to initialize the marucam device.\n");
-                exit(1);
-            }
-        }
-        fprintf(stdout, "[Webcam] Webcam support was enabled.\n");
-    }
-#endif
-
     linux_boot = (kernel_filename != NULL);
 
     if (!linux_boot && *kernel_cmdline != '\0') {
@@ -3865,12 +3731,14 @@ int main(int argc, char **argv, char **envp)
 
     qdev_machine_init();
 
-    machine->init(ram_size, boot_devices,
-                  kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
 #ifdef CONFIG_MARU
-    g_free((gchar *)tmp_cmdline);
+    // return variable points different address from input variable.
+    kernel_cmdline = prepare_maru_devices(kernel_cmdline);
 #endif
 
+    machine->init(ram_size, boot_devices,
+                  kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
+
     cpu_synchronize_all_post_init();
 
     set_numa_modes();