stap:
endif
-all: $(PROGS) stap
+all: $(PROGS) stap check-gl
# Dummy command so that make thinks it has done something
@true
$(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)$@")
/* 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
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[] = {
.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)
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
}
#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
-* 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
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
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
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
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
-Version: 2.0.0
+Version: 1.5.22
Maintainer: Yeong-Kyoon Lee<yeongkyoon.lee@samsung.com>
Source: emulator
--- /dev/null
+#!/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
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
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
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 \
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 \
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
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 \
#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
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
--- /dev/null
+Andreas Schiffler <aschiffler@ferzkopp.net>
--- /dev/null
+(C) A. Schiffler, ZLIB - see file LICENSE
--- /dev/null
+/*
+
+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
--- /dev/null
+/*!\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
--- /dev/null
+/*
+
+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);
+}
--- /dev/null
+/*
+
+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 */
--- /dev/null
+#include "hw/gloffscreen_test.h"
+#include "debug_ch.h"
+
+int main (int argc, char** argv)
+{
+ return gl_acceleration_capability_check();
+}
#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;
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");
}
}
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);
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");
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);
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))
(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 );
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)
{
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)
{
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;
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;
int get_emul_num_lock_state(void)
{
- return _emul_state.qemu_num_lock;
+ return _emul_state.qemu_num_lock;
}
+
/* 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,
};
int lcd_size_h;
int sdl_bpp;
int max_touch_point;
- //TODO:
+ int vm_base_port;
+ /* add here */
} EmulatorConfigInfo;
typedef struct EmulatorConfigState {
MultiTouchState qemu_mts;
int qemu_caps_lock;
int qemu_num_lock;
- //TODO:
+ /* add here */
} EmulatorConfigState;
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);
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);
-/*
+/*
* 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;
+}
#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);
#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;
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)
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[])
{
}
}
-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);
} 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");
}
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;
}
-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;
}
-static void system_info(void)
+static void print_system_info(void)
{
#define DIV 1024
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);
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)
{
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");
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. */
/**
* @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__ */
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),
/* 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);
--- /dev/null
+/*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
+
* THE SOFTWARE.
*/
-#include "gloffscreen.h"
+#include "gloffscreen_test.h"
#include <stdlib.h>
#include <stdio.h>
--- /dev/null
+/*
+ * 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__ */
"glXGetVisualFromFBConfig\0"
"glXIsDirect\0"
"glXCreatePixmap\0"
+"glXDestroyPixmap\0"
+"glXCreatePbuffer\n"
+"glXDestroyPbuffer\n"
"\0"
};
}
/* 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;
}
/* 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);
/*
* 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
*
* 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 "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);
/* 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)
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);
.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);
"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;
k->no_hotplug = 1;
k->init = brightness_initfn;
+ k->exit = brightness_exitfn;
}
static TypeInfo brightness_info = {
/*
* 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
*
* 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
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_ */
-/*\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_ */
-/*\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)
/*
+ * 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_ */
/*
+ * 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
*
*/
/*
- * 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
*
* 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
usleep(10000);
}
}
-
+
if (mcd->driver != nil) {
[mcd->driver stopCapture];
}
-/*\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(¶m->stack[3], "YUYV", 32);\r
- break;\r
- case V4L2_PIX_FMT_YUV420:\r
- memcpy(¶m->stack[3], "YU12", 32);\r
- break;\r
- case V4L2_PIX_FMT_YVU420:\r
- memcpy(¶m->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(¶m->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(¶m->stack[3], "YUYV", 32);
+ break;
+ case V4L2_PIX_FMT_YUV420:
+ memcpy(¶m->stack[3], "YU12", 32);
+ break;
+ case V4L2_PIX_FMT_YVU420:
+ memcpy(¶m->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(¶m->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");
+}
-/*\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_ */
-/*\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(¶m->stack[3], "YUYV", 32);\r
- break;\r
- case V4L2_PIX_FMT_YUV420:\r
- memcpy(¶m->stack[3], "YU12", 32);\r
- break;\r
- case V4L2_PIX_FMT_YVU420:\r
- memcpy(¶m->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(¶m->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(¶m->stack[3], "YUYV", 32);
+ break;
+ case V4L2_PIX_FMT_YUV420:
+ memcpy(¶m->stack[3], "YU12", 32);
+ break;
+ case V4L2_PIX_FMT_YVU420:
+ memcpy(¶m->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(¶m->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++;
+ }
+}
/*
* 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>
#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 */
/*
#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_ */
-/*
+/*
* 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_t* overlay_ptr;
+uint8_t *overlay_ptr;
uint8_t overlay0_power;
uint16_t overlay0_left;
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:
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:
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) */
/*
* 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
*
* 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 "qemu-common.h"
-extern uint8_t* overlay_ptr;
+extern uint8_t *overlay_ptr;
extern uint8_t overlay0_power;
extern uint16_t overlay0_left;
extern uint16_t overlay0_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_ */
* 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
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: ");
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: ");
}
--- /dev/null
+/*
+ * 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);
+}
+
--- /dev/null
+/*
+ * 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_ */
*
* 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;
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");
}
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);
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,
return 0;
}
+static void virtio_keyboard_bh(void *opaque)
+{
+ virtio_keyboard_notify(opaque);
+}
+
VirtIODevice *virtio_keyboard_init(DeviceState *dev)
{
VirtIOKeyboard *vkbd;
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);
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);
*
* 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>
*
VirtIOKbdQueue kbdqueue;
QemuMutex event_mutex;
+ QEMUBH *bh;
} VirtIOKeyboard;
VirtIODevice *virtio_keyboard_init(DeviceState *dev);
/*
* 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>
#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);
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;
}
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);
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);
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");
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(
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);
}
/*
- * 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>
VirtQueue *vq;
bool waitBuf;
+ QEMUBH *bh;
DeviceState *qdev;
QEMUPutMouseEntry *eh_entry;
} TouchscreenState;
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];
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*));
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)
}
}
+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)
{
}
}
- if ( i >= MAX_PIXMAP_TEXTURE )
- return 0;
+ return 0;
}
static ClientGLXDrawable find_pixmap_texture(GLState *state,
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;
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;
}
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:
}
}
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:
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);
}
}
{ 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[] =
*/
/**
- * @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;
*/
-#ifndef MARU_DISPLAY_H_
-#define MARU_DISPLAY_H_
+#ifndef __MARU_DISPLAY_H__
+#define __MARU_DISPLAY_H__
#include "console.h"
DisplaySurface* get_qemu_display_surface(void);
MaruScreenshot* get_maru_screenshot(void);
-#endif /* MARU_DISPLAY_H_ */
+#endif /* __MARU_DISPLAY_H__ */
#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"
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
pthread_mutex_unlock(&sdl_mutex);
vga_hw_invalidate();
+ sdl_skip_update = 0;
break;
}
}
}
+ /* 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
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);
}
#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;
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
}
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);
}
#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"
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");
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);
-/*
- * 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_
-/*
- * 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"
+++ /dev/null
-/*
- * 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;
-}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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';
+}
--- /dev/null
+/*
+ * 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__
+
*/\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
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
\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
}\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
/* 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
#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);
<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" />
/**
+ * 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;
}
}
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);
}
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
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;
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;
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;
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)) {
}
}
}
+
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;
}
}
}
@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");
/**
* 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>
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;
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);
private volatile boolean stopRequest;
private Runnable runnable;
+ private int intervalWait;
public PollFBThread(int lcdWidth, int lcdHeight) {
this.display = Display.getDefault();
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;
imageData.setPixels(0, i, lcdWidth, array, i * lcdWidth);
}
- Image temp = framebuffer;
+ temp = framebuffer;
framebuffer = new Image(display, imageData);
temp.dispose();
public void stopRequest() {
stopRequest = true;
+
+ synchronized(pollThread) {
+ pollThread.notify();
+ }
}
}
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);
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");
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;
}
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
0, 0, x, y);
//back to old transform
e.gc.setTransform(oldtransform);
-
+
transform.dispose();
finger.drawImage(e, currentState.getCurrentAngle());
}
}
@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");
/**
* 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>
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;
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;
}
+ 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();
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;
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;
}
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();
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;
}
return new SkinReopenPolicy(reopenSkin, isAboutToReopen);
-
}
protected void skinFinalize() {
closeKeyWindow();
}
- /* dispose the color tag */
- if (colorPairTag != null) {
- colorPairTag.dispose();
+ /* dispose the color */
+ if (colorVM != null) {
+ colorVM.dispose();
}
/* save config only for emulator close */
@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);
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;
}
for (KeyEventData data : pressedKeyEventList) {
if (data.keycode == releaseData.keycode &&
- data.stateMask == releaseData.stateMask &&
+ //data.stateMask == releaseData.stateMask &&
data.keyLocation == releaseData.keyLocation) {
pressedKeyEventList.remove(data);
}
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() {
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);
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);
public void closeKeyWindow() {
keyWindowItem.setSelection(isKeyWindow = false);
- pairTagCanvas.setVisible(false);
+ pairTag.setVisible(false);
if (keyWindow != null) {
keyWindow.getShell().close();
}
+ /* 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) {
isOpen = true;
logger.info("Open the about dialog");
- AboutDialog dialog = new AboutDialog(shell);
+ AboutDialog dialog = new AboutDialog(shell, config);
dialog.open();
isOpen = false;
}
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;
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;
}
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;
/* 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 */
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);
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);
private Timer timer;
private DataTranfer() {
+ /* do nothing */
}
- private void setData( byte[] data ) {
+ private void setData(byte[] data) {
this.receivedData = data;
isTransferState = false;
}
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;
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();
logger.log( Level.SEVERE, e.getMessage(), e );
}
+ this.bao = new ByteArrayOutputStream();
+ this.dataOutputStream = new DataOutputStream(bao);
}
public void setInitialData(long data) {
heartbeatTimer.schedule(heartbeatExecutor, 1, HEART_BEAT_INTERVAL * 1000);
}
- while ( true ) {
-
- if ( isTerminated ) {
+ while (true) {
+ if (isTerminated) {
break;
}
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;
}
break;
}
case BOOTING_PROGRESS: {
- logger.info("received BOOTING_PROGRESS from QEMU.");
+ //logger.info("received BOOTING_PROGRESS from QEMU.");
resetDataTransfer(progressDataTransfer);
receiveData(progressDataTransfer, length);
if (value == 100 | value == 0) {
/* this means progressbar will be
- dispose soon */
+ disposed soon */
if (skin.bootingProgress != null) {
skin.bootingProgress = null;
}
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;
}
}
@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);
}
}
IOUtil.closeSocket(socket);
+ try {
+ bao.close();
+ dataOutputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
synchronized (this) {
skin.shutdown();
}
--- /dev/null
+/**
+ *
+ *
+ * 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();
+ }
+
+}
}
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";
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();
}
}
--- /dev/null
+/**
+ *
+ *
+ * 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
--- /dev/null
+/**
+ * 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
--- /dev/null
+/**
+ *
+ *
+ * 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;
+ }
+}
--- /dev/null
+/**
+ *
+ *
+ * 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;
+ }
+}
--- /dev/null
+/**
+ *
+ *
+ * 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
--- /dev/null
+/**
+ *
+ *
+ * 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;
+ }
+}
--- /dev/null
+/**
+ *
+ *
+ * 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);
+ }
+}
--- /dev/null
+/**
+ *
+ *
+ * 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;
+ }
+}
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;
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) {
/* 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);
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"),
}
}
-
+
+ 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;
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);
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.
ClassLoader classLoader = this.getClass().getClassLoader();
IconName[] values = IconName.values();
- for ( IconName iconName : values ) {
+ for (IconName iconName : values) {
String icoNname = iconName.getName();
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();
+ }
+ }
}
-
}
/**
*
*
- * 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>
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;
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();
@Override
public Canvas compose(int style) {
+ shell.setBackground(backgroundColor);
+
displayCanvas = new Canvas(shell, style);
int vmIndex = config.getArgInt(ArgsConstants.NET_BASE_PORT) % 100;
shell.setLocation(x, y);
String emulatorName = SkinUtil.makeEmulatorName(config);
- shell.setText(emulatorName);
+ shell.setText("Emulator - " + emulatorName);
displayCanvas.setBackground(
shell.getDisplay().getSystemColor(SWT.COLOR_BLACK));
});
/* 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);
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();
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());
toggleButton.dispose();
}
- if (skin.pairTagCanvas != null) {
- skin.pairTagCanvas.dispose();
+ if (skin.pairTag != null) {
+ skin.pairTag.dispose();
}
if (backgroundColor != null) {
shell.setLocation(x, y);
String emulatorName = SkinUtil.makeEmulatorName(config);
- shell.setText(emulatorName);
+ shell.setText("Emulator - " + emulatorName);
lcdCanvas.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK));
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) {
MULTI_DEBUG_CHANNEL(qemu, skin_client);
-
#define SKIN_SERVER_READY_TIME 3 // second
#define SKIN_SERVER_SLEEP_TIME 10 // milli second
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, };
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
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;
}
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 );
{
} 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
}
#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
#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
/*
* 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>
#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;
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);
}
}
- mloop_evcmd_hwkey(event_type, keycode);
+ maru_hwkey_event(event_type, keycode);
}
void do_scale_event(double scale_factor)
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;
/* 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);
void do_open_shell(void)
{
INFO("open shell\n");
+
/* do nothing */
}
}
-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 ) {
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 );
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;
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;
}
}
+ pthread_mutex_destroy(&mutex_send_data);
+ pthread_mutex_destroy(&mutex_recv_heartbeat_count);
}
void notify_sensor_daemon_start(void)
}
}
+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;
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;
}
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;
#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);
#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
#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;
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;
{
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
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
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;
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]);
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);
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
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
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') {
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();