Merge pull request 'OpenVR support plus some fixes' (#45) from dsc/wowlet:openvr-qml-windows into master
Reviewed-on: https://git.wownero.com/wowlet/wowlet/pulls/45
							
								
								
									
										3
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							
							
						
						| 
						 | 
					@ -5,3 +5,6 @@
 | 
				
			||||||
	path = monero
 | 
						path = monero
 | 
				
			||||||
	url = https://git.wownero.com/wownero/wownero
 | 
						url = https://git.wownero.com/wownero/wownero
 | 
				
			||||||
	branch = wowlet
 | 
						branch = wowlet
 | 
				
			||||||
 | 
					[submodule "contrib/quirc"]
 | 
				
			||||||
 | 
						path = contrib/quirc
 | 
				
			||||||
 | 
						url = https://github.com/dlbeer/quirc.git
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,8 @@ set(VERSION "beta-1")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
option(FETCH_DEPS "Download dependencies if they are not found" ON)
 | 
					option(FETCH_DEPS "Download dependencies if they are not found" ON)
 | 
				
			||||||
option(XMRIG "Include XMRig module" ON)
 | 
					option(XMRIG "Include XMRig module" ON)
 | 
				
			||||||
 | 
					option(OPENVR "Include OpenVR support" OFF)
 | 
				
			||||||
 | 
					option(QML "Include QtQuick (QML)" OFF)
 | 
				
			||||||
option(TOR_BIN "Path to Tor binary to embed inside WOWlet" OFF)
 | 
					option(TOR_BIN "Path to Tor binary to embed inside WOWlet" OFF)
 | 
				
			||||||
option(STATIC "Link libraries statically, requires static Qt")
 | 
					option(STATIC "Link libraries statically, requires static Qt")
 | 
				
			||||||
option(USE_DEVICE_TREZOR "Trezor support compilation" OFF)
 | 
					option(USE_DEVICE_TREZOR "Trezor support compilation" OFF)
 | 
				
			||||||
| 
						 | 
					@ -24,16 +26,26 @@ include(FindCcache)
 | 
				
			||||||
include(CheckIncludeFile)
 | 
					include(CheckIncludeFile)
 | 
				
			||||||
include(CheckSymbolExists)
 | 
					include(CheckSymbolExists)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(DEBUG)
 | 
					 | 
				
			||||||
    set(CMAKE_VERBOSE_MAKEFILE ON)
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
set(WOWNERO_HEAD "f611d5c9e32bc62f1735f6571b0bdb95cc020531")
 | 
					set(WOWNERO_HEAD "f611d5c9e32bc62f1735f6571b0bdb95cc020531")
 | 
				
			||||||
set(BUILD_GUI_DEPS ON)
 | 
					set(BUILD_GUI_DEPS ON)
 | 
				
			||||||
set(ARCH "x86-64")
 | 
					set(ARCH "x86-64")
 | 
				
			||||||
set(BUILD_64 ON)
 | 
					set(BUILD_64 ON)
 | 
				
			||||||
set(INSTALL_VENDORED_LIBUNBOUND ${STATIC})
 | 
					set(INSTALL_VENDORED_LIBUNBOUND ${STATIC})
 | 
				
			||||||
set(USE_SINGLE_BUILDDIR ON)
 | 
					set(USE_SINGLE_BUILDDIR ON)
 | 
				
			||||||
 | 
					if(OPENVR)
 | 
				
			||||||
 | 
					    set(QML ON)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Are we in debug mode?
 | 
				
			||||||
 | 
					set(_CMAKE_BUILD_TYPE "")
 | 
				
			||||||
 | 
					string(TOUPPER "${CMAKE_BUILD_TYPE}" _CMAKE_BUILD_TYPE)
 | 
				
			||||||
 | 
					if("${_CMAKE_BUILD_TYPE}" STREQUAL "DEBUG")
 | 
				
			||||||
 | 
					    set(DEBUG ON)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set(CMAKE_VERBOSE_MAKEFILE ON)
 | 
				
			||||||
 | 
					    message(STATUS "OPENVR: ${OPENVR}")
 | 
				
			||||||
 | 
					    message(STATUS "QML: ${QML}")
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
check_include_file(sys/prctl.h HAVE_SYS_PRCTL_H)
 | 
					check_include_file(sys/prctl.h HAVE_SYS_PRCTL_H)
 | 
				
			||||||
check_symbol_exists(prctl "sys/prctl.h" HAVE_PRCTL)
 | 
					check_symbol_exists(prctl "sys/prctl.h" HAVE_PRCTL)
 | 
				
			||||||
| 
						 | 
					@ -87,7 +99,7 @@ if(GIT_FOUND)
 | 
				
			||||||
    if(NOT _WOWNERO_HEAD STREQUAL WOWNERO_HEAD)
 | 
					    if(NOT _WOWNERO_HEAD STREQUAL WOWNERO_HEAD)
 | 
				
			||||||
        message(FATAL_ERROR "[submodule] Monero HEAD was at ${_WOWNERO_HEAD} but should be at ${WOWNERO_HEAD}")
 | 
					        message(FATAL_ERROR "[submodule] Monero HEAD was at ${_WOWNERO_HEAD} but should be at ${WOWNERO_HEAD}")
 | 
				
			||||||
    else()
 | 
					    else()
 | 
				
			||||||
        message(STATUS "[submodule] Monero HEAD @ ${WOWNERO_HEAD}")
 | 
					        message(STATUS "[submodule] Wownero HEAD @ ${WOWNERO_HEAD}")
 | 
				
			||||||
    endif()
 | 
					    endif()
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -365,4 +377,25 @@ if(APPLE)
 | 
				
			||||||
    add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/contrib/KDMacTouchBar")
 | 
					    add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/contrib/KDMacTouchBar")
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(OPENVR)
 | 
				
			||||||
 | 
					    # Add contrib/openvr as library
 | 
				
			||||||
 | 
					    add_definitions(-DVR_API_PUBLIC)
 | 
				
			||||||
 | 
					    add_definitions(-DOPENVR_BUILD_STATIC)  # is this needed?
 | 
				
			||||||
 | 
					    add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/contrib/openvr")
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(APPLE)
 | 
				
			||||||
 | 
					    add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/contrib/KDMacTouchBar")
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(WITH_SCANNER)
 | 
				
			||||||
 | 
					    add_library(quirc STATIC
 | 
				
			||||||
 | 
					            contrib/quirc/lib/decode.c
 | 
				
			||||||
 | 
					            contrib/quirc/lib/identify.c
 | 
				
			||||||
 | 
					            contrib/quirc/lib/quirc.c
 | 
				
			||||||
 | 
					            contrib/quirc/lib/version_db.c
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					    target_include_directories(quirc PUBLIC contrib/quirc/lib)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_subdirectory(src)
 | 
					add_subdirectory(src)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,7 @@ ENV OPENSSL_ROOT_DIR=/usr/local/openssl/
 | 
				
			||||||
ENV TOR_BIN=/usr/local/tor/bin/tor.exe
 | 
					ENV TOR_BIN=/usr/local/tor/bin/tor.exe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN apt update && \
 | 
					RUN apt update && \
 | 
				
			||||||
    DEBIAN_FRONTEND=noninteractive apt install -y curl wget zip automake build-essential cmake gcc-mingw-w64 g++-mingw-w64 gettext git libtool pkg-config \
 | 
					    DEBIAN_FRONTEND=noninteractive apt install -y curl nano wget zip automake build-essential cmake gcc-mingw-w64 g++-mingw-w64 gettext git libtool pkg-config \
 | 
				
			||||||
    python && \
 | 
					    python && \
 | 
				
			||||||
    rm -rf /var/lib/apt/lists/*
 | 
					    rm -rf /var/lib/apt/lists/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,8 +27,12 @@ RUN make -j$THREADS -C /depends HOST=x86_64-w64-mingw32 NO_QT=1
 | 
				
			||||||
RUN git clone git://code.qt.io/qt/qt5.git -b ${QT_VERSION} --depth 1 && \
 | 
					RUN git clone git://code.qt.io/qt/qt5.git -b ${QT_VERSION} --depth 1 && \
 | 
				
			||||||
    cd qt5 && \
 | 
					    cd qt5 && \
 | 
				
			||||||
    git clone git://code.qt.io/qt/qtbase.git -b ${QT_VERSION} --depth 1 && \
 | 
					    git clone git://code.qt.io/qt/qtbase.git -b ${QT_VERSION} --depth 1 && \
 | 
				
			||||||
 | 
					    git clone git://code.qt.io/qt/qtdeclarative.git -b ${QT_VERSION} --depth 1 && \
 | 
				
			||||||
 | 
					    git clone git://code.qt.io/qt/qtgraphicaleffects.git -b ${QT_VERSION} --depth 1 && \
 | 
				
			||||||
    git clone git://code.qt.io/qt/qtimageformats.git -b ${QT_VERSION} --depth 1 && \
 | 
					    git clone git://code.qt.io/qt/qtimageformats.git -b ${QT_VERSION} --depth 1 && \
 | 
				
			||||||
    git clone git://code.qt.io/qt/qtmultimedia.git -b ${QT_VERSION} --depth 1 && \
 | 
					    git clone git://code.qt.io/qt/qtmultimedia.git -b ${QT_VERSION} --depth 1 && \
 | 
				
			||||||
 | 
					    git clone git://code.qt.io/qt/qtquickcontrols.git -b ${QT_VERSION} --depth 1 && \
 | 
				
			||||||
 | 
					    git clone git://code.qt.io/qt/qtquickcontrols2.git -b ${QT_VERSION} --depth 1 && \
 | 
				
			||||||
    git clone git://code.qt.io/qt/qtsvg.git -b ${QT_VERSION} --depth 1 && \
 | 
					    git clone git://code.qt.io/qt/qtsvg.git -b ${QT_VERSION} --depth 1 && \
 | 
				
			||||||
    git clone git://code.qt.io/qt/qttools.git -b ${QT_VERSION} --depth 1 && \
 | 
					    git clone git://code.qt.io/qt/qttools.git -b ${QT_VERSION} --depth 1 && \
 | 
				
			||||||
    git clone git://code.qt.io/qt/qttranslations.git -b ${QT_VERSION} --depth 1 && \
 | 
					    git clone git://code.qt.io/qt/qttranslations.git -b ${QT_VERSION} --depth 1 && \
 | 
				
			||||||
| 
						 | 
					@ -38,8 +42,8 @@ RUN git clone git://code.qt.io/qt/qt5.git -b ${QT_VERSION} --depth 1 && \
 | 
				
			||||||
    ./configure --prefix=/depends/x86_64-w64-mingw32 -xplatform win32-g++ \
 | 
					    ./configure --prefix=/depends/x86_64-w64-mingw32 -xplatform win32-g++ \
 | 
				
			||||||
    -device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- \
 | 
					    -device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- \
 | 
				
			||||||
    -I $(pwd)/qtbase/src/3rdparty/angle/include \
 | 
					    -I $(pwd)/qtbase/src/3rdparty/angle/include \
 | 
				
			||||||
    -opensource -confirm-license -release -static -static-runtime -no-opengl \
 | 
					    -opensource -confirm-license -release -static -static-runtime -opengl dynamic -no-angle \
 | 
				
			||||||
    -no-avx -openssl -I /depends/x86_64-w64-mingw32/include -L /depends/x86_64-w64-mingw32/lib \
 | 
					    -no-feature-qml-worker-script -no-avx -openssl -I /depends/x86_64-w64-mingw32/include -L /depends/x86_64-w64-mingw32/lib \
 | 
				
			||||||
    -qt-freetype -qt-harfbuzz -qt-libjpeg -qt-libpng -qt-pcre -qt-zlib \
 | 
					    -qt-freetype -qt-harfbuzz -qt-libjpeg -qt-libpng -qt-pcre -qt-zlib \
 | 
				
			||||||
    -skip gamepad -skip location -skip qt3d -skip qtactiveqt -skip qtandroidextras \
 | 
					    -skip gamepad -skip location -skip qt3d -skip qtactiveqt -skip qtandroidextras \
 | 
				
			||||||
    -skip qtcanvas3d -skip qtcharts -skip qtconnectivity -skip qtdatavis3d -skip qtdoc \
 | 
					    -skip qtcanvas3d -skip qtcharts -skip qtconnectivity -skip qtdatavis3d -skip qtdoc \
 | 
				
			||||||
| 
						 | 
					@ -47,7 +51,6 @@ RUN git clone git://code.qt.io/qt/qt5.git -b ${QT_VERSION} --depth 1 && \
 | 
				
			||||||
    -skip qtscript -skip qtscxml -skip qtsensors -skip qtserialbus -skip qtserialport \
 | 
					    -skip qtscript -skip qtscxml -skip qtsensors -skip qtserialbus -skip qtserialport \
 | 
				
			||||||
    -skip qtspeech -skip qttools -skip qtvirtualkeyboard -skip qtwayland -skip qtwebchannel \
 | 
					    -skip qtspeech -skip qttools -skip qtvirtualkeyboard -skip qtwayland -skip qtwebchannel \
 | 
				
			||||||
    -skip qtwebengine -skip qtwebview -skip qtwinextras -skip qtx11extras \
 | 
					    -skip qtwebengine -skip qtwebview -skip qtwinextras -skip qtx11extras \
 | 
				
			||||||
    -skip qtdeclarative -skip qtquickcontrols -skip qtquickcontrols2 \
 | 
					 | 
				
			||||||
    -skip serialbus -skip webengine \
 | 
					    -skip serialbus -skip webengine \
 | 
				
			||||||
    -nomake examples -nomake tests -nomake tools && \
 | 
					    -nomake examples -nomake tests -nomake tools && \
 | 
				
			||||||
    make -j$THREADS && \
 | 
					    make -j$THREADS && \
 | 
				
			||||||
| 
						 | 
					@ -94,7 +97,7 @@ RUN git clone -b v1.2.11 --depth 1 https://github.com/madler/zlib && \
 | 
				
			||||||
# libpng -> libqrencode
 | 
					# libpng -> libqrencode
 | 
				
			||||||
RUN git clone -b libpng16 --depth 1 https://github.com/glennrp/libpng.git && \
 | 
					RUN git clone -b libpng16 --depth 1 https://github.com/glennrp/libpng.git && \
 | 
				
			||||||
    cd libpng && \
 | 
					    cd libpng && \
 | 
				
			||||||
    git reset --hard dbe3e0c43e549a1602286144d94b0666549b18e6 && \
 | 
					    git reset --hard a37d4836519517bdce6cb9d956092321eca3e73b && \
 | 
				
			||||||
    CPPFLAGS="-I/depends/x86_64-w64-mingw32/include" LDFLAGS="-L/depends/x86_64-w64-mingw32/lib" \
 | 
					    CPPFLAGS="-I/depends/x86_64-w64-mingw32/include" LDFLAGS="-L/depends/x86_64-w64-mingw32/lib" \
 | 
				
			||||||
    ./configure --host=x86_64-w64-mingw32 --prefix=/depends/x86_64-w64-mingw32 && \
 | 
					    ./configure --host=x86_64-w64-mingw32 --prefix=/depends/x86_64-w64-mingw32 && \
 | 
				
			||||||
    make -j$THREADS && \
 | 
					    make -j$THREADS && \
 | 
				
			||||||
| 
						 | 
					@ -122,11 +125,11 @@ RUN wget https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.16.tar.gz && \
 | 
				
			||||||
    rm -rf $(pwd)
 | 
					    rm -rf $(pwd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# OpenSSL -> Tor
 | 
					# OpenSSL -> Tor
 | 
				
			||||||
RUN wget https://www.openssl.org/source/openssl-1.1.1i.tar.gz && \
 | 
					RUN wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz && \
 | 
				
			||||||
    echo "e8be6a35fe41d10603c3cc635e93289ed00bf34b79671a3a4de64fcee00d5242 openssl-1.1.1i.tar.gz" | sha256sum -c && \
 | 
					    echo "892a0875b9872acd04a9fde79b1f943075d5ea162415de3047c327df33fbaee5 openssl-1.1.1k.tar.gz" | sha256sum -c && \
 | 
				
			||||||
    tar -xzf openssl-1.1.1i.tar.gz && \
 | 
					    tar -xzf openssl-1.1.1k.tar.gz && \
 | 
				
			||||||
    rm openssl-1.1.1i.tar.gz && \
 | 
					    rm openssl-1.1.1k.tar.gz && \
 | 
				
			||||||
    cd openssl-1.1.1i && \
 | 
					    cd openssl-1.1.1k && \
 | 
				
			||||||
    ./Configure mingw64 no-shared no-dso --cross-compile-prefix=x86_64-w64-mingw32- --prefix=/usr/local/openssl && \
 | 
					    ./Configure mingw64 no-shared no-dso --cross-compile-prefix=x86_64-w64-mingw32- --prefix=/usr/local/openssl && \
 | 
				
			||||||
    make -j$THREADS && \
 | 
					    make -j$THREADS && \
 | 
				
			||||||
    make -j$THREADS install_sw && \
 | 
					    make -j$THREADS install_sw && \
 | 
				
			||||||
| 
						 | 
					@ -146,10 +149,9 @@ RUN wget https://github.com/libevent/libevent/releases/download/release-2.1.11-s
 | 
				
			||||||
    make -j$THREADS install && \
 | 
					    make -j$THREADS install && \
 | 
				
			||||||
    rm -rf $(pwd)
 | 
					    rm -rf $(pwd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENV TOR_VERSION=0.4.5.5-rc
 | 
					RUN git clone -b tor-0.4.5.7 --depth 1 https://git.torproject.org/tor.git && \
 | 
				
			||||||
RUN git clone -b tor-0.4.5.5-rc --depth 1 https://git.torproject.org/tor.git && \
 | 
					 | 
				
			||||||
    cd tor  && \
 | 
					    cd tor  && \
 | 
				
			||||||
    git reset --hard b36a00e9a9d3eb4b2949951afaa72e45fb7e68cd && \
 | 
					    git reset --hard 83f895c015de55201e5f226f84a866f30f5ee14b && \
 | 
				
			||||||
    ./autogen.sh && \
 | 
					    ./autogen.sh && \
 | 
				
			||||||
    ./configure --host=x86_64-w64-mingw32 \
 | 
					    ./configure --host=x86_64-w64-mingw32 \
 | 
				
			||||||
    --disable-asciidoc \
 | 
					    --disable-asciidoc \
 | 
				
			||||||
| 
						 | 
					@ -181,3 +183,4 @@ RUN git clone https://git.wownero.com/wowlet/monero-seed.git && \
 | 
				
			||||||
    make -Cbuild -j$THREADS && \
 | 
					    make -Cbuild -j$THREADS && \
 | 
				
			||||||
    make -Cbuild install && \
 | 
					    make -Cbuild install && \
 | 
				
			||||||
    rm -rf $(pwd)
 | 
					    rm -rf $(pwd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										9
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						| 
						 | 
					@ -30,6 +30,8 @@ CMAKEFLAGS = \
 | 
				
			||||||
	-DARCH=x86_64 \
 | 
						-DARCH=x86_64 \
 | 
				
			||||||
	-DBUILD_64=On \
 | 
						-DBUILD_64=On \
 | 
				
			||||||
	-DBUILD_TESTS=Off \
 | 
						-DBUILD_TESTS=Off \
 | 
				
			||||||
 | 
						-DOPENVR=Off \
 | 
				
			||||||
 | 
						-DQML=Off \
 | 
				
			||||||
	-DXMRIG=Off \
 | 
						-DXMRIG=Off \
 | 
				
			||||||
	-DTOR_BIN=Off \
 | 
						-DTOR_BIN=Off \
 | 
				
			||||||
	-DCMAKE_CXX_STANDARD=11 \
 | 
						-DCMAKE_CXX_STANDARD=11 \
 | 
				
			||||||
| 
						 | 
					@ -52,8 +54,14 @@ depends:
 | 
				
			||||||
	mkdir -p build/$(target)/release
 | 
						mkdir -p build/$(target)/release
 | 
				
			||||||
	cd build/$(target)/release && cmake -D STATIC=ON -DREPRODUCIBLE=$(or ${SOURCE_DATE_EPOCH},OFF) -DTOR_VERSION=$(or ${TOR_VERSION}, OFF) -DTOR_BIN=$(or ${TOR_BIN},OFF) -D DEV_MODE=$(or ${DEV_MODE},OFF) -D BUILD_TAG=$(tag) -D CMAKE_BUILD_TYPE=Release -D CMAKE_TOOLCHAIN_FILE=$(root)/$(target)/share/toolchain.cmake ../../.. && $(MAKE)
 | 
						cd build/$(target)/release && cmake -D STATIC=ON -DREPRODUCIBLE=$(or ${SOURCE_DATE_EPOCH},OFF) -DTOR_VERSION=$(or ${TOR_VERSION}, OFF) -DTOR_BIN=$(or ${TOR_BIN},OFF) -D DEV_MODE=$(or ${DEV_MODE},OFF) -D BUILD_TAG=$(tag) -D CMAKE_BUILD_TYPE=Release -D CMAKE_TOOLCHAIN_FILE=$(root)/$(target)/share/toolchain.cmake ../../.. && $(MAKE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					windows:
 | 
				
			||||||
 | 
						mkdir -p build/$(target)/release
 | 
				
			||||||
 | 
						cd build/$(target)/release && cmake -D STATIC=ON -DZLIB_ROOT=/usr/x86_64-w64-mingw32/ -DREPRODUCIBLE=$(or ${SOURCE_DATE_EPOCH},OFF) -DTOR_VERSION=$(or ${TOR_VERSION}, OFF) -DOPENVR=ON -DQML=ON -DWITH_SCANNER=ON -DTOR_BIN=$(or ${TOR_BIN},OFF) -D DEV_MODE=$(or ${DEV_MODE},OFF) -D BUILD_TAG=$(tag) -D CMAKE_BUILD_TYPE=Debug -D CMAKE_TOOLCHAIN_FILE=$(root)/$(target)/share/toolchain.cmake ../../.. && $(MAKE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
windows-mxe-release: CMAKEFLAGS += -DBUILD_TAG="win-x64"
 | 
					windows-mxe-release: CMAKEFLAGS += -DBUILD_TAG="win-x64"
 | 
				
			||||||
windows-mxe-release: CMAKEFLAGS += -DTOR_BIN=$(or ${TOR_BIN},OFF)
 | 
					windows-mxe-release: CMAKEFLAGS += -DTOR_BIN=$(or ${TOR_BIN},OFF)
 | 
				
			||||||
 | 
					windows-mxe-debug: CMAKEFLAGS += -DOPENVR=On
 | 
				
			||||||
windows-mxe-release: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Release
 | 
					windows-mxe-release: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Release
 | 
				
			||||||
windows-mxe-release:
 | 
					windows-mxe-release:
 | 
				
			||||||
	cmake -Bbuild $(CMAKEFLAGS)
 | 
						cmake -Bbuild $(CMAKEFLAGS)
 | 
				
			||||||
| 
						 | 
					@ -61,6 +69,7 @@ windows-mxe-release:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
windows-mxe-debug: CMAKEFLAGS += -DBUILD_TAG="win-x64"
 | 
					windows-mxe-debug: CMAKEFLAGS += -DBUILD_TAG="win-x64"
 | 
				
			||||||
windows-mxe-debug: CMAKEFLAGS += -DTOR_BIN=$(or ${TOR_BIN},OFF)
 | 
					windows-mxe-debug: CMAKEFLAGS += -DTOR_BIN=$(or ${TOR_BIN},OFF)
 | 
				
			||||||
 | 
					windows-mxe-debug: CMAKEFLAGS += -DOPENVR=On
 | 
				
			||||||
windows-mxe-debug: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Debug
 | 
					windows-mxe-debug: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Debug
 | 
				
			||||||
windows-mxe-debug:
 | 
					windows-mxe-debug:
 | 
				
			||||||
	cmake -Bbuild $(CMAKEFLAGS)
 | 
						cmake -Bbuild $(CMAKEFLAGS)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										93
									
								
								contrib/openvr/CMakeLists.txt
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,93 @@
 | 
				
			||||||
 | 
					# Set project name.
 | 
				
			||||||
 | 
					project(OpenVRSDK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Fetch the version from the headers
 | 
				
			||||||
 | 
					set(VERSION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/headers/openvr.h")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set(VERSION_MAJOR_REGEX "\tstatic const uint32_t k_nSteamVRVersionMajor = (.+);")
 | 
				
			||||||
 | 
					set(VERSION_MINOR_REGEX "\tstatic const uint32_t k_nSteamVRVersionMinor = (.+);")
 | 
				
			||||||
 | 
					set(VERSION_BUILD_REGEX "\tstatic const uint32_t k_nSteamVRVersionBuild = (.+);")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					file(STRINGS "${VERSION_FILE}" VERSION_MAJOR_STRING REGEX "${VERSION_MAJOR_REGEX}")
 | 
				
			||||||
 | 
					file(STRINGS "${VERSION_FILE}" VERSION_MINOR_STRING REGEX "${VERSION_MINOR_REGEX}")
 | 
				
			||||||
 | 
					file(STRINGS "${VERSION_FILE}" VERSION_BUILD_STRING REGEX "${VERSION_BUILD_REGEX}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string(REGEX REPLACE "${VERSION_MAJOR_REGEX}" "\\1" VERSION_MAJOR ${VERSION_MAJOR_STRING})
 | 
				
			||||||
 | 
					string(REGEX REPLACE "${VERSION_MINOR_REGEX}" "\\1" VERSION_MINOR ${VERSION_MINOR_STRING})
 | 
				
			||||||
 | 
					string(REGEX REPLACE "${VERSION_BUILD_REGEX}" "\\1" VERSION_BUILD ${VERSION_BUILD_STRING})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set(OPENVR_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_BUILD}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Setup some options.
 | 
				
			||||||
 | 
					option(BUILD_SHARED "Builds the library as shared library" OFF)
 | 
				
			||||||
 | 
					option(BUILD_FRAMEWORK "Builds the library as an apple Framework" OFF)
 | 
				
			||||||
 | 
					option(BUILD_UNIVERSAL "Builds the shared or framework as a universal (fat, 32- & 64-bit) binary" ON)
 | 
				
			||||||
 | 
					option(BUILD_OSX_I386 "Builds the shared or framework as a 32-bit binary, even on a 64-bit platform" OFF)
 | 
				
			||||||
 | 
					option(USE_LIBCXX "Uses libc++ instead of libstdc++" ON)
 | 
				
			||||||
 | 
					option(USE_CUSTOM_LIBCXX "Uses a custom libc++" OFF)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_definitions( -DVR_API_PUBLIC )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Check if 32 or 64 bit system.
 | 
				
			||||||
 | 
					set(SIZEOF_VOIDP ${CMAKE_SIZEOF_VOID_P})
 | 
				
			||||||
 | 
					if(CMAKE_SIZEOF_VOID_P EQUAL 8)
 | 
				
			||||||
 | 
					  set(PROCESSOR_ARCH "64")
 | 
				
			||||||
 | 
					else()
 | 
				
			||||||
 | 
					  set(PROCESSOR_ARCH "32")
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Get platform.
 | 
				
			||||||
 | 
					if(WIN32)
 | 
				
			||||||
 | 
					  set(PLATFORM_NAME "win")
 | 
				
			||||||
 | 
					  if(NOT BUILD_SHARED)
 | 
				
			||||||
 | 
					    add_definitions(-DOPENVR_BUILD_STATIC)
 | 
				
			||||||
 | 
					  endif()
 | 
				
			||||||
 | 
					elseif(UNIX AND NOT APPLE)
 | 
				
			||||||
 | 
					  if(CMAKE_SYSTEM_NAME MATCHES ".*Linux")
 | 
				
			||||||
 | 
					    set(PLATFORM_NAME "linux")
 | 
				
			||||||
 | 
					    add_definitions(-DLINUX -DPOSIX)
 | 
				
			||||||
 | 
					    if(PROCESSOR_ARCH MATCHES "64")
 | 
				
			||||||
 | 
					        add_definitions(-DLINUX64)
 | 
				
			||||||
 | 
					    endif()
 | 
				
			||||||
 | 
					  endif()
 | 
				
			||||||
 | 
					elseif(APPLE)
 | 
				
			||||||
 | 
					  if(CMAKE_SYSTEM_NAME MATCHES ".*Darwin.*" OR CMAKE_SYSTEM_NAME MATCHES ".*MacOS.*")
 | 
				
			||||||
 | 
					    set(PLATFORM_NAME "osx")
 | 
				
			||||||
 | 
					    add_definitions(-DOSX -DPOSIX)
 | 
				
			||||||
 | 
					    if(BUILD_UNIVERSAL)
 | 
				
			||||||
 | 
					      set(CMAKE_OSX_ARCHITECTURES "i386;x86_64")
 | 
				
			||||||
 | 
					    endif()
 | 
				
			||||||
 | 
					    if(BUILD_OSX_I386)
 | 
				
			||||||
 | 
					      set(PROCESSOR_ARCH "32")
 | 
				
			||||||
 | 
					      set(CMAKE_OSX_ARCHITECTURES "i386")
 | 
				
			||||||
 | 
					    endif()
 | 
				
			||||||
 | 
					  endif()
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Set output folder for static and shared libraries
 | 
				
			||||||
 | 
					set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin/${PLATFORM_NAME}${PROCESSOR_ARCH})
 | 
				
			||||||
 | 
					set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin/${PLATFORM_NAME}${PROCESSOR_ARCH})
 | 
				
			||||||
 | 
					set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin/${PLATFORM_NAME}${PROCESSOR_ARCH})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Enable some properties.
 | 
				
			||||||
 | 
					if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
 | 
				
			||||||
 | 
						# Enable c++11 and hide symbols which shouldn't be visible
 | 
				
			||||||
 | 
						set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC -fvisibility=hidden")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# Set custom libc++ usage here
 | 
				
			||||||
 | 
						if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND USE_LIBCXX)
 | 
				
			||||||
 | 
							if(USE_CUSTOM_LIBCXX)
 | 
				
			||||||
 | 
								if(BUILD_SHARED)
 | 
				
			||||||
 | 
									set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -stdlib=libc++")
 | 
				
			||||||
 | 
								endif()
 | 
				
			||||||
 | 
								set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc++")
 | 
				
			||||||
 | 
								include_directories( ${LIBCXX_INCLUDE} ${LIBCXX_ABI_INCLUDE})
 | 
				
			||||||
 | 
								message(STATUS "Using custom libc++")
 | 
				
			||||||
 | 
							else()
 | 
				
			||||||
 | 
								set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
 | 
				
			||||||
 | 
								message(STATUS "Using libc++")
 | 
				
			||||||
 | 
							endif()
 | 
				
			||||||
 | 
						endif()
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_subdirectory(src)
 | 
				
			||||||
							
								
								
									
										27
									
								
								contrib/openvr/LICENSE
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,27 @@
 | 
				
			||||||
 | 
					Copyright (c) 2015, Valve Corporation
 | 
				
			||||||
 | 
					All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Redistribution and use in source and binary forms, with or without modification,
 | 
				
			||||||
 | 
					are permitted provided that the following conditions are met:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Redistributions of source code must retain the above copyright notice, this
 | 
				
			||||||
 | 
					list of conditions and the following disclaimer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. Redistributions in binary form must reproduce the above copyright notice,
 | 
				
			||||||
 | 
					this list of conditions and the following disclaimer in the documentation and/or
 | 
				
			||||||
 | 
					other materials provided with the distribution.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. Neither the name of the copyright holder nor the names of its contributors
 | 
				
			||||||
 | 
					may be used to endorse or promote products derived from this software without
 | 
				
			||||||
 | 
					specific prior written permission.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 | 
				
			||||||
 | 
					ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
				
			||||||
 | 
					WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
				
			||||||
 | 
					DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 | 
				
			||||||
 | 
					ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
				
			||||||
 | 
					(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
				
			||||||
 | 
					LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 | 
				
			||||||
 | 
					ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
				
			||||||
 | 
					(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
				
			||||||
 | 
					SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
							
								
								
									
										19
									
								
								contrib/openvr/README.md
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,19 @@
 | 
				
			||||||
 | 
					### Warning
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Hard forked from commit `4c85abcb7f7f1f02adaf3812018c99fc593bc341` @ openvr**.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					At the time of writing, the above version does not compile. Had to make several changes. In addition, 
 | 
				
			||||||
 | 
					binary blobs where removed from the repository.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### OpenVR SDK
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OpenVR is an API and runtime that allows access to VR hardware from multiple 
 | 
				
			||||||
 | 
					vendors without requiring that applications have specific knowledge of the 
 | 
				
			||||||
 | 
					hardware they are targeting. This repository is an SDK that contains the API 
 | 
				
			||||||
 | 
					and samples. The runtime is under SteamVR in Tools on Steam. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Documentation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Documentation for the API is available on the [GitHub Wiki](https://github.com/ValveSoftware/openvr/wiki/API-Documentation)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					More information on OpenVR and SteamVR can be found on http://steamvr.com
 | 
				
			||||||
							
								
								
									
										9
									
								
								contrib/openvr/Toolchain-clang.cmake
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,9 @@
 | 
				
			||||||
 | 
					set(CMAKE_SYSTEM_NAME Linux)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set(CMAKE_C_COMPILER clang)
 | 
				
			||||||
 | 
					set(CMAKE_CXX_COMPILER clang++)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
 | 
				
			||||||
 | 
					set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
 | 
				
			||||||
 | 
					set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
 | 
				
			||||||
 | 
					set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
 | 
				
			||||||
							
								
								
									
										5624
									
								
								contrib/openvr/headers/openvr.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						
							
								
								
									
										8220
									
								
								contrib/openvr/headers/openvr_api.cs
									
										
									
									
									
										Executable file
									
								
							
							
						
						
							
								
								
									
										5761
									
								
								contrib/openvr/headers/openvr_api.json
									
										
									
									
									
										Executable file
									
								
							
							
						
						
							
								
								
									
										3125
									
								
								contrib/openvr/headers/openvr_capi.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						
							
								
								
									
										4212
									
								
								contrib/openvr/headers/openvr_driver.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						
							
								
								
									
										116
									
								
								contrib/openvr/src/CMakeLists.txt
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,116 @@
 | 
				
			||||||
 | 
					# Project name.
 | 
				
			||||||
 | 
					project(openvr_api)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set( LIBNAME "openvr_api" )
 | 
				
			||||||
 | 
					set(OPENVR_HEADER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../headers)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Set some properies for specific files.
 | 
				
			||||||
 | 
					if(APPLE)
 | 
				
			||||||
 | 
					  set(CMAKE_MACOSX_RPATH 1)
 | 
				
			||||||
 | 
					  if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
 | 
				
			||||||
 | 
					    set_source_files_properties(vrcommon/pathtools_public.cpp vrcommon/vrpathregistry_public.cpp PROPERTIES COMPILE_FLAGS "-x objective-c++")
 | 
				
			||||||
 | 
					  endif()
 | 
				
			||||||
 | 
					  if(BUILD_SHARED OR BUILD_FRAMEWORK)
 | 
				
			||||||
 | 
					    find_library(FOUNDATION_FRAMEWORK Foundation)
 | 
				
			||||||
 | 
					    mark_as_advanced(FOUNDATION_FRAMEWORK)
 | 
				
			||||||
 | 
					    set(EXTRA_LIBS ${EXTRA_LIBS} ${FOUNDATION_FRAMEWORK})
 | 
				
			||||||
 | 
					  endif(BUILD_SHARED OR BUILD_FRAMEWORK)
 | 
				
			||||||
 | 
					elseif(WIN32)
 | 
				
			||||||
 | 
					  if(CMAKE_SIZEOF_VOID_P EQUAL 8)
 | 
				
			||||||
 | 
					    add_definitions( -DWIN64 )
 | 
				
			||||||
 | 
					    set( LIBNAME "openvr_api64" )
 | 
				
			||||||
 | 
					  endif()
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Add include folders.
 | 
				
			||||||
 | 
					include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../headers ${CMAKE_CURRENT_SOURCE_DIR}/vrcommon)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(USE_CUSTOM_LIBCXX)
 | 
				
			||||||
 | 
						link_directories(
 | 
				
			||||||
 | 
							${LIBCXX_LIB_DIR}
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Set the source group and files.
 | 
				
			||||||
 | 
					set(CORE_FILES
 | 
				
			||||||
 | 
						openvr_api_public.cpp
 | 
				
			||||||
 | 
						jsoncpp.cpp
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					set(VRCOMMON_FILES
 | 
				
			||||||
 | 
						vrcommon/dirtools_public.cpp
 | 
				
			||||||
 | 
						vrcommon/envvartools_public.cpp
 | 
				
			||||||
 | 
						vrcommon/pathtools_public.cpp
 | 
				
			||||||
 | 
						vrcommon/sharedlibtools_public.cpp
 | 
				
			||||||
 | 
						vrcommon/hmderrors_public.cpp
 | 
				
			||||||
 | 
						vrcommon/vrpathregistry_public.cpp
 | 
				
			||||||
 | 
						vrcommon/strtools_public.cpp
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set(SOURCE_FILES
 | 
				
			||||||
 | 
						${CORE_FILES}
 | 
				
			||||||
 | 
						${VRCOMMON_FILES}
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set(PUBLIC_HEADER_FILES
 | 
				
			||||||
 | 
						${OPENVR_HEADER_DIR}/openvr_driver.h
 | 
				
			||||||
 | 
						${OPENVR_HEADER_DIR}/openvr_capi.h
 | 
				
			||||||
 | 
						${OPENVR_HEADER_DIR}/openvr.h
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					source_group("Src" FILES
 | 
				
			||||||
 | 
						${CORE_FILES}
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					source_group("VRCommon" FILES
 | 
				
			||||||
 | 
						${VRCOMMON_FILES}
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Build the library.
 | 
				
			||||||
 | 
					if(BUILD_SHARED)
 | 
				
			||||||
 | 
						add_library(${LIBNAME} SHARED ${SOURCE_FILES})
 | 
				
			||||||
 | 
					elseif(BUILD_FRAMEWORK)
 | 
				
			||||||
 | 
						set( LIBNAME "OpenVR" )
 | 
				
			||||||
 | 
						add_library( ${LIBNAME} 
 | 
				
			||||||
 | 
					            SHARED ${SOURCE_FILES}
 | 
				
			||||||
 | 
					            ${CMAKE_SOURCE_DIR}/headers/openvr.h
 | 
				
			||||||
 | 
					            ${CMAKE_SOURCE_DIR}/headers/openvr_api.cs
 | 
				
			||||||
 | 
					            ${CMAKE_SOURCE_DIR}/headers/openvr_api.json
 | 
				
			||||||
 | 
					            ${CMAKE_SOURCE_DIR}/headers/openvr_capi.h
 | 
				
			||||||
 | 
					            ${CMAKE_SOURCE_DIR}/headers/openvr_driver.h
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						set_target_properties(OpenVR PROPERTIES
 | 
				
			||||||
 | 
							FRAMEWORK TRUE
 | 
				
			||||||
 | 
							FRAMEWORK_VERSION A
 | 
				
			||||||
 | 
							MACOSX_FRAMEWORK_IDENTIFIER com.valvesoftware.OpenVR.framework
 | 
				
			||||||
 | 
							MACOSX_FRAMEWORK_INFO_PLIST ${CMAKE_SOURCE_DIR}/src/Info.plist
 | 
				
			||||||
 | 
							# "current version" in semantic format in Mach-O binary file
 | 
				
			||||||
 | 
							VERSION 1.0.6
 | 
				
			||||||
 | 
							# "compatibility version" in semantic format in Mach-O binary file
 | 
				
			||||||
 | 
							SOVERSION 1.0.0
 | 
				
			||||||
 | 
							PUBLIC_HEADER "${CMAKE_SOURCE_DIR}/headers/openvr.h;${CMAKE_SOURCE_DIR}/headers/openvr_api.cs;${CMAKE_SOURCE_DIR}/headers/openvr_api.json;${CMAKE_SOURCE_DIR}/headers/openvr_capi.h;${CMAKE_SOURCE_DIR}/headers/openvr_driver.h"
 | 
				
			||||||
 | 
							LINKER_LANGUAGE CXX
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					else()
 | 
				
			||||||
 | 
						add_library(${LIBNAME} STATIC ${SOURCE_FILES})
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(USE_CUSTOM_LIBCXX)
 | 
				
			||||||
 | 
						set(EXTRA_LIBS ${EXTRA_LIBS} c++ c++abi)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					target_link_libraries(${LIBNAME} ${EXTRA_LIBS} ${CMAKE_DL_LIBS})
 | 
				
			||||||
 | 
					target_include_directories(${LIBNAME} PUBLIC ${OPENVR_HEADER_DIR})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					install(TARGETS ${LIBNAME} DESTINATION lib)
 | 
				
			||||||
 | 
					install(FILES ${PUBLIC_HEADER_FILES} DESTINATION include/openvr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Generate a .pc file for linux environments
 | 
				
			||||||
 | 
					if(PLATFORM_NAME MATCHES "linux")
 | 
				
			||||||
 | 
					    set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files")
 | 
				
			||||||
 | 
					    CONFIGURE_FILE("openvr.pc.in" "openvr.pc" @ONLY)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set(OPENVR_PC ${CMAKE_CURRENT_BINARY_DIR}/openvr.pc)
 | 
				
			||||||
 | 
					    if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
 | 
				
			||||||
 | 
					        install(FILES ${OPENVR_PC} DESTINATION "${INSTALL_PKGCONFIG_DIR}")
 | 
				
			||||||
 | 
					    endif()
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
							
								
								
									
										18
									
								
								contrib/openvr/src/Info.plist
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 | 
				
			||||||
 | 
					<plist version="1.0">
 | 
				
			||||||
 | 
					<dict>
 | 
				
			||||||
 | 
						<key>CFBundleIdentifier</key>
 | 
				
			||||||
 | 
						<string>com.valvesoftware.OpenVR.framework</string>
 | 
				
			||||||
 | 
						<key>CFBundleInfoDictionaryVersion</key>
 | 
				
			||||||
 | 
						<string>6.0</string>
 | 
				
			||||||
 | 
						<key>CFBundleName</key>
 | 
				
			||||||
 | 
						<string>OpenVR</string>
 | 
				
			||||||
 | 
						<key>CFBundlePackageType</key>
 | 
				
			||||||
 | 
						<string>FMWK</string>
 | 
				
			||||||
 | 
						<key>CFBundleShortVersionString</key>
 | 
				
			||||||
 | 
						<string>1.0</string>
 | 
				
			||||||
 | 
						<key>CFBundleVersion</key>
 | 
				
			||||||
 | 
						<string>1.0</string>
 | 
				
			||||||
 | 
					</dict>
 | 
				
			||||||
 | 
					</plist>
 | 
				
			||||||
							
								
								
									
										39
									
								
								contrib/openvr/src/README
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,39 @@
 | 
				
			||||||
 | 
					This is the source code for the OpenVR API client binding library which connects
 | 
				
			||||||
 | 
					OpenVR applications to the SteamVR runtime, taking into account the version
 | 
				
			||||||
 | 
					of the OpenVR interface they were compiled against.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The client binding library - openvr_api.dll on Windows, openvr_api.so on
 | 
				
			||||||
 | 
					Linux, and openvr_api.dylib or OpenVR.framework on macOS - knows how to find
 | 
				
			||||||
 | 
					and read the SteamVR runtime installation information which allows it to
 | 
				
			||||||
 | 
					find and dynamically connect to the installed runtime. In combination with the
 | 
				
			||||||
 | 
					interface version identifiers from /include/openvr.h which are baked
 | 
				
			||||||
 | 
					into applications at the time they are built, the OpenVR API client
 | 
				
			||||||
 | 
					binding library captures and conveys to the SteamVR runtime the version
 | 
				
			||||||
 | 
					of the OpenVR API interface behavior that the application expects.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Applications carry with them a private/local copy of the client binding
 | 
				
			||||||
 | 
					library when they ship, and they should install it locally to their
 | 
				
			||||||
 | 
					application.  Applications should not install the client binding library
 | 
				
			||||||
 | 
					globally or attempt to link to a globally installed client binding library.
 | 
				
			||||||
 | 
					Doing so negates at least part of the ability for the client binding library
 | 
				
			||||||
 | 
					to accurately reflect the version of the OpenVR API that the application
 | 
				
			||||||
 | 
					was built against, and so hinders compatibility support in the face of
 | 
				
			||||||
 | 
					API changes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Most applications should simply link to and redistribute with their application
 | 
				
			||||||
 | 
					the pre-built client binding library found in the /bin directory of this
 | 
				
			||||||
 | 
					repository. Some small number of applications which have specific requirements
 | 
				
			||||||
 | 
					around redistributing only binaries they build themselves should build
 | 
				
			||||||
 | 
					the client library from this source and either statically link it into
 | 
				
			||||||
 | 
					their application or redistribute the binary they build.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This is a cmake project, to build it use the version of cmake appropriate
 | 
				
			||||||
 | 
					for your platform. For example, to build on a POSIX system simply perform
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  cd src; mkdir _build; cd _build; cmake ..; make
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					and you will end up with the static library /src/bin/<arch>/libopenvr_api.a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To build a shared library, pass -DBUILD_SHARED=1 to cmake.
 | 
				
			||||||
 | 
					To build as a framework on apple platforms, pass -DBUILD_FRAMEWORK=1 to cmake.
 | 
				
			||||||
 | 
					To see a complete list of configurable build options, use `cmake -LAH`
 | 
				
			||||||
							
								
								
									
										35
									
								
								contrib/openvr/src/ivrclientcore.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,35 @@
 | 
				
			||||||
 | 
					//========= Copyright Valve Corporation ============//
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace vr
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class IVRClientCore
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						/** Initializes the system */
 | 
				
			||||||
 | 
						virtual EVRInitError Init( vr::EVRApplicationType eApplicationType, const char *pStartupInfo ) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** cleans up everything in vrclient.dll and prepares the DLL to be unloaded */
 | 
				
			||||||
 | 
						virtual void Cleanup() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** checks to see if the specified interface/version is supported in this vrclient.dll */
 | 
				
			||||||
 | 
						virtual EVRInitError IsInterfaceVersionValid( const char *pchInterfaceVersion ) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** Retrieves any interface from vrclient.dll */
 | 
				
			||||||
 | 
						virtual void *GetGenericInterface( const char *pchNameAndVersion, EVRInitError *peError ) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** Returns true if any driver has an HMD attached. Can be called outside of Init/Cleanup */
 | 
				
			||||||
 | 
						virtual bool BIsHmdPresent() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** Returns an English error string from inside vrclient.dll which might be newer than the API DLL */
 | 
				
			||||||
 | 
						virtual const char *GetEnglishStringForHmdError( vr::EVRInitError eError ) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** Returns an error symbol from inside vrclient.dll which might be newer than the API DLL */
 | 
				
			||||||
 | 
						virtual const char *GetIDForVRInitError( vr::EVRInitError eError ) = 0;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char * const IVRClientCore_Version = "IVRClientCore_003";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										284
									
								
								contrib/openvr/src/json/json-forwards.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,284 @@
 | 
				
			||||||
 | 
					/// Json-cpp amalgated forward header (http://jsoncpp.sourceforge.net/).
 | 
				
			||||||
 | 
					/// It is intended to be used with #include "json/json-forwards.h"
 | 
				
			||||||
 | 
					/// This header provides forward declaration for all JsonCpp types.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// //////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// Beginning of content of file: LICENSE
 | 
				
			||||||
 | 
					// //////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					The JsonCpp library's source code, including accompanying documentation, 
 | 
				
			||||||
 | 
					tests and demonstration applications, are licensed under the following
 | 
				
			||||||
 | 
					conditions...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The author (Baptiste Lepilleur) explicitly disclaims copyright in all 
 | 
				
			||||||
 | 
					jurisdictions which recognize such a disclaimer. In such jurisdictions, 
 | 
				
			||||||
 | 
					this software is released into the Public Domain.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
 | 
				
			||||||
 | 
					2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
 | 
				
			||||||
 | 
					released under the terms of the MIT License (see below).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In jurisdictions which recognize Public Domain property, the user of this 
 | 
				
			||||||
 | 
					software may choose to accept it either as 1) Public Domain, 2) under the 
 | 
				
			||||||
 | 
					conditions of the MIT License (see below), or 3) under the terms of dual 
 | 
				
			||||||
 | 
					Public Domain/MIT License conditions described here, as they choose.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The MIT License is about as close to Public Domain as a license can get, and is
 | 
				
			||||||
 | 
					described in clear, concise terms at:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   http://en.wikipedia.org/wiki/MIT_License
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					The full text of the MIT License follows:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					========================================================================
 | 
				
			||||||
 | 
					Copyright (c) 2007-2010 Baptiste Lepilleur
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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.
 | 
				
			||||||
 | 
					========================================================================
 | 
				
			||||||
 | 
					(END LICENSE TEXT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The MIT license is compatible with both the GPL and commercial
 | 
				
			||||||
 | 
					software, affording one all of the rights of Public Domain with the
 | 
				
			||||||
 | 
					minor nuisance of being required to keep the above copyright notice
 | 
				
			||||||
 | 
					and license text in the source code. Note also that by accepting the
 | 
				
			||||||
 | 
					Public Domain "license" you can re-license your copy using whatever
 | 
				
			||||||
 | 
					license you like.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// //////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// End of content of file: LICENSE
 | 
				
			||||||
 | 
					// //////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_FORWARD_AMALGATED_H_INCLUDED
 | 
				
			||||||
 | 
					# define JSON_FORWARD_AMALGATED_H_INCLUDED
 | 
				
			||||||
 | 
					/// If defined, indicates that the source file is amalgated
 | 
				
			||||||
 | 
					/// to prevent private header inclusion.
 | 
				
			||||||
 | 
					#define JSON_IS_AMALGAMATION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// //////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// Beginning of content of file: include/json/config.h
 | 
				
			||||||
 | 
					// //////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Copyright 2007-2010 Baptiste Lepilleur
 | 
				
			||||||
 | 
					// Distributed under MIT license, or public domain if desired and
 | 
				
			||||||
 | 
					// recognized in your jurisdiction.
 | 
				
			||||||
 | 
					// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_CONFIG_H_INCLUDED
 | 
				
			||||||
 | 
					#define JSON_CONFIG_H_INCLUDED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// If defined, indicates that json library is embedded in CppTL library.
 | 
				
			||||||
 | 
					//# define JSON_IN_CPPTL 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// If defined, indicates that json may leverage CppTL library
 | 
				
			||||||
 | 
					//#  define JSON_USE_CPPTL 1
 | 
				
			||||||
 | 
					/// If defined, indicates that cpptl vector based map should be used instead of
 | 
				
			||||||
 | 
					/// std::map
 | 
				
			||||||
 | 
					/// as Value container.
 | 
				
			||||||
 | 
					//#  define JSON_USE_CPPTL_SMALLMAP 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// If non-zero, the library uses exceptions to report bad input instead of C
 | 
				
			||||||
 | 
					// assertion macros. The default is to use exceptions.
 | 
				
			||||||
 | 
					#ifndef JSON_USE_EXCEPTION
 | 
				
			||||||
 | 
					#define JSON_USE_EXCEPTION 1
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// If defined, indicates that the source file is amalgated
 | 
				
			||||||
 | 
					/// to prevent private header inclusion.
 | 
				
			||||||
 | 
					/// Remarks: it is automatically defined in the generated amalgated header.
 | 
				
			||||||
 | 
					// #define JSON_IS_AMALGAMATION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef JSON_IN_CPPTL
 | 
				
			||||||
 | 
					#include <cpptl/config.h>
 | 
				
			||||||
 | 
					#ifndef JSON_USE_CPPTL
 | 
				
			||||||
 | 
					#define JSON_USE_CPPTL 1
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef JSON_IN_CPPTL
 | 
				
			||||||
 | 
					#define JSON_API CPPTL_API
 | 
				
			||||||
 | 
					#elif defined(JSON_DLL_BUILD)
 | 
				
			||||||
 | 
					#if defined(_MSC_VER)
 | 
				
			||||||
 | 
					#define JSON_API __declspec(dllexport)
 | 
				
			||||||
 | 
					#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
 | 
				
			||||||
 | 
					#endif // if defined(_MSC_VER)
 | 
				
			||||||
 | 
					#elif defined(JSON_DLL)
 | 
				
			||||||
 | 
					#if defined(_MSC_VER)
 | 
				
			||||||
 | 
					#define JSON_API __declspec(dllimport)
 | 
				
			||||||
 | 
					#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
 | 
				
			||||||
 | 
					#endif // if defined(_MSC_VER)
 | 
				
			||||||
 | 
					#endif // ifdef JSON_IN_CPPTL
 | 
				
			||||||
 | 
					#if !defined(JSON_API)
 | 
				
			||||||
 | 
					#define JSON_API
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for
 | 
				
			||||||
 | 
					// integer
 | 
				
			||||||
 | 
					// Storages, and 64 bits integer support is disabled.
 | 
				
			||||||
 | 
					// #define JSON_NO_INT64 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(_MSC_VER) // MSVC
 | 
				
			||||||
 | 
					#  if _MSC_VER <= 1200 // MSVC 6
 | 
				
			||||||
 | 
					    // Microsoft Visual Studio 6 only support conversion from __int64 to double
 | 
				
			||||||
 | 
					    // (no conversion from unsigned __int64).
 | 
				
			||||||
 | 
					#    define JSON_USE_INT64_DOUBLE_CONVERSION 1
 | 
				
			||||||
 | 
					    // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
 | 
				
			||||||
 | 
					    // characters in the debug information)
 | 
				
			||||||
 | 
					    // All projects I've ever seen with VS6 were using this globally (not bothering
 | 
				
			||||||
 | 
					    // with pragma push/pop).
 | 
				
			||||||
 | 
					#    pragma warning(disable : 4786)
 | 
				
			||||||
 | 
					#  endif // MSVC 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  if _MSC_VER >= 1500 // MSVC 2008
 | 
				
			||||||
 | 
					    /// Indicates that the following function is deprecated.
 | 
				
			||||||
 | 
					#    define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
 | 
				
			||||||
 | 
					#  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // defined(_MSC_VER)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_HAS_RVALUE_REFERENCES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010
 | 
				
			||||||
 | 
					#define JSON_HAS_RVALUE_REFERENCES 1
 | 
				
			||||||
 | 
					#endif // MSVC >= 2010
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __clang__
 | 
				
			||||||
 | 
					#if __has_feature(cxx_rvalue_references)
 | 
				
			||||||
 | 
					#define JSON_HAS_RVALUE_REFERENCES 1
 | 
				
			||||||
 | 
					#endif  // has_feature
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
 | 
				
			||||||
 | 
					#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
 | 
				
			||||||
 | 
					#define JSON_HAS_RVALUE_REFERENCES 1
 | 
				
			||||||
 | 
					#endif  // GXX_EXPERIMENTAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // __clang__ || __GNUC__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // not defined JSON_HAS_RVALUE_REFERENCES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_HAS_RVALUE_REFERENCES
 | 
				
			||||||
 | 
					#define JSON_HAS_RVALUE_REFERENCES 0
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __clang__
 | 
				
			||||||
 | 
					#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
 | 
				
			||||||
 | 
					#  if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
 | 
				
			||||||
 | 
					#    define JSONCPP_DEPRECATED(message)  __attribute__ ((deprecated(message)))
 | 
				
			||||||
 | 
					#  elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
 | 
				
			||||||
 | 
					#    define JSONCPP_DEPRECATED(message)  __attribute__((__deprecated__))
 | 
				
			||||||
 | 
					#  endif  // GNUC version
 | 
				
			||||||
 | 
					#endif // __clang__ || __GNUC__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(JSONCPP_DEPRECATED)
 | 
				
			||||||
 | 
					#define JSONCPP_DEPRECATED(message)
 | 
				
			||||||
 | 
					#endif // if !defined(JSONCPP_DEPRECATED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Json {
 | 
				
			||||||
 | 
					typedef int Int;
 | 
				
			||||||
 | 
					typedef unsigned int UInt;
 | 
				
			||||||
 | 
					#if defined(JSON_NO_INT64)
 | 
				
			||||||
 | 
					typedef int LargestInt;
 | 
				
			||||||
 | 
					typedef unsigned int LargestUInt;
 | 
				
			||||||
 | 
					#undef JSON_HAS_INT64
 | 
				
			||||||
 | 
					#else                 // if defined(JSON_NO_INT64)
 | 
				
			||||||
 | 
					// For Microsoft Visual use specific types as long long is not supported
 | 
				
			||||||
 | 
					#if defined(_MSC_VER) // Microsoft Visual Studio
 | 
				
			||||||
 | 
					typedef __int64 Int64;
 | 
				
			||||||
 | 
					typedef unsigned __int64 UInt64;
 | 
				
			||||||
 | 
					#else                 // if defined(_MSC_VER) // Other platforms, use long long
 | 
				
			||||||
 | 
					typedef long long int Int64;
 | 
				
			||||||
 | 
					typedef unsigned long long int UInt64;
 | 
				
			||||||
 | 
					#endif // if defined(_MSC_VER)
 | 
				
			||||||
 | 
					typedef Int64 LargestInt;
 | 
				
			||||||
 | 
					typedef UInt64 LargestUInt;
 | 
				
			||||||
 | 
					#define JSON_HAS_INT64
 | 
				
			||||||
 | 
					#endif // if defined(JSON_NO_INT64)
 | 
				
			||||||
 | 
					} // end namespace Json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // JSON_CONFIG_H_INCLUDED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// //////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// End of content of file: include/json/config.h
 | 
				
			||||||
 | 
					// //////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// //////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// Beginning of content of file: include/json/forwards.h
 | 
				
			||||||
 | 
					// //////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Copyright 2007-2010 Baptiste Lepilleur
 | 
				
			||||||
 | 
					// Distributed under MIT license, or public domain if desired and
 | 
				
			||||||
 | 
					// recognized in your jurisdiction.
 | 
				
			||||||
 | 
					// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef JSON_FORWARDS_H_INCLUDED
 | 
				
			||||||
 | 
					#define JSON_FORWARDS_H_INCLUDED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(JSON_IS_AMALGAMATION)
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif // if !defined(JSON_IS_AMALGAMATION)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Json {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// writer.h
 | 
				
			||||||
 | 
					class FastWriter;
 | 
				
			||||||
 | 
					class StyledWriter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// reader.h
 | 
				
			||||||
 | 
					class Reader;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// features.h
 | 
				
			||||||
 | 
					class Features;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// value.h
 | 
				
			||||||
 | 
					typedef unsigned int ArrayIndex;
 | 
				
			||||||
 | 
					class StaticString;
 | 
				
			||||||
 | 
					class Path;
 | 
				
			||||||
 | 
					class PathArgument;
 | 
				
			||||||
 | 
					class Value;
 | 
				
			||||||
 | 
					class ValueIteratorBase;
 | 
				
			||||||
 | 
					class ValueIterator;
 | 
				
			||||||
 | 
					class ValueConstIterator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // JSON_FORWARDS_H_INCLUDED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// //////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// End of content of file: include/json/forwards.h
 | 
				
			||||||
 | 
					// //////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //ifndef JSON_FORWARD_AMALGATED_H_INCLUDED
 | 
				
			||||||
							
								
								
									
										2077
									
								
								contrib/openvr/src/json/json.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						
							
								
								
									
										5266
									
								
								contrib/openvr/src/jsoncpp.cpp
									
										
									
									
									
										Executable file
									
								
							
							
						
						
							
								
								
									
										11
									
								
								contrib/openvr/src/openvr.pc.in
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					prefix=@CMAKE_INSTALL_PREFIX@
 | 
				
			||||||
 | 
					exec_prefix=${prefix}
 | 
				
			||||||
 | 
					libdir=${prefix}/lib
 | 
				
			||||||
 | 
					includedir=${prefix}/include/openvr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Name: openvr
 | 
				
			||||||
 | 
					Description: OpenVR is an API and runtime that allos access to VR hardware.
 | 
				
			||||||
 | 
					Version: @OPENVR_VERSION@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Libs: -L${libdir} -lopenvr_api -ldl
 | 
				
			||||||
 | 
					Cflags: -I${includedir}
 | 
				
			||||||
							
								
								
									
										356
									
								
								contrib/openvr/src/openvr_api_public.cpp
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,356 @@
 | 
				
			||||||
 | 
					//========= Copyright Valve Corporation ============//
 | 
				
			||||||
 | 
					#define VR_API_EXPORT 1
 | 
				
			||||||
 | 
					#define VR_API_PUBLIC 1
 | 
				
			||||||
 | 
					#include "openvr.h"
 | 
				
			||||||
 | 
					#include "ivrclientcore.h"
 | 
				
			||||||
 | 
					#include <vrcommon/pathtools_public.h>
 | 
				
			||||||
 | 
					#include <vrcommon/sharedlibtools_public.h>
 | 
				
			||||||
 | 
					#include <vrcommon/envvartools_public.h>
 | 
				
			||||||
 | 
					#include "hmderrors_public.h"
 | 
				
			||||||
 | 
					#include <vrcommon/strtools_public.h>
 | 
				
			||||||
 | 
					#include <vrcommon/vrpathregistry_public.h>
 | 
				
			||||||
 | 
					#include <mutex>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using vr::EVRInitError;
 | 
				
			||||||
 | 
					using vr::IVRSystem;
 | 
				
			||||||
 | 
					using vr::IVRClientCore;
 | 
				
			||||||
 | 
					using vr::VRInitError_None;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// figure out how to import from the VR API dll
 | 
				
			||||||
 | 
					#if defined(_WIN32)
 | 
				
			||||||
 | 
					#define DYNAMIC_LIB_EXT ".dll"
 | 
				
			||||||
 | 
					#define PROGRAM_EXT ".exe"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(OPENVR_BUILD_STATIC)
 | 
				
			||||||
 | 
					#define VR_EXPORT_INTERFACE extern "C" __declspec( dllexport )
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define VR_EXPORT_INTERFACE extern "C"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#elif defined(__GNUC__) || defined(COMPILER_GCC) || defined(__APPLE__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VR_EXPORT_INTERFACE extern "C" __attribute__((visibility("default")))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#error "Unsupported Platform."
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace vr
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void *g_pVRModule = NULL;
 | 
				
			||||||
 | 
					static IVRClientCore *g_pHmdSystem = NULL;
 | 
				
			||||||
 | 
					static std::recursive_mutex g_mutexSystem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef void* (*VRClientCoreFactoryFn)(const char *pInterfaceName, int *pReturnCode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint32_t g_nVRToken = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t VR_GetInitToken()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return g_nVRToken;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EVRInitError VR_LoadHmdSystemInternal();
 | 
				
			||||||
 | 
					void CleanupInternalInterfaces();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t VR_InitInternal2( EVRInitError *peError, vr::EVRApplicationType eApplicationType, const char *pStartupInfo )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						EVRInitError err = VR_LoadHmdSystemInternal();
 | 
				
			||||||
 | 
						if ( err == vr::VRInitError_None )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							err = g_pHmdSystem->Init( eApplicationType, pStartupInfo );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( peError )
 | 
				
			||||||
 | 
							*peError = err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( err != VRInitError_None )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SharedLib_Unload( g_pVRModule );
 | 
				
			||||||
 | 
							g_pHmdSystem = NULL;
 | 
				
			||||||
 | 
							g_pVRModule = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ++g_nVRToken;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VR_INTERFACE uint32_t VR_CALLTYPE VR_InitInternal( EVRInitError *peError, EVRApplicationType eApplicationType );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t VR_InitInternal( EVRInitError *peError, vr::EVRApplicationType eApplicationType )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return VR_InitInternal2( peError, eApplicationType, nullptr );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void VR_ShutdownInternal()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined( VR_API_PUBLIC )
 | 
				
			||||||
 | 
						CleanupInternalInterfaces();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( g_pHmdSystem )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							g_pHmdSystem->Cleanup();
 | 
				
			||||||
 | 
							g_pHmdSystem = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( g_pVRModule )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SharedLib_Unload( g_pVRModule );
 | 
				
			||||||
 | 
							g_pVRModule = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						++g_nVRToken;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EVRInitError VR_LoadHmdSystemInternal()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string sRuntimePath, sConfigPath, sLogPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool bReadPathRegistry = CVRPathRegistry_Public::GetPaths( &sRuntimePath, &sConfigPath, &sLogPath, NULL, NULL );
 | 
				
			||||||
 | 
						if( !bReadPathRegistry )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return vr::VRInitError_Init_PathRegistryNotFound;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// figure out where we're going to look for vrclient.dll
 | 
				
			||||||
 | 
						// see if the specified path actually exists.
 | 
				
			||||||
 | 
						if( !Path_IsDirectory( sRuntimePath ) )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return vr::VRInitError_Init_InstallationNotFound;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Because we don't have a way to select debug vs. release yet we'll just
 | 
				
			||||||
 | 
						// use debug if it's there
 | 
				
			||||||
 | 
					#if defined( LINUX64 ) || defined( LINUXARM64 )
 | 
				
			||||||
 | 
						std::string sTestPath = Path_Join( sRuntimePath, "bin", PLATSUBDIR );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						std::string sTestPath = Path_Join( sRuntimePath, "bin" );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						if( !Path_IsDirectory( sTestPath ) )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return vr::VRInitError_Init_InstallationCorrupt;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined( WIN64 )
 | 
				
			||||||
 | 
						std::string sDLLPath = Path_Join( sTestPath, "vrclient_x64" DYNAMIC_LIB_EXT );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						std::string sDLLPath = Path_Join( sTestPath, "vrclient" DYNAMIC_LIB_EXT );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// only look in the override
 | 
				
			||||||
 | 
						void *pMod = SharedLib_Load( sDLLPath.c_str() );
 | 
				
			||||||
 | 
						// nothing more to do if we can't load the DLL
 | 
				
			||||||
 | 
						if( !pMod )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return vr::VRInitError_Init_VRClientDLLNotFound;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						VRClientCoreFactoryFn fnFactory = ( VRClientCoreFactoryFn )( SharedLib_GetFunction( pMod, "VRClientCoreFactory" ) );
 | 
				
			||||||
 | 
						if( !fnFactory )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SharedLib_Unload( pMod );
 | 
				
			||||||
 | 
							return vr::VRInitError_Init_FactoryNotFound;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int nReturnCode = 0;
 | 
				
			||||||
 | 
						g_pHmdSystem = static_cast< IVRClientCore * > ( fnFactory( vr::IVRClientCore_Version, &nReturnCode ) );
 | 
				
			||||||
 | 
						if( !g_pHmdSystem )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SharedLib_Unload( pMod );
 | 
				
			||||||
 | 
							return vr::VRInitError_Init_InterfaceNotFound;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						g_pVRModule = pMod;
 | 
				
			||||||
 | 
						return VRInitError_None;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *VR_GetGenericInterface(const char *pchInterfaceVersion, EVRInitError *peError)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!g_pHmdSystem)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (peError)
 | 
				
			||||||
 | 
								*peError = vr::VRInitError_Init_NotInitialized;
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return g_pHmdSystem->GetGenericInterface(pchInterfaceVersion, peError);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool VR_IsInterfaceVersionValid(const char *pchInterfaceVersion)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!g_pHmdSystem)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return g_pHmdSystem->IsInterfaceVersionValid(pchInterfaceVersion) == VRInitError_None;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool VR_IsHmdPresent()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if( g_pHmdSystem )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// if we're already initialized, just call through
 | 
				
			||||||
 | 
							return g_pHmdSystem->BIsHmdPresent();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// otherwise we need to do a bit more work
 | 
				
			||||||
 | 
							EVRInitError err = VR_LoadHmdSystemInternal();
 | 
				
			||||||
 | 
							if( err != VRInitError_None )
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							bool bHasHmd = g_pHmdSystem->BIsHmdPresent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							g_pHmdSystem = NULL;
 | 
				
			||||||
 | 
							SharedLib_Unload( g_pVRModule );
 | 
				
			||||||
 | 
							g_pVRModule = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return bHasHmd;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns true if the OpenVR runtime is installed. */
 | 
				
			||||||
 | 
					bool VR_IsRuntimeInstalled()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if( g_pHmdSystem )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// if we're already initialized, OpenVR is obviously installed
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// otherwise we need to do a bit more work
 | 
				
			||||||
 | 
							std::string sRuntimePath, sConfigPath, sLogPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							bool bReadPathRegistry = CVRPathRegistry_Public::GetPaths( &sRuntimePath, &sConfigPath, &sLogPath, NULL, NULL );
 | 
				
			||||||
 | 
							if( !bReadPathRegistry )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// figure out where we're going to look for vrclient.dll
 | 
				
			||||||
 | 
							// see if the specified path actually exists.
 | 
				
			||||||
 | 
							if( !Path_IsDirectory( sRuntimePath ) )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// the installation may be corrupt in some way, but it certainly looks installed
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: This is the old Runtime Path interface that is no longer exported in the
 | 
				
			||||||
 | 
					//			latest header. We still want to export it from the DLL, though, so updating
 | 
				
			||||||
 | 
					//			to a new DLL doesn't break old compiled code. This version was not thread 
 | 
				
			||||||
 | 
					//			safe and could change the buffer pointer to by a previous result on a 
 | 
				
			||||||
 | 
					//			subsequent call
 | 
				
			||||||
 | 
					// -------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					VR_EXPORT_INTERFACE const char *VR_CALLTYPE VR_RuntimePath();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns where OpenVR runtime is installed. */
 | 
				
			||||||
 | 
					const char *VR_RuntimePath()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static char rchBuffer[1024];
 | 
				
			||||||
 | 
						uint32_t unRequiredSize;
 | 
				
			||||||
 | 
						if ( VR_GetRuntimePath( rchBuffer, sizeof( rchBuffer ), &unRequiredSize ) && unRequiredSize < sizeof( rchBuffer ) )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return rchBuffer;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return nullptr;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns where OpenVR runtime is installed. */
 | 
				
			||||||
 | 
					bool VR_GetRuntimePath( char *pchPathBuffer, uint32_t unBufferSize, uint32_t *punRequiredBufferSize )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// otherwise we need to do a bit more work
 | 
				
			||||||
 | 
						std::string sRuntimePath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*punRequiredBufferSize = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool bReadPathRegistry = CVRPathRegistry_Public::GetPaths( &sRuntimePath, nullptr, nullptr, nullptr, nullptr );
 | 
				
			||||||
 | 
						if ( !bReadPathRegistry )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// figure out where we're going to look for vrclient.dll
 | 
				
			||||||
 | 
						// see if the specified path actually exists.
 | 
				
			||||||
 | 
						if ( !Path_IsDirectory( sRuntimePath ) )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*punRequiredBufferSize = (uint32_t)sRuntimePath.size() + 1;
 | 
				
			||||||
 | 
						if ( sRuntimePath.size() >= unBufferSize )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							*pchPathBuffer = '\0';
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							strcpy_safe( pchPathBuffer, unBufferSize, sRuntimePath.c_str() );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns the symbol version of an HMD error. */
 | 
				
			||||||
 | 
					const char *VR_GetVRInitErrorAsSymbol( EVRInitError error )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if( g_pHmdSystem )
 | 
				
			||||||
 | 
							return g_pHmdSystem->GetIDForVRInitError( error );
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return GetIDForVRInitError( error );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns the english string version of an HMD error. */
 | 
				
			||||||
 | 
					const char *VR_GetVRInitErrorAsEnglishDescription( EVRInitError error )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::lock_guard<std::recursive_mutex> lock( g_mutexSystem );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( g_pHmdSystem )
 | 
				
			||||||
 | 
							return g_pHmdSystem->GetEnglishStringForHmdError( error );
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return GetEnglishStringForHmdError( error );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VR_INTERFACE const char *VR_CALLTYPE VR_GetStringForHmdError( vr::EVRInitError error );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns the english string version of an HMD error. */
 | 
				
			||||||
 | 
					const char *VR_GetStringForHmdError( EVRInitError error )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return VR_GetVRInitErrorAsEnglishDescription( error );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										101
									
								
								contrib/openvr/src/vrcommon/dirtools_public.cpp
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,101 @@
 | 
				
			||||||
 | 
					//========= Copyright Valve Corporation ============//
 | 
				
			||||||
 | 
					#include <vrcommon/dirtools_public.h>
 | 
				
			||||||
 | 
					#include <vrcommon/strtools_public.h>
 | 
				
			||||||
 | 
					#include <vrcommon/pathtools_public.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					#include "windows.h"
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <sys/stat.h>
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined( OSX )
 | 
				
			||||||
 | 
					#include <sys/syslimits.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: utility function to create dirs & subdirs
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					bool BCreateDirectoryRecursive( const char *pchPath )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Does it already exist?
 | 
				
			||||||
 | 
						if ( Path_IsDirectory( pchPath ) )
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// copy the path into something we can munge
 | 
				
			||||||
 | 
						int len = (int)strlen( pchPath );
 | 
				
			||||||
 | 
						char *path = (char *)malloc( len + 1 );
 | 
				
			||||||
 | 
						strcpy( path, pchPath );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Walk backwards to first non-existing dir that we find
 | 
				
			||||||
 | 
						char *s = path + len - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const char slash = Path_GetSlash();
 | 
				
			||||||
 | 
						while ( s > path )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if ( *s == slash )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*s = '\0';
 | 
				
			||||||
 | 
								bool bExists = Path_IsDirectory( path );
 | 
				
			||||||
 | 
								*s = slash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if ( bExists )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									++s;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							--s;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// and then move forwards from there
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ( *s )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if ( *s == slash )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*s = '\0';
 | 
				
			||||||
 | 
								BCreateDirectory( path );
 | 
				
			||||||
 | 
								*s = slash;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							s++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool bRetVal = BCreateDirectory( path );
 | 
				
			||||||
 | 
						free( path );
 | 
				
			||||||
 | 
						return bRetVal;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Creates the directory, returning true if it is created, or if it already existed
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					bool BCreateDirectory( const char *pchPath )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef WIN32
 | 
				
			||||||
 | 
						std::wstring wPath = UTF8to16( pchPath );
 | 
				
			||||||
 | 
						if ( ::CreateDirectoryW( wPath.c_str(), NULL ) )
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( ::GetLastError() == ERROR_ALREADY_EXISTS )
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						int i = mkdir( pchPath, S_IRWXU | S_IRWXG | S_IRWXO );
 | 
				
			||||||
 | 
						if ( i == 0 )
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						if ( errno == EEXIST )
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										17
									
								
								contrib/openvr/src/vrcommon/dirtools_public.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,17 @@
 | 
				
			||||||
 | 
					//========= Copyright Valve Corporation ============//
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(_WIN32)
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <sys/stat.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern bool BCreateDirectoryRecursive( const char *pchPath );
 | 
				
			||||||
 | 
					extern bool BCreateDirectory( const char *pchPath );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										88
									
								
								contrib/openvr/src/vrcommon/envvartools_public.cpp
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,88 @@
 | 
				
			||||||
 | 
					//========= Copyright Valve Corporation ============//
 | 
				
			||||||
 | 
					#include <vrcommon/envvartools_public.h>
 | 
				
			||||||
 | 
					#include <vrcommon/strtools_public.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <cctype>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(_WIN32)
 | 
				
			||||||
 | 
					#include <windows.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef GetEnvironmentVariable
 | 
				
			||||||
 | 
					#undef SetEnvironmentVariable
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string GetEnvironmentVariable( const char *pchVarName )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined(_WIN32)
 | 
				
			||||||
 | 
						char rchValue[32767]; // max size for an env var on Windows
 | 
				
			||||||
 | 
						DWORD cChars = GetEnvironmentVariableA( pchVarName, rchValue, sizeof( rchValue ) );
 | 
				
			||||||
 | 
						if( cChars == 0 )
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return rchValue;
 | 
				
			||||||
 | 
					#elif defined(POSIX)
 | 
				
			||||||
 | 
						char *pchValue = getenv( pchVarName );
 | 
				
			||||||
 | 
						if( pchValue )
 | 
				
			||||||
 | 
							return pchValue;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#error "Unsupported Platform"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool GetEnvironmentVariableAsBool( const char *pchVarName, bool bDefault )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string sValue = GetEnvironmentVariable( pchVarName );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( sValue.empty() )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return bDefault;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sValue = StringToLower( sValue );
 | 
				
			||||||
 | 
						std::string sYesValues[] = { "y", "yes", "true" };
 | 
				
			||||||
 | 
						std::string sNoValues[] = { "n", "no", "false" };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for ( std::string &sMatch : sYesValues )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if ( sMatch == sValue )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for ( std::string &sMatch : sNoValues )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if ( sMatch == sValue )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( std::isdigit( sValue.at(0) ) )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return atoi( sValue.c_str() ) != 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fprintf( stderr,
 | 
				
			||||||
 | 
								 "GetEnvironmentVariableAsBool(%s): Unable to parse value '%s', using default %d\n",
 | 
				
			||||||
 | 
								 pchVarName, sValue.c_str(), bDefault );
 | 
				
			||||||
 | 
						return bDefault;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool SetEnvironmentVariable( const char *pchVarName, const char *pchVarValue )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined(_WIN32)
 | 
				
			||||||
 | 
						return 0 != SetEnvironmentVariableA( pchVarName, pchVarValue );
 | 
				
			||||||
 | 
					#elif defined(POSIX)
 | 
				
			||||||
 | 
						if( pchVarValue == NULL )
 | 
				
			||||||
 | 
							return 0 == unsetenv( pchVarName );
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return 0 == setenv( pchVarName, pchVarValue, 1 );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#error "Unsupported Platform"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										8
									
								
								contrib/openvr/src/vrcommon/envvartools_public.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					//========= Copyright Valve Corporation ============//
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string GetEnvironmentVariable( const char *pchVarName );
 | 
				
			||||||
 | 
					bool GetEnvironmentVariableAsBool( const char *pchVarName, bool bDefault );
 | 
				
			||||||
 | 
					bool SetEnvironmentVariable( const char *pchVarName, const char *pchVarValue );
 | 
				
			||||||
							
								
								
									
										338
									
								
								contrib/openvr/src/vrcommon/hmderrors_public.cpp
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,338 @@
 | 
				
			||||||
 | 
					//========= Copyright Valve Corporation ============//
 | 
				
			||||||
 | 
					#include "openvr.h"
 | 
				
			||||||
 | 
					#include "hmderrors_public.h"
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <algorithm>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace vr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define RETURN_ENUM_AS_STRING(enumValue) case enumValue: return #enumValue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *GetEnglishStringForHmdError( vr::EVRInitError eError )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch( eError )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						case VRInitError_None:								return "No Error (0)";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case VRInitError_Init_InstallationNotFound:			return "Installation Not Found (100)";
 | 
				
			||||||
 | 
						case VRInitError_Init_InstallationCorrupt:			return "Installation Corrupt (101)";
 | 
				
			||||||
 | 
						case VRInitError_Init_VRClientDLLNotFound:			return "vrclient Shared Lib Not Found (102)";
 | 
				
			||||||
 | 
						case VRInitError_Init_FileNotFound:					return "File Not Found (103)";
 | 
				
			||||||
 | 
						case VRInitError_Init_FactoryNotFound:				return "Factory Function Not Found (104)";
 | 
				
			||||||
 | 
						case VRInitError_Init_InterfaceNotFound:			return "Interface Not Found (105)";
 | 
				
			||||||
 | 
						case VRInitError_Init_InvalidInterface:				return "Invalid Interface (106)";
 | 
				
			||||||
 | 
						case VRInitError_Init_UserConfigDirectoryInvalid:	return "User Config Directory Invalid (107)";
 | 
				
			||||||
 | 
						case VRInitError_Init_HmdNotFound:					return "Hmd Not Found (108)";
 | 
				
			||||||
 | 
						case VRInitError_Init_NotInitialized:				return "Not Initialized (109)";
 | 
				
			||||||
 | 
						case VRInitError_Init_PathRegistryNotFound:			return "Installation path could not be located (110)";
 | 
				
			||||||
 | 
						case VRInitError_Init_NoConfigPath:					return "Config path could not be located (111)";
 | 
				
			||||||
 | 
						case VRInitError_Init_NoLogPath:					return "Log path could not be located (112)";
 | 
				
			||||||
 | 
						case VRInitError_Init_PathRegistryNotWritable:		return "Unable to write path registry (113)";
 | 
				
			||||||
 | 
						case VRInitError_Init_AppInfoInitFailed:			return "App info manager init failed (114)";
 | 
				
			||||||
 | 
						case VRInitError_Init_Retry:						return "Internal Retry (115)";
 | 
				
			||||||
 | 
						case VRInitError_Init_InitCanceledByUser:			return "User Canceled Init (116)";
 | 
				
			||||||
 | 
						case VRInitError_Init_AnotherAppLaunching:			return "Another app was already launching (117)";
 | 
				
			||||||
 | 
						case VRInitError_Init_SettingsInitFailed:			return "Settings manager init failed (118)";
 | 
				
			||||||
 | 
						case VRInitError_Init_ShuttingDown:					return "VR system shutting down (119)";
 | 
				
			||||||
 | 
						case VRInitError_Init_TooManyObjects:				return "Too many tracked objects (120)";
 | 
				
			||||||
 | 
						case VRInitError_Init_NoServerForBackgroundApp:		return "Not starting vrserver for background app (121)";
 | 
				
			||||||
 | 
						case VRInitError_Init_NotSupportedWithCompositor:	return "The requested interface is incompatible with the compositor and the compositor is running (122)";
 | 
				
			||||||
 | 
						case VRInitError_Init_NotAvailableToUtilityApps:	return "This interface is not available to utility applications (123)";
 | 
				
			||||||
 | 
						case VRInitError_Init_Internal:						return "vrserver internal error (124)";
 | 
				
			||||||
 | 
						case VRInitError_Init_HmdDriverIdIsNone:			return "Hmd DriverId is invalid (125)";
 | 
				
			||||||
 | 
						case VRInitError_Init_HmdNotFoundPresenceFailed:	return "Hmd Not Found Presence Failed (126)";
 | 
				
			||||||
 | 
						case VRInitError_Init_VRMonitorNotFound:			return "VR Monitor Not Found (127)";
 | 
				
			||||||
 | 
						case VRInitError_Init_VRMonitorStartupFailed:		return "VR Monitor startup failed (128)";
 | 
				
			||||||
 | 
						case VRInitError_Init_LowPowerWatchdogNotSupported: return "Low Power Watchdog Not Supported (129)";
 | 
				
			||||||
 | 
						case VRInitError_Init_InvalidApplicationType:		return "Invalid Application Type (130)";
 | 
				
			||||||
 | 
						case VRInitError_Init_NotAvailableToWatchdogApps:	return "Not available to watchdog apps (131)";
 | 
				
			||||||
 | 
						case VRInitError_Init_WatchdogDisabledInSettings:	return "Watchdog disabled in settings (132)";
 | 
				
			||||||
 | 
						case VRInitError_Init_VRDashboardNotFound:			return "VR Dashboard Not Found (133)";
 | 
				
			||||||
 | 
						case VRInitError_Init_VRDashboardStartupFailed:		return "VR Dashboard startup failed (134)";
 | 
				
			||||||
 | 
						case VRInitError_Init_VRHomeNotFound:				return "VR Home Not Found (135)";
 | 
				
			||||||
 | 
						case VRInitError_Init_VRHomeStartupFailed:			return "VR home startup failed (136)";
 | 
				
			||||||
 | 
						case VRInitError_Init_RebootingBusy:				return "Rebooting In Progress (137)";
 | 
				
			||||||
 | 
						case VRInitError_Init_FirmwareUpdateBusy:			return "Firmware Update In Progress (138)";
 | 
				
			||||||
 | 
						case VRInitError_Init_FirmwareRecoveryBusy:			return "Firmware Recovery In Progress (139)";
 | 
				
			||||||
 | 
						case VRInitError_Init_USBServiceBusy:				return "USB Service Busy (140)";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case VRInitError_Driver_Failed:							return "Driver Failed (200)";
 | 
				
			||||||
 | 
						case VRInitError_Driver_Unknown:						return "Driver Not Known (201)";
 | 
				
			||||||
 | 
						case VRInitError_Driver_HmdUnknown:						return "HMD Not Known (202)";
 | 
				
			||||||
 | 
						case VRInitError_Driver_NotLoaded:						return "Driver Not Loaded (203)";
 | 
				
			||||||
 | 
						case VRInitError_Driver_RuntimeOutOfDate:				return "Driver runtime is out of date (204)";
 | 
				
			||||||
 | 
						case VRInitError_Driver_HmdInUse:						return "HMD already in use by another application (205)";
 | 
				
			||||||
 | 
						case VRInitError_Driver_NotCalibrated:					return "Device is not calibrated (206)";
 | 
				
			||||||
 | 
						case VRInitError_Driver_CalibrationInvalid:				return "Device Calibration is invalid (207)";
 | 
				
			||||||
 | 
						case VRInitError_Driver_HmdDisplayNotFound:				return "HMD detected over USB, but Monitor not found (208)";
 | 
				
			||||||
 | 
						case VRInitError_Driver_TrackedDeviceInterfaceUnknown:	return "Driver Tracked Device Interface unknown (209)";
 | 
				
			||||||
 | 
						// case VRInitError_Driver_HmdDisplayNotFoundAfterFix:	return "HMD detected over USB, but Monitor not found after attempt to fix (210)"; // taken out upon Ben's request: He thinks that there is no need to separate that error from 208
 | 
				
			||||||
 | 
						case VRInitError_Driver_HmdDriverIdOutOfBounds:			return "Hmd DriverId is our of bounds (211)";
 | 
				
			||||||
 | 
						case VRInitError_Driver_HmdDisplayMirrored:				return "HMD detected over USB, but Monitor may be mirrored instead of extended (212)";
 | 
				
			||||||
 | 
						case VRInitError_Driver_HmdDisplayNotFoundLaptop:		return "On laptop, HMD detected over USB, but Monitor not found (213)";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case VRInitError_IPC_ServerInitFailed:						return "VR Server Init Failed (300)";
 | 
				
			||||||
 | 
						case VRInitError_IPC_ConnectFailed:							return "Connect to VR Server Failed (301)";
 | 
				
			||||||
 | 
						case VRInitError_IPC_SharedStateInitFailed:					return "Shared IPC State Init Failed (302)";
 | 
				
			||||||
 | 
						case VRInitError_IPC_CompositorInitFailed:					return "Shared IPC Compositor Init Failed (303)";
 | 
				
			||||||
 | 
						case VRInitError_IPC_MutexInitFailed:						return "Shared IPC Mutex Init Failed (304)";
 | 
				
			||||||
 | 
						case VRInitError_IPC_Failed:								return "Shared IPC Failed (305)";
 | 
				
			||||||
 | 
						case VRInitError_IPC_CompositorConnectFailed:				return "Shared IPC Compositor Connect Failed (306)";
 | 
				
			||||||
 | 
						case VRInitError_IPC_CompositorInvalidConnectResponse:		return "Shared IPC Compositor Invalid Connect Response (307)";
 | 
				
			||||||
 | 
						case VRInitError_IPC_ConnectFailedAfterMultipleAttempts:	return "Shared IPC Connect Failed After Multiple Attempts (308)";
 | 
				
			||||||
 | 
						case VRInitError_IPC_ConnectFailedAfterTargetExited:		return "Shared IPC Connect Failed After Target Exited (309)";
 | 
				
			||||||
 | 
						case VRInitError_IPC_NamespaceUnavailable:					return "Shared IPC Namespace Unavailable (310)";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case VRInitError_Compositor_Failed:					return "Compositor failed to initialize (400)";
 | 
				
			||||||
 | 
						case VRInitError_Compositor_D3D11HardwareRequired:	return "Compositor failed to find DX11 hardware (401)";
 | 
				
			||||||
 | 
						case VRInitError_Compositor_FirmwareRequiresUpdate:	return "Compositor requires mandatory firmware update (402)";
 | 
				
			||||||
 | 
						case VRInitError_Compositor_OverlayInitFailed:		return "Compositor initialization succeeded, but overlay init failed (403)";
 | 
				
			||||||
 | 
						case VRInitError_Compositor_ScreenshotsInitFailed:	return "Compositor initialization succeeded, but screenshot init failed (404)";
 | 
				
			||||||
 | 
						case VRInitError_Compositor_UnableToCreateDevice:	return "Compositor unable to create graphics device (405)";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Oculus
 | 
				
			||||||
 | 
						case VRInitError_VendorSpecific_UnableToConnectToOculusRuntime:	return "Unable to connect to Oculus Runtime (1000)";
 | 
				
			||||||
 | 
						case VRInitError_VendorSpecific_OculusRuntimeBadInstall:		return "Unable to connect to Oculus Runtime, possible bad install (1114)";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Lighthouse
 | 
				
			||||||
 | 
						case VRInitError_VendorSpecific_HmdFound_CantOpenDevice:				return "HMD found, but can not open device (1101)";
 | 
				
			||||||
 | 
						case VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart:	return "HMD found, but unable to request config (1102)";
 | 
				
			||||||
 | 
						case VRInitError_VendorSpecific_HmdFound_NoStoredConfig:				return "HMD found, but no stored config (1103)";
 | 
				
			||||||
 | 
						case VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck:       return "HMD found, but failed configuration check (1113)";
 | 
				
			||||||
 | 
						case VRInitError_VendorSpecific_HmdFound_ConfigTooBig:					return "HMD found, but config too big (1104)";
 | 
				
			||||||
 | 
						case VRInitError_VendorSpecific_HmdFound_ConfigTooSmall:				return "HMD found, but config too small (1105)";
 | 
				
			||||||
 | 
						case VRInitError_VendorSpecific_HmdFound_UnableToInitZLib:				return "HMD found, but unable to init ZLib (1106)";
 | 
				
			||||||
 | 
						case VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion:		return "HMD found, but problems with the data (1107)";
 | 
				
			||||||
 | 
						case VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart:		return "HMD found, but problems with the data (1108)";
 | 
				
			||||||
 | 
						case VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart:		return "HMD found, but problems with the data (1109)";
 | 
				
			||||||
 | 
						case VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext:		return "HMD found, but problems with the data (1110)";
 | 
				
			||||||
 | 
						case VRInitError_VendorSpecific_HmdFound_UserDataAddressRange:			return "HMD found, but problems with the data (1111)";
 | 
				
			||||||
 | 
						case VRInitError_VendorSpecific_HmdFound_UserDataError:					return "HMD found, but problems with the data (1112)";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case VRInitError_Steam_SteamInstallationNotFound: return "Unable to find Steam installation (2000)";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return GetIDForVRInitError( eError );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *GetIDForVRInitError( vr::EVRInitError eError )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch( eError )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_None );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Unknown );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_InstallationNotFound );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_InstallationCorrupt );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_VRClientDLLNotFound );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_FileNotFound );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_FactoryNotFound );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_InterfaceNotFound );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_InvalidInterface );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_UserConfigDirectoryInvalid );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_HmdNotFound );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_NotInitialized );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_PathRegistryNotFound );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_NoConfigPath );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_NoLogPath );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_PathRegistryNotWritable );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_AppInfoInitFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_Retry );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_InitCanceledByUser );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_AnotherAppLaunching );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_SettingsInitFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_ShuttingDown );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_TooManyObjects );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_NoServerForBackgroundApp );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_NotSupportedWithCompositor );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_NotAvailableToUtilityApps );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_Internal );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_HmdDriverIdIsNone );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_HmdNotFoundPresenceFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_VRMonitorNotFound );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_VRMonitorStartupFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_LowPowerWatchdogNotSupported );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_InvalidApplicationType );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_NotAvailableToWatchdogApps );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_WatchdogDisabledInSettings );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_VRDashboardNotFound );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_VRDashboardStartupFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_VRHomeNotFound );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_VRHomeStartupFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_RebootingBusy );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_FirmwareUpdateBusy );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_FirmwareRecoveryBusy );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_USBServiceBusy );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_VRWebHelperStartupFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_TrackerManagerInitFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_AlreadyRunning );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_FailedForVrMonitor);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_PropertyManagerInitFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_WebServerFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_IllegalTypeTransition );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_MismatchedRuntimes );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_InvalidProcessId );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_VRServiceStartupFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_PrismNeedsNewDrivers );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_PrismStartupTimedOut );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_CouldNotStartPrism );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_CreateDriverDirectDeviceFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Init_PrismExitedUnexpectedly );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Driver_Failed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Driver_Unknown );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Driver_HmdUnknown);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Driver_NotLoaded);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Driver_RuntimeOutOfDate);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Driver_HmdInUse);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Driver_NotCalibrated);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Driver_CalibrationInvalid);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Driver_HmdDisplayNotFound);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Driver_TrackedDeviceInterfaceUnknown );
 | 
				
			||||||
 | 
							// RETURN_ENUM_AS_STRING( VRInitError_Driver_HmdDisplayNotFoundAfterFix );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Driver_HmdDriverIdOutOfBounds );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Driver_HmdDisplayMirrored );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Driver_HmdDisplayNotFoundLaptop );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_IPC_ServerInitFailed);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_IPC_ConnectFailed);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_IPC_SharedStateInitFailed);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_IPC_CompositorInitFailed);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_IPC_MutexInitFailed);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_IPC_Failed);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_IPC_CompositorConnectFailed);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_IPC_CompositorInvalidConnectResponse);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_IPC_ConnectFailedAfterMultipleAttempts );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_IPC_ConnectFailedAfterTargetExited );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_IPC_NamespaceUnavailable );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_Failed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_D3D11HardwareRequired );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_FirmwareRequiresUpdate );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_OverlayInitFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_ScreenshotsInitFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_UnableToCreateDevice );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_SharedStateIsNull );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_NotificationManagerIsNull );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_ResourceManagerClientIsNull );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_MessageOverlaySharedStateInitFailure );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_PropertiesInterfaceIsNull );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateFullscreenWindowFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_SettingsInterfaceIsNull );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_FailedToShowWindow );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_DistortInterfaceIsNull );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_DisplayFrequencyFailure );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_RendererInitializationFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_DXGIFactoryInterfaceIsNull );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_DXGIFactoryCreateFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_DXGIFactoryQueryFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_InvalidAdapterDesktop );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_InvalidHmdAttachment );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_InvalidOutputDesktop );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_InvalidDeviceProvided );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_D3D11RendererInitializationFailed );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_FailedToFindDisplayMode );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_FailedToCreateSwapChain );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_FailedToGetBackBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_FailedToCreateRenderTarget );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_FailedToCreateDXGI2SwapChain );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_FailedtoGetDXGI2BackBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_FailedToCreateDXGI2RenderTarget );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_FailedToGetDXGIDeviceInterface );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_SelectDisplayMode );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_FailedToCreateNvAPIRenderTargets );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_NvAPISetDisplayMode );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_FailedToCreateDirectModeDisplay );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_InvalidHmdPropertyContainer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_UpdateDisplayFrequency );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateRasterizerState );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateWireframeRasterizerState );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateSamplerState );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateClampToBorderSamplerState );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateAnisoSamplerState );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateOverlaySamplerState );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreatePanoramaSamplerState );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateFontSamplerState );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateNoBlendState );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateBlendState );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateAlphaBlendState );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateBlendStateMaskR );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateBlendStateMaskG );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateBlendStateMaskB );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateDepthStencilState );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateDepthStencilStateNoWrite );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateDepthStencilStateNoDepth );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateFlushTexture );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateDistortionSurfaces );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateConstantBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateHmdPoseConstantBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateHmdPoseStagingConstantBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateSharedFrameInfoConstantBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateOverlayConstantBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateSceneTextureIndexConstantBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateReadableSceneTextureIndexConstantBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateLayerGraphicsTextureIndexConstantBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateLayerComputeTextureIndexConstantBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateLayerComputeSceneTextureIndexConstantBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateComputeHmdPoseConstantBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateGeomConstantBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreatePanelMaskConstantBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreatePixelSimUBO );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateMSAARenderTextures );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateResolveRenderTextures );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateComputeResolveRenderTextures );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateDriverDirectModeResolveTextures );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_OpenDriverDirectModeResolveTextures );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateFallbackSyncTexture );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_ShareFallbackSyncTexture );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateOverlayIndexBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateOverlayVertexBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateTextVertexBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateTextIndexBuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateMirrorTextures );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateLastFrameRenderTexture );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateMirrorOverlay );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_FailedToCreateVirtualDisplayBackbuffer );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_DisplayModeNotSupported );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateOverlayInvalidCall );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_CreateOverlayAlreadyInitialized );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_FailedToCreateMailbox );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_WindowInterfaceIsNull );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_SystemLayerCreateInstance );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Compositor_SystemLayerCreateSession );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Vendor-specific errors
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_UnableToConnectToOculusRuntime);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_WindowsNotInDevMode );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_OculusRuntimeBadInstall );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Lighthouse
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_CantOpenDevice);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_NoStoredConfig);
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_ConfigTooBig );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_ConfigTooSmall );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_UnableToInitZLib );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_UserDataAddressRange );
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_VendorSpecific_HmdFound_UserDataError );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							RETURN_ENUM_AS_STRING( VRInitError_Steam_SteamInstallationNotFound );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								static char buf[128];
 | 
				
			||||||
 | 
								sprintf( buf, "Unknown error (%d)", eError );
 | 
				
			||||||
 | 
								return buf;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										6
									
								
								contrib/openvr/src/vrcommon/hmderrors_public.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					//========= Copyright Valve Corporation ============//
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *GetEnglishStringForHmdError( vr::EVRInitError eError );
 | 
				
			||||||
 | 
					const char *GetIDForVRInitError( vr::EVRInitError eError );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										988
									
								
								contrib/openvr/src/vrcommon/pathtools_public.cpp
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,988 @@
 | 
				
			||||||
 | 
					//========= Copyright Valve Corporation ============//
 | 
				
			||||||
 | 
					#include <vrcommon/strtools_public.h>
 | 
				
			||||||
 | 
					#include <vrcommon/pathtools_public.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined( _WIN32)
 | 
				
			||||||
 | 
					#include <windows.h>
 | 
				
			||||||
 | 
					#include <direct.h>
 | 
				
			||||||
 | 
					#include <shobjidl.h>
 | 
				
			||||||
 | 
					#include <knownfolders.h>
 | 
				
			||||||
 | 
					#include <shlobj.h>
 | 
				
			||||||
 | 
					#include <share.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef GetEnvironmentVariable
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include <dlfcn.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <alloca.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined OSX
 | 
				
			||||||
 | 
					#include <Foundation/Foundation.h>
 | 
				
			||||||
 | 
					#include <AppKit/AppKit.h>
 | 
				
			||||||
 | 
					#include <mach-o/dyld.h>
 | 
				
			||||||
 | 
					#define _S_IFDIR S_IFDIR     // really from tier0/platform.h which we dont have yet
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/stat.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <algorithm>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns the path (including filename) to the current executable */
 | 
				
			||||||
 | 
					std::string Path_GetExecutablePath()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined( _WIN32 )
 | 
				
			||||||
 | 
						wchar_t *pwchPath = new wchar_t[MAX_UNICODE_PATH];
 | 
				
			||||||
 | 
						char *pchPath = new char[MAX_UNICODE_PATH_IN_UTF8];
 | 
				
			||||||
 | 
						::GetModuleFileNameW( NULL, pwchPath, MAX_UNICODE_PATH );
 | 
				
			||||||
 | 
						WideCharToMultiByte( CP_UTF8, 0, pwchPath, -1, pchPath, MAX_UNICODE_PATH_IN_UTF8, NULL, NULL );
 | 
				
			||||||
 | 
						delete[] pwchPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string sPath = pchPath;
 | 
				
			||||||
 | 
						delete[] pchPath;
 | 
				
			||||||
 | 
						return sPath;
 | 
				
			||||||
 | 
					#elif defined( OSX )
 | 
				
			||||||
 | 
						char rchPath[1024];
 | 
				
			||||||
 | 
						uint32_t nBuff = sizeof( rchPath );
 | 
				
			||||||
 | 
						bool bSuccess = _NSGetExecutablePath(rchPath, &nBuff) == 0;
 | 
				
			||||||
 | 
						rchPath[nBuff-1] = '\0';
 | 
				
			||||||
 | 
						if( bSuccess )
 | 
				
			||||||
 | 
							return rchPath;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
					#elif defined LINUX
 | 
				
			||||||
 | 
						char rchPath[1024];
 | 
				
			||||||
 | 
						size_t nBuff = sizeof( rchPath );
 | 
				
			||||||
 | 
						ssize_t nRead = readlink("/proc/self/exe", rchPath, nBuff-1 );
 | 
				
			||||||
 | 
						if ( nRead != -1 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							rchPath[ nRead ] = 0;
 | 
				
			||||||
 | 
							return rchPath;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						AssertMsg( false, "Implement Plat_GetExecutablePath" );
 | 
				
			||||||
 | 
						return "";
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns the path of the current working directory */
 | 
				
			||||||
 | 
					std::string Path_GetWorkingDirectory()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string sPath;
 | 
				
			||||||
 | 
					#if defined( _WIN32 )
 | 
				
			||||||
 | 
						wchar_t buf[MAX_UNICODE_PATH];
 | 
				
			||||||
 | 
						sPath = UTF16to8( _wgetcwd( buf, MAX_UNICODE_PATH ) );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						char buf[ 1024 ];
 | 
				
			||||||
 | 
						sPath = getcwd( buf, sizeof( buf ) );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						return sPath;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Sets the path of the current working directory. Returns true if this was successful. */
 | 
				
			||||||
 | 
					bool Path_SetWorkingDirectory( const std::string & sPath )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						bool bSuccess;
 | 
				
			||||||
 | 
					#if defined( _WIN32 )
 | 
				
			||||||
 | 
						std::wstring wsPath = UTF8to16( sPath.c_str() );
 | 
				
			||||||
 | 
						bSuccess = 0 == _wchdir( wsPath.c_str() );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						bSuccess = 0 == chdir( sPath.c_str() );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						return bSuccess;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Gets the path to a temporary directory. */
 | 
				
			||||||
 | 
					std::string Path_GetTemporaryDirectory()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined( _WIN32 )
 | 
				
			||||||
 | 
						wchar_t buf[MAX_UNICODE_PATH];
 | 
				
			||||||
 | 
						if ( GetTempPathW( MAX_UNICODE_PATH, buf ) == 0 )
 | 
				
			||||||
 | 
							return Path_GetWorkingDirectory();
 | 
				
			||||||
 | 
						return UTF16to8( buf );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						const char *pchTmpDir = getenv( "TMPDIR" );
 | 
				
			||||||
 | 
						if ( pchTmpDir == NULL )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return pchTmpDir;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns the specified path without its filename */
 | 
				
			||||||
 | 
					std::string Path_StripFilename( const std::string & sPath, char slash )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if( slash == 0 )
 | 
				
			||||||
 | 
							slash = Path_GetSlash();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string::size_type n = sPath.find_last_of( slash );
 | 
				
			||||||
 | 
						if( n == std::string::npos )
 | 
				
			||||||
 | 
							return sPath;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return std::string( sPath.begin(), sPath.begin() + n );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** returns just the filename from the provided full or relative path. */
 | 
				
			||||||
 | 
					std::string Path_StripDirectory( const std::string & sPath, char slash )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if( slash == 0 )
 | 
				
			||||||
 | 
							slash = Path_GetSlash();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string::size_type n = sPath.find_last_of( slash );
 | 
				
			||||||
 | 
						if( n == std::string::npos )
 | 
				
			||||||
 | 
							return sPath;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return std::string( sPath.begin() + n + 1, sPath.end() );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** returns just the filename with no extension of the provided filename. 
 | 
				
			||||||
 | 
					* If there is a path the path is left intact. */
 | 
				
			||||||
 | 
					std::string Path_StripExtension( const std::string & sPath )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						for( std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++ )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if( *i == '.' )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return std::string( sPath.begin(), i.base() - 1 );
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// if we find a slash there is no extension
 | 
				
			||||||
 | 
							if( *i == '\\' || *i == '/' )
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// we didn't find an extension
 | 
				
			||||||
 | 
						return sPath;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** returns just extension of the provided filename (if any). */
 | 
				
			||||||
 | 
					std::string Path_GetExtension( const std::string & sPath )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						for ( std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++ )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if ( *i == '.' )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return std::string( i.base(), sPath.end() );
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// if we find a slash there is no extension
 | 
				
			||||||
 | 
							if ( *i == '\\' || *i == '/' )
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// we didn't find an extension
 | 
				
			||||||
 | 
						return "";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Path_IsAbsolute( const std::string & sPath )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if( sPath.empty() )
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
						if ( sPath.size() < 3 ) // must be c:\x or \\x at least
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( sPath[1] == ':' ) // drive letter plus slash, but must test both slash cases
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if ( sPath[2] == '\\' || sPath[2] == '/' )
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if ( sPath[0] == '\\' && sPath[1] == '\\' ) // UNC path
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						if( sPath[0] == '\\' || sPath[0] == '/' ) // any leading slash
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Makes an absolute path from a relative path and a base path */
 | 
				
			||||||
 | 
					std::string Path_MakeAbsolute( const std::string & sRelativePath, const std::string & sBasePath )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if( Path_IsAbsolute( sRelativePath ) )
 | 
				
			||||||
 | 
							return Path_Compact( sRelativePath );
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if( !Path_IsAbsolute( sBasePath ) )
 | 
				
			||||||
 | 
								return "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							std::string sCompacted = Path_Compact( Path_Join( sBasePath, sRelativePath ) );
 | 
				
			||||||
 | 
							if( Path_IsAbsolute( sCompacted ) )
 | 
				
			||||||
 | 
								return sCompacted;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								return "";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Fixes the directory separators for the current platform */
 | 
				
			||||||
 | 
					std::string Path_FixSlashes( const std::string & sPath, char slash )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if( slash == 0 )
 | 
				
			||||||
 | 
							slash = Path_GetSlash();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string sFixed = sPath;
 | 
				
			||||||
 | 
						for( std::string::iterator i = sFixed.begin(); i != sFixed.end(); i++ )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if( *i == '/' || *i == '\\' )
 | 
				
			||||||
 | 
								*i = slash;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sFixed;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char Path_GetSlash()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined(_WIN32)
 | 
				
			||||||
 | 
						return '\\';
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						return '/';
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Jams two paths together with the right kind of slash */
 | 
				
			||||||
 | 
					std::string Path_Join( const std::string & first, const std::string & second, char slash )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if( slash == 0 )
 | 
				
			||||||
 | 
							slash = Path_GetSlash();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// only insert a slash if we don't already have one
 | 
				
			||||||
 | 
						std::string::size_type nLen = first.length();
 | 
				
			||||||
 | 
						if( !nLen )
 | 
				
			||||||
 | 
							return second;
 | 
				
			||||||
 | 
					#if defined(_WIN32)
 | 
				
			||||||
 | 
						if( first.back() == '\\' || first.back() == '/' )
 | 
				
			||||||
 | 
						    nLen--;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						char last_char = first[first.length()-1];
 | 
				
			||||||
 | 
						if (last_char == '\\' || last_char == '/')
 | 
				
			||||||
 | 
						    nLen--;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return first.substr( 0, nLen ) + std::string( 1, slash ) + second;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, char slash )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return Path_Join( Path_Join( first, second, slash ), third, slash );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, const std::string &fourth, char slash )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return Path_Join( Path_Join( Path_Join( first, second, slash ), third, slash ), fourth, slash );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string Path_Join( 
 | 
				
			||||||
 | 
						const std::string & first, 
 | 
				
			||||||
 | 
						const std::string & second, 
 | 
				
			||||||
 | 
						const std::string & third, 
 | 
				
			||||||
 | 
						const std::string & fourth, 
 | 
				
			||||||
 | 
						const std::string & fifth, 
 | 
				
			||||||
 | 
						char slash )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return Path_Join( Path_Join( Path_Join( Path_Join( first, second, slash ), third, slash ), fourth, slash ), fifth, slash );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string Path_RemoveTrailingSlash( const std::string & sRawPath, char slash )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ( slash == 0 )
 | 
				
			||||||
 | 
							slash = Path_GetSlash();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string sPath = sRawPath;
 | 
				
			||||||
 | 
						std::string::size_type nCurrent = sRawPath.length();
 | 
				
			||||||
 | 
						if ( nCurrent == 0 )
 | 
				
			||||||
 | 
							return sPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int nLastFound = -1;
 | 
				
			||||||
 | 
						nCurrent--;
 | 
				
			||||||
 | 
						while( nCurrent != 0 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if ( sRawPath[ nCurrent ] == slash )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								nLastFound = (int)nCurrent;
 | 
				
			||||||
 | 
								nCurrent--;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
						if ( nLastFound >= 0 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							sPath.erase( nLastFound, std::string::npos );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						return sPath;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Removes redundant <dir>/.. elements in the path. Returns an empty path if the 
 | 
				
			||||||
 | 
					* specified path has a broken number of directories for its number of ..s */
 | 
				
			||||||
 | 
					std::string Path_Compact( const std::string & sRawPath, char slash )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if( slash == 0 )
 | 
				
			||||||
 | 
							slash = Path_GetSlash();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string sPath = Path_FixSlashes( sRawPath, slash );
 | 
				
			||||||
 | 
						std::string sSlashString( 1, slash );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// strip out all /./
 | 
				
			||||||
 | 
						for( std::string::size_type i = 0; (i + 3) < sPath.length();  )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if( sPath[ i ] == slash && sPath[ i+1 ] == '.' && sPath[ i+2 ] == slash )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								sPath.replace( i, 3, sSlashString );
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								++i;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// get rid of trailing /. but leave the path separator
 | 
				
			||||||
 | 
						if( sPath.length() > 2 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							std::string::size_type len = sPath.length();
 | 
				
			||||||
 | 
							if( sPath[ len-1 ] == '.'  && sPath[ len-2 ] == slash )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								sPath.pop_back();
 | 
				
			||||||
 | 
								//Not sure why the following line of code was used for a while.  It causes problems with strlen.
 | 
				
			||||||
 | 
								//sPath[len-1] = 0;  // for now, at least 
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// get rid of leading ./ 
 | 
				
			||||||
 | 
						if( sPath.length() > 2 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if( sPath[ 0 ] == '.'  && sPath[ 1 ] == slash )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								sPath.replace( 0, 2, "" );
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// each time we encounter .. back up until we've found the previous directory name
 | 
				
			||||||
 | 
						// then get rid of both
 | 
				
			||||||
 | 
						std::string::size_type i = 0;
 | 
				
			||||||
 | 
						while( i < sPath.length() )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if( i > 0 && sPath.length() - i >= 2 
 | 
				
			||||||
 | 
								&& sPath[i] == '.'
 | 
				
			||||||
 | 
								&& sPath[i+1] == '.'
 | 
				
			||||||
 | 
								&& ( i + 2 == sPath.length() || sPath[ i+2 ] == slash )
 | 
				
			||||||
 | 
								&& sPath[ i-1 ] == slash )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								// check if we've hit the start of the string and have a bogus path
 | 
				
			||||||
 | 
								if( i == 1 )
 | 
				
			||||||
 | 
									return "";
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								// find the separator before i-1
 | 
				
			||||||
 | 
								std::string::size_type iDirStart = i-2;
 | 
				
			||||||
 | 
								while( iDirStart > 0 && sPath[ iDirStart - 1 ] != slash )
 | 
				
			||||||
 | 
									--iDirStart;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// remove everything from iDirStart to i+2
 | 
				
			||||||
 | 
								sPath.replace( iDirStart, (i - iDirStart) + 3, "" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// start over
 | 
				
			||||||
 | 
								i = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								++i;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sPath;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns true if these two paths are the same without respect for internal . or ..
 | 
				
			||||||
 | 
					* sequences, slash type, or case (on case-insensitive platforms). */
 | 
				
			||||||
 | 
					bool Path_IsSamePath( const std::string & sPath1, const std::string & sPath2 )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string sCompact1 = Path_Compact( sPath1 );
 | 
				
			||||||
 | 
						std::string sCompact2 = Path_Compact( sPath2 );
 | 
				
			||||||
 | 
					#if defined(WIN32)
 | 
				
			||||||
 | 
						return !stricmp( sCompact1.c_str(), sCompact2.c_str() );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						return !strcmp( sCompact1.c_str(), sCompact2.c_str() );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns the path to the current DLL or exe */
 | 
				
			||||||
 | 
					std::string Path_GetThisModulePath()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// gets the path of vrclient.dll itself
 | 
				
			||||||
 | 
					#ifdef WIN32
 | 
				
			||||||
 | 
						HMODULE hmodule = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						::GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast<LPCTSTR>(Path_GetThisModulePath), &hmodule );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wchar_t *pwchPath = new wchar_t[MAX_UNICODE_PATH];
 | 
				
			||||||
 | 
						char *pchPath = new char[ MAX_UNICODE_PATH_IN_UTF8 ];
 | 
				
			||||||
 | 
						::GetModuleFileNameW( hmodule, pwchPath, MAX_UNICODE_PATH );
 | 
				
			||||||
 | 
						WideCharToMultiByte( CP_UTF8, 0, pwchPath, -1, pchPath, MAX_UNICODE_PATH_IN_UTF8, NULL, NULL );
 | 
				
			||||||
 | 
						delete[] pwchPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string sPath = pchPath;
 | 
				
			||||||
 | 
						delete [] pchPath;
 | 
				
			||||||
 | 
						return sPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#elif defined( OSX ) || defined( LINUX )
 | 
				
			||||||
 | 
						// get the addr of a function in vrclient.so and then ask the dlopen system about it
 | 
				
			||||||
 | 
						Dl_info info;
 | 
				
			||||||
 | 
						dladdr( (void *)Path_GetThisModulePath, &info );
 | 
				
			||||||
 | 
						return info.dli_fname;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** returns true if the specified path exists and is a directory */
 | 
				
			||||||
 | 
					bool Path_IsDirectory( const std::string & sPath )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string sFixedPath = Path_FixSlashes( sPath );
 | 
				
			||||||
 | 
						if( sFixedPath.empty() )
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						char cLast = sFixedPath[ sFixedPath.length() - 1 ];
 | 
				
			||||||
 | 
						if( cLast == '/' || cLast == '\\' )
 | 
				
			||||||
 | 
							sFixedPath.erase( sFixedPath.end() - 1, sFixedPath.end() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// see if the specified path actually exists.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(POSIX)
 | 
				
			||||||
 | 
						struct	stat	buf;
 | 
				
			||||||
 | 
						if ( stat( sFixedPath.c_str(), &buf ) == -1 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined( LINUX ) || defined( OSX )
 | 
				
			||||||
 | 
						return S_ISDIR( buf.st_mode );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						return (buf.st_mode & _S_IFDIR) != 0;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						struct	_stat	buf;
 | 
				
			||||||
 | 
						std::wstring wsFixedPath = UTF8to16( sFixedPath.c_str() );
 | 
				
			||||||
 | 
						if ( _wstat( wsFixedPath.c_str(), &buf ) == -1 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (buf.st_mode & _S_IFDIR) != 0;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** returns true if the specified path represents an app bundle */
 | 
				
			||||||
 | 
					bool Path_IsAppBundle( const std::string & sPath )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined(OSX)
 | 
				
			||||||
 | 
						@autoreleasepool {
 | 
				
			||||||
 | 
							NSBundle *bundle = [ NSBundle bundleWithPath: [ NSString stringWithUTF8String:sPath.c_str() ] ];
 | 
				
			||||||
 | 
							bool bisAppBundle = ( nullptr != bundle );
 | 
				
			||||||
 | 
							return bisAppBundle;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: returns true if the the path exists
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					bool Path_Exists( const std::string & sPath )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string sFixedPath = Path_FixSlashes( sPath );
 | 
				
			||||||
 | 
						if( sFixedPath.empty() )
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
						struct	_stat	buf;
 | 
				
			||||||
 | 
						std::wstring wsFixedPath = UTF8to16( sFixedPath.c_str() );
 | 
				
			||||||
 | 
						if ( _wstat( wsFixedPath.c_str(), &buf ) == -1 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						struct stat buf;
 | 
				
			||||||
 | 
						if ( stat ( sFixedPath.c_str(), &buf ) == -1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: helper to find a directory upstream from a given path
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					std::string Path_FindParentDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string strFoundPath = "";
 | 
				
			||||||
 | 
						std::string strCurrentPath = Path_FixSlashes( strStartDirectory );
 | 
				
			||||||
 | 
						if ( strCurrentPath.length() == 0 )
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool bExists = Path_Exists( strCurrentPath );
 | 
				
			||||||
 | 
						std::string strCurrentDirectoryName = Path_StripDirectory( strCurrentPath );
 | 
				
			||||||
 | 
						if ( bExists && stricmp( strCurrentDirectoryName.c_str(), strDirectoryName.c_str() ) == 0 )
 | 
				
			||||||
 | 
							return strCurrentPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while( bExists && strCurrentPath.length() != 0 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							strCurrentPath = Path_StripFilename( strCurrentPath );
 | 
				
			||||||
 | 
							strCurrentDirectoryName = Path_StripDirectory( strCurrentPath );
 | 
				
			||||||
 | 
							bExists = Path_Exists( strCurrentPath );
 | 
				
			||||||
 | 
							if ( bExists && stricmp( strCurrentDirectoryName.c_str(), strDirectoryName.c_str() ) == 0 )
 | 
				
			||||||
 | 
								return strCurrentPath;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return "";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: helper to find a subdirectory upstream from a given path
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					std::string Path_FindParentSubDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string strFoundPath = "";
 | 
				
			||||||
 | 
						std::string strCurrentPath = Path_FixSlashes( strStartDirectory );
 | 
				
			||||||
 | 
						if ( strCurrentPath.length() == 0 )
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool bExists = Path_Exists( strCurrentPath );
 | 
				
			||||||
 | 
						while( bExists && strCurrentPath.length() != 0 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							strCurrentPath = Path_StripFilename( strCurrentPath );
 | 
				
			||||||
 | 
							bExists = Path_Exists( strCurrentPath );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if( Path_Exists( Path_Join( strCurrentPath, strDirectoryName ) ) )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								strFoundPath = Path_Join( strCurrentPath, strDirectoryName );
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return strFoundPath;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: reading and writing files in the vortex directory
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					std::vector<uint8_t> Path_ReadBinaryFile( const std::string & strFilename )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						FILE *f;
 | 
				
			||||||
 | 
					#if defined( POSIX )
 | 
				
			||||||
 | 
						f = fopen( strFilename.c_str(), "rb" );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						std::wstring wstrFilename = UTF8to16( strFilename.c_str() );
 | 
				
			||||||
 | 
						// the open operation needs to be sharable, therefore use of _wfsopen instead of _wfopen_s
 | 
				
			||||||
 | 
						f = _wfsopen( wstrFilename.c_str(), L"rb", _SH_DENYNO );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::vector<uint8_t> vecFileContents;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( f != NULL )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							fseek( f, 0, SEEK_END );
 | 
				
			||||||
 | 
							int size = ftell( f );
 | 
				
			||||||
 | 
							fseek( f, 0, SEEK_SET );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							vecFileContents.resize( size );
 | 
				
			||||||
 | 
							if ( fread( &vecFileContents[ 0 ], size, 1, f ) == 1 )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								vecFileContents.clear();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fclose( f );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return vecFileContents ;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned char * Path_ReadBinaryFile( const std::string &strFilename, int *pSize )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						FILE *f;
 | 
				
			||||||
 | 
					#if defined( POSIX )
 | 
				
			||||||
 | 
						f = fopen( strFilename.c_str(), "rb" );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						std::wstring wstrFilename = UTF8to16( strFilename.c_str() );
 | 
				
			||||||
 | 
						// the open operation needs to be sharable, therefore use of _wfsopen instead of _wfopen_s
 | 
				
			||||||
 | 
						f = _wfsopen( wstrFilename.c_str(), L"rb", _SH_DENYNO );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						unsigned char* buf = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( f != NULL )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							fseek(f, 0, SEEK_END);
 | 
				
			||||||
 | 
							int size = ftell(f);
 | 
				
			||||||
 | 
							fseek(f, 0, SEEK_SET);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							buf = new unsigned char[size];
 | 
				
			||||||
 | 
							if (buf && fread(buf, size, 1, f) == 1)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (pSize)
 | 
				
			||||||
 | 
									*pSize = size;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								delete[] buf;
 | 
				
			||||||
 | 
								buf = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fclose(f);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return buf;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t  Path_ReadBinaryFile( const std::string &strFilename, unsigned char *pBuffer, uint32_t unSize )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						FILE *f;
 | 
				
			||||||
 | 
					#if defined( POSIX )
 | 
				
			||||||
 | 
						f = fopen( strFilename.c_str(), "rb" );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						std::wstring wstrFilename = UTF8to16( strFilename.c_str() );
 | 
				
			||||||
 | 
						errno_t err = _wfopen_s( &f, wstrFilename.c_str(), L"rb" );
 | 
				
			||||||
 | 
						if ( err != 0 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							f = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t unSizeToReturn = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( f != NULL )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							fseek( f, 0, SEEK_END );
 | 
				
			||||||
 | 
							uint32_t size = (uint32_t)ftell( f );
 | 
				
			||||||
 | 
							fseek( f, 0, SEEK_SET );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ( size > unSize || !pBuffer )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								unSizeToReturn = (uint32_t)size;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if ( fread( pBuffer, size, 1, f ) == 1 )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									unSizeToReturn = (uint32_t)size;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fclose( f );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return unSizeToReturn;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Path_WriteBinaryFile(const std::string &strFilename, unsigned char *pData, unsigned nSize)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						FILE *f;
 | 
				
			||||||
 | 
					#if defined( POSIX )
 | 
				
			||||||
 | 
						f = fopen(strFilename.c_str(), "wb");
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						std::wstring wstrFilename = UTF8to16( strFilename.c_str() );
 | 
				
			||||||
 | 
						errno_t err = _wfopen_s( &f, wstrFilename.c_str(), L"wb" );
 | 
				
			||||||
 | 
						if (err != 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							f = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						size_t written = 0;
 | 
				
			||||||
 | 
						if (f != NULL) {
 | 
				
			||||||
 | 
							written = fwrite(pData, sizeof(unsigned char), nSize, f);
 | 
				
			||||||
 | 
							fclose(f);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return written == nSize ? true : false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string Path_ReadTextFile( const std::string &strFilename )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// doing it this way seems backwards, but I don't
 | 
				
			||||||
 | 
						// see an easy way to do this with C/C++ style IO
 | 
				
			||||||
 | 
						// that isn't worse...
 | 
				
			||||||
 | 
						int size;
 | 
				
			||||||
 | 
						unsigned char* buf = Path_ReadBinaryFile( strFilename, &size );
 | 
				
			||||||
 | 
						if (!buf)
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// convert CRLF -> LF
 | 
				
			||||||
 | 
						size_t outsize = 1;
 | 
				
			||||||
 | 
						for (int i=1; i < size; i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (buf[i] == '\n' && buf[i-1] == '\r') // CRLF
 | 
				
			||||||
 | 
								buf[outsize-1] = '\n'; // ->LF
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								buf[outsize++] = buf[i]; // just copy
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string ret((char *)buf, outsize);
 | 
				
			||||||
 | 
						delete[] buf;
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Path_MakeWritable( const std::string &strFilename )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined ( _WIN32 )
 | 
				
			||||||
 | 
						std::wstring wstrFilename = UTF8to16( strFilename.c_str() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DWORD dwAttrs = GetFileAttributesW( wstrFilename.c_str() );
 | 
				
			||||||
 | 
						if ( dwAttrs != INVALID_FILE_ATTRIBUTES && ( dwAttrs & FILE_ATTRIBUTE_READONLY ) )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return SetFileAttributesW( wstrFilename.c_str(), dwAttrs & ~FILE_ATTRIBUTE_READONLY );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						struct stat sb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( stat( strFilename.c_str(), &sb ) == 0 && !( sb.st_mode & S_IWUSR ) )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return ( chmod( strFilename.c_str(), sb.st_mode | S_IWUSR ) == 0 );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Path_WriteStringToTextFile( const std::string &strFilename, const char *pchData )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						FILE *f;
 | 
				
			||||||
 | 
					#if defined( POSIX )
 | 
				
			||||||
 | 
						f = fopen( strFilename.c_str(), "w" );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						std::wstring wstrFilename = UTF8to16( strFilename.c_str() );
 | 
				
			||||||
 | 
						errno_t err = _wfopen_s( &f, wstrFilename.c_str(), L"w" );
 | 
				
			||||||
 | 
						if ( err != 0 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							f = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						bool ok = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( f != NULL )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ok = fputs( pchData, f) >= 0;
 | 
				
			||||||
 | 
							fclose(f);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ok;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Path_WriteStringToTextFileAtomic( const std::string &strFilename, const char *pchData )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string strTmpFilename = strFilename + ".tmp";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( !Path_WriteStringToTextFile( strTmpFilename, pchData ) )
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Platform specific atomic file replacement
 | 
				
			||||||
 | 
					#if defined( _WIN32 )
 | 
				
			||||||
 | 
						std::wstring wsFilename = UTF8to16( strFilename.c_str() );
 | 
				
			||||||
 | 
						std::wstring wsTmpFilename = UTF8to16( strTmpFilename.c_str() );
 | 
				
			||||||
 | 
						if ( !::ReplaceFileW( wsFilename.c_str(), wsTmpFilename.c_str(), nullptr, 0, 0, 0 ) )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// if we couldn't ReplaceFile, try a non-atomic write as a fallback
 | 
				
			||||||
 | 
							if ( !Path_WriteStringToTextFile( strFilename, pchData ) )
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#elif defined( POSIX )
 | 
				
			||||||
 | 
						if ( rename( strTmpFilename.c_str(), strFilename.c_str() ) == -1 )
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#error Do not know how to write atomic file
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(WIN32)
 | 
				
			||||||
 | 
					#define FILE_URL_PREFIX "file:///"
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define FILE_URL_PREFIX "file://"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ----------------------------------------------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Turns a path to a file on disk into a URL (or just returns the value if it's already a URL)
 | 
				
			||||||
 | 
					// ----------------------------------------------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					std::string Path_FilePathToUrl( const std::string & sRelativePath, const std::string & sBasePath )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ( StringHasPrefix( sRelativePath, "http://" )
 | 
				
			||||||
 | 
							|| StringHasPrefix( sRelativePath, "https://" )
 | 
				
			||||||
 | 
							|| StringHasPrefix( sRelativePath, "vr-input-workshop://" )
 | 
				
			||||||
 | 
							|| StringHasPrefix( sRelativePath, "file://" )
 | 
				
			||||||
 | 
						   )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return sRelativePath;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							std::string sAbsolute = Path_MakeAbsolute( sRelativePath, sBasePath );
 | 
				
			||||||
 | 
							if ( sAbsolute.empty() )
 | 
				
			||||||
 | 
								return sAbsolute;
 | 
				
			||||||
 | 
							sAbsolute = Path_FixSlashes( sAbsolute, '/' );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							size_t unBufferSize = sAbsolute.length() * 3;
 | 
				
			||||||
 | 
							char *pchBuffer = (char *)alloca( unBufferSize );
 | 
				
			||||||
 | 
							V_URLEncodeFullPath( pchBuffer, (int)unBufferSize, sAbsolute.c_str(), (int)sAbsolute.length() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return std::string( FILE_URL_PREFIX ) + pchBuffer;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -----------------------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Strips off file:// off a URL and returns the path. For other kinds of URLs an empty string is returned
 | 
				
			||||||
 | 
					// -----------------------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					std::string Path_UrlToFilePath( const std::string & sFileUrl )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ( !strnicmp( sFileUrl.c_str(), FILE_URL_PREFIX, strlen( FILE_URL_PREFIX ) ) )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							char *pchBuffer = (char *)alloca( sFileUrl.length() );
 | 
				
			||||||
 | 
							V_URLDecodeNoPlusForSpace( pchBuffer, (int)sFileUrl.length(), 
 | 
				
			||||||
 | 
								sFileUrl.c_str() + strlen( FILE_URL_PREFIX ), (int)( sFileUrl.length() - strlen( FILE_URL_PREFIX ) ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return Path_FixSlashes( pchBuffer );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -----------------------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Returns the root of the directory the system wants us to store user documents in
 | 
				
			||||||
 | 
					// -----------------------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					std::string GetUserDocumentsPath()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
						WCHAR rwchPath[MAX_PATH];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( !SUCCEEDED( SHGetFolderPathW( NULL, CSIDL_MYDOCUMENTS | CSIDL_FLAG_CREATE, NULL, 0, rwchPath ) ) )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Convert the path to UTF-8 and store in the output
 | 
				
			||||||
 | 
						std::string sUserPath = UTF16to8( rwchPath );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sUserPath;
 | 
				
			||||||
 | 
					#elif defined( OSX )
 | 
				
			||||||
 | 
						@autoreleasepool {
 | 
				
			||||||
 | 
							NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES );
 | 
				
			||||||
 | 
							if ( [paths count] == 0 )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return "";
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							return [[paths objectAtIndex:0] UTF8String];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#elif defined( LINUX )
 | 
				
			||||||
 | 
						// @todo: not solved/changed as part of OSX - still not real - just removed old class based steam cut and paste
 | 
				
			||||||
 | 
						const char *pchHome = getenv( "HOME" );
 | 
				
			||||||
 | 
						if ( pchHome == NULL )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return pchHome;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -----------------------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: deletes / unlinks a single file
 | 
				
			||||||
 | 
					// -----------------------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					bool Path_UnlinkFile( const std::string &strFilename )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
						std::wstring wsFilename = UTF8to16( strFilename.c_str() );
 | 
				
			||||||
 | 
						return ( 0 != DeleteFileW( wsFilename.c_str() ) );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						return ( 0 == unlink( strFilename.c_str() ) );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -----------------------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Limits the set of characters that are allowed in filenames
 | 
				
			||||||
 | 
					// -----------------------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					std::string Path_SanitizeFilename( const std::string& sFilename )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string sFixed = sFilename;
 | 
				
			||||||
 | 
						std::string::iterator iLastDot = sFixed.end();
 | 
				
			||||||
 | 
						for ( std::string::iterator i = sFixed.begin(); i != sFixed.end(); i++ )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if ( *i == '.' )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								iLastDot = i;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// path-related characters are forbidden (except the last period)
 | 
				
			||||||
 | 
							switch ( *i )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								case '\0':
 | 
				
			||||||
 | 
								case '.':
 | 
				
			||||||
 | 
								case '\\':
 | 
				
			||||||
 | 
								case '/':
 | 
				
			||||||
 | 
								case ':':
 | 
				
			||||||
 | 
								case '|':
 | 
				
			||||||
 | 
								case '?':
 | 
				
			||||||
 | 
								case '>':
 | 
				
			||||||
 | 
								case '<':
 | 
				
			||||||
 | 
								case '&':
 | 
				
			||||||
 | 
								case '%':
 | 
				
			||||||
 | 
								case '@':
 | 
				
			||||||
 | 
								case '$':
 | 
				
			||||||
 | 
								case '*':
 | 
				
			||||||
 | 
								case '\"':
 | 
				
			||||||
 | 
									*i = '_';
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									if ( *i < 32 )
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										*i = '_';
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( iLastDot != sFixed.end() && iLastDot != sFixed.begin() 
 | 
				
			||||||
 | 
							&& iLastDot+1 != sFixed.end() )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							*iLastDot = '.';
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sFixed;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										153
									
								
								contrib/openvr/src/vrcommon/pathtools_public.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,153 @@
 | 
				
			||||||
 | 
					//========= Copyright Valve Corporation ============//
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns the path (including filename) to the current executable */
 | 
				
			||||||
 | 
					std::string Path_GetExecutablePath();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns the path of the current working directory */
 | 
				
			||||||
 | 
					std::string Path_GetWorkingDirectory();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Sets the path of the current working directory. Returns true if this was successful. */
 | 
				
			||||||
 | 
					bool Path_SetWorkingDirectory( const std::string & sPath );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Gets the path to a temporary directory. */
 | 
				
			||||||
 | 
					std::string Path_GetTemporaryDirectory();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** returns the path (including filename) of the current shared lib or DLL */
 | 
				
			||||||
 | 
					std::string Path_GetThisModulePath();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns the specified path without its filename.
 | 
				
			||||||
 | 
					* If slash is unspecified the native path separator of the current platform
 | 
				
			||||||
 | 
					* will be used. */
 | 
				
			||||||
 | 
					std::string Path_StripFilename( const std::string & sPath, char slash = 0 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** returns just the filename from the provided full or relative path. */
 | 
				
			||||||
 | 
					std::string Path_StripDirectory( const std::string & sPath, char slash = 0 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** returns just the filename with no extension of the provided filename. 
 | 
				
			||||||
 | 
					* If there is a path the path is left intact. */
 | 
				
			||||||
 | 
					std::string Path_StripExtension( const std::string & sPath );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** returns just extension of the provided filename (if any). */
 | 
				
			||||||
 | 
					std::string Path_GetExtension( const std::string & sPath );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns true if the path is absolute */
 | 
				
			||||||
 | 
					bool Path_IsAbsolute( const std::string & sPath );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Makes an absolute path from a relative path and a base path */
 | 
				
			||||||
 | 
					std::string Path_MakeAbsolute( const std::string & sRelativePath, const std::string & sBasePath );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Fixes the directory separators for the current platform.
 | 
				
			||||||
 | 
					* If slash is unspecified the native path separator of the current platform
 | 
				
			||||||
 | 
					* will be used. */
 | 
				
			||||||
 | 
					std::string Path_FixSlashes( const std::string & sPath, char slash = 0 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns the path separator for the current platform */
 | 
				
			||||||
 | 
					char Path_GetSlash();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Jams two paths together with the right kind of slash */
 | 
				
			||||||
 | 
					std::string Path_Join( const std::string & first, const std::string & second, char slash = 0 );
 | 
				
			||||||
 | 
					std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, char slash = 0 );
 | 
				
			||||||
 | 
					std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, const std::string &fourth, char slash = 0 );
 | 
				
			||||||
 | 
					std::string Path_Join( 
 | 
				
			||||||
 | 
						const std::string & first, 
 | 
				
			||||||
 | 
						const std::string & second, 
 | 
				
			||||||
 | 
						const std::string & third, 
 | 
				
			||||||
 | 
						const std::string & fourth, 
 | 
				
			||||||
 | 
						const std::string & fifth, 
 | 
				
			||||||
 | 
						char slash = 0 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Removes redundant <dir>/.. elements in the path. Returns an empty path if the 
 | 
				
			||||||
 | 
					* specified path has a broken number of directories for its number of ..s.
 | 
				
			||||||
 | 
					* If slash is unspecified the native path separator of the current platform
 | 
				
			||||||
 | 
					* will be used. */
 | 
				
			||||||
 | 
					std::string Path_Compact( const std::string & sRawPath, char slash = 0 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns true if these two paths are the same without respect for internal . or ..
 | 
				
			||||||
 | 
					* sequences, slash type, or case (on case-insensitive platforms). */
 | 
				
			||||||
 | 
					bool Path_IsSamePath( const std::string & sPath1, const std::string & sPath2 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//** Removed trailing slashes */
 | 
				
			||||||
 | 
					std::string Path_RemoveTrailingSlash( const std::string & sRawPath, char slash = 0 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** returns true if the specified path exists and is a directory */
 | 
				
			||||||
 | 
					bool Path_IsDirectory( const std::string & sPath );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** returns true if the specified path represents an app bundle */
 | 
				
			||||||
 | 
					bool Path_IsAppBundle( const std::string & sPath );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** returns true if the the path exists */
 | 
				
			||||||
 | 
					bool Path_Exists( const std::string & sPath );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Helper functions to find parent directories or subdirectories of parent directories */
 | 
				
			||||||
 | 
					std::string Path_FindParentDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName );
 | 
				
			||||||
 | 
					std::string Path_FindParentSubDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Make a text file writable. */
 | 
				
			||||||
 | 
					bool Path_MakeWritable( const std::string &strFilename );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Path operations to read or write text/binary files */
 | 
				
			||||||
 | 
					unsigned char * Path_ReadBinaryFile( const std::string &strFilename, int *pSize );
 | 
				
			||||||
 | 
					uint32_t  Path_ReadBinaryFile( const std::string &strFilename, unsigned char *pBuffer, uint32_t unSize );
 | 
				
			||||||
 | 
					std::vector<uint8_t> Path_ReadBinaryFile( const std::string & strFilename );
 | 
				
			||||||
 | 
					bool Path_WriteBinaryFile( const std::string &strFilename, unsigned char *pData, unsigned nSize );
 | 
				
			||||||
 | 
					std::string Path_ReadTextFile( const std::string &strFilename );
 | 
				
			||||||
 | 
					bool Path_WriteStringToTextFile( const std::string &strFilename, const char *pchData );
 | 
				
			||||||
 | 
					bool Path_WriteStringToTextFileAtomic( const std::string &strFilename, const char *pchData );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns a file:// url for paths, or an http or https url if that's what was provided */
 | 
				
			||||||
 | 
					std::string Path_FilePathToUrl( const std::string & sRelativePath, const std::string & sBasePath );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Strips off file:// off a URL and returns the path. For other kinds of URLs an empty string is returned */
 | 
				
			||||||
 | 
					std::string Path_UrlToFilePath( const std::string & sFileUrl );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns the root of the directory the system wants us to store user documents in */
 | 
				
			||||||
 | 
					std::string GetUserDocumentsPath();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** deletes / unlinks a single file */
 | 
				
			||||||
 | 
					bool Path_UnlinkFile( const std::string &strFilename );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string Path_SanitizeFilename( const std::string& sFilename );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef MAX_UNICODE_PATH
 | 
				
			||||||
 | 
						#define MAX_UNICODE_PATH 32767
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef MAX_UNICODE_PATH_IN_UTF8
 | 
				
			||||||
 | 
						#define MAX_UNICODE_PATH_IN_UTF8 (MAX_UNICODE_PATH * 4)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					#if defined(WIN32)
 | 
				
			||||||
 | 
					#define DYNAMIC_LIB_EXT	".dll"
 | 
				
			||||||
 | 
					#define PROGRAM_EXT ".exe"
 | 
				
			||||||
 | 
					#ifdef _WIN64
 | 
				
			||||||
 | 
					#define PLATSUBDIR	"win64"
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define PLATSUBDIR	"win32"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#elif defined(OSX)
 | 
				
			||||||
 | 
					#define DYNAMIC_LIB_EXT	".dylib"
 | 
				
			||||||
 | 
					#define PLATSUBDIR	"osx32"
 | 
				
			||||||
 | 
					#define PROGRAM_EXT ""
 | 
				
			||||||
 | 
					#elif defined(LINUX)
 | 
				
			||||||
 | 
					#define DYNAMIC_LIB_EXT	".so"
 | 
				
			||||||
 | 
					#define PROGRAM_EXT ""
 | 
				
			||||||
 | 
					#if defined( LINUX32 )
 | 
				
			||||||
 | 
					#define PLATSUBDIR	"linux32"
 | 
				
			||||||
 | 
					#elif defined( ANDROIDARM64 )
 | 
				
			||||||
 | 
					#define PLATSUBDIR	"androidarm64" 
 | 
				
			||||||
 | 
					#elif defined( LINUXARM64 )
 | 
				
			||||||
 | 
					#define PLATSUBDIR	"linuxarm64" 
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define PLATSUBDIR	"linux64"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#warning "Unknown platform for PLATSUBDIR"
 | 
				
			||||||
 | 
					#define PLATSUBDIR	"unknown_platform"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										63
									
								
								contrib/openvr/src/vrcommon/sharedlibtools_public.cpp
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,63 @@
 | 
				
			||||||
 | 
					//========= Copyright Valve Corporation ============//
 | 
				
			||||||
 | 
					#include <vrcommon/sharedlibtools_public.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(_WIN32)
 | 
				
			||||||
 | 
					#include <windows.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(POSIX)
 | 
				
			||||||
 | 
					#include <dlfcn.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SharedLibHandle SharedLib_Load( const char *pchPath, uint32_t *pErrorCode )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						SharedLibHandle pHandle = nullptr;
 | 
				
			||||||
 | 
					#if defined( _WIN32)
 | 
				
			||||||
 | 
						pHandle = ( SharedLibHandle )LoadLibraryEx( pchPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH );
 | 
				
			||||||
 | 
					#elif defined(POSIX)
 | 
				
			||||||
 | 
						pHandle = (SharedLibHandle) dlopen(pchPath, RTLD_LOCAL|RTLD_NOW);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( pErrorCode )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if ( pHandle == nullptr )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
					#if defined( _WIN32)
 | 
				
			||||||
 | 
								*pErrorCode = ( uint32_t ) GetLastError();
 | 
				
			||||||
 | 
					#elif defined(POSIX)
 | 
				
			||||||
 | 
								*pErrorCode = 1;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*pErrorCode = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return pHandle;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *SharedLib_GetFunction( SharedLibHandle lib, const char *pchFunctionName)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined( _WIN32)
 | 
				
			||||||
 | 
						return (void*)GetProcAddress( (HMODULE)lib, pchFunctionName );
 | 
				
			||||||
 | 
					#elif defined(POSIX)
 | 
				
			||||||
 | 
						return dlsym( lib, pchFunctionName );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SharedLib_Unload( SharedLibHandle lib )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ( !lib )
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					#if defined( _WIN32)
 | 
				
			||||||
 | 
						FreeLibrary( (HMODULE)lib );
 | 
				
			||||||
 | 
					#elif defined(POSIX)
 | 
				
			||||||
 | 
						dlclose( lib );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										12
									
								
								contrib/openvr/src/vrcommon/sharedlibtools_public.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					//========= Copyright Valve Corporation ============//
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef void *SharedLibHandle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SharedLibHandle SharedLib_Load( const char *pchPath, uint32_t *pErrorCode = nullptr );
 | 
				
			||||||
 | 
					void *SharedLib_GetFunction( SharedLibHandle lib, const char *pchFunctionName);
 | 
				
			||||||
 | 
					void SharedLib_Unload( SharedLibHandle lib );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										606
									
								
								contrib/openvr/src/vrcommon/strtools_public.cpp
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,606 @@
 | 
				
			||||||
 | 
					//========= Copyright Valve Corporation ============//
 | 
				
			||||||
 | 
					#include <vrcommon/strtools_public.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <sstream>
 | 
				
			||||||
 | 
					#include <codecvt>
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <functional>
 | 
				
			||||||
 | 
					#include <locale>
 | 
				
			||||||
 | 
					#include <codecvt>
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined( _WIN32 )
 | 
				
			||||||
 | 
					#include <windows.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined( OSX ) || defined( LINUX )
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose:  stricmp -> strcasecmp bridge
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					int stricmp( const char *pStr1, const char *pStr2 )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return strcasecmp( pStr1, pStr2 );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: strincmp -> strncasecmp bridge
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					int strnicmp( const char *pStr1, const char *pStr2, size_t unBufferLen )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return strncasecmp( pStr1, pStr2, unBufferLen );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose:
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					bool StringHasPrefix( const std::string & sString, const std::string & sPrefix )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return 0 == strnicmp( sString.c_str(), sPrefix.c_str(), sPrefix.length() );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool StringHasPrefixCaseSensitive( const std::string & sString, const std::string & sPrefix )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return 0 == strncmp( sString.c_str(), sPrefix.c_str(), sPrefix.length() );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool StringHasSuffix( const std::string &sString, const std::string &sSuffix )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						size_t cStrLen = sString.length();
 | 
				
			||||||
 | 
						size_t cSuffixLen = sSuffix.length();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( cSuffixLen > cStrLen )
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string sStringSuffix = sString.substr( cStrLen - cSuffixLen, cSuffixLen );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0 == stricmp( sStringSuffix.c_str(), sSuffix.c_str() );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool StringHasSuffixCaseSensitive( const std::string &sString, const std::string &sSuffix )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						size_t cStrLen = sString.length();
 | 
				
			||||||
 | 
						size_t cSuffixLen = sSuffix.length();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( cSuffixLen > cStrLen )
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string sStringSuffix = sString.substr( cStrLen - cSuffixLen, cSuffixLen );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0 == strncmp( sStringSuffix.c_str(), sSuffix.c_str(),cSuffixLen );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose:
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					typedef std::codecvt_utf8< wchar_t > convert_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string UTF16to8(const wchar_t * in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static std::wstring_convert< convert_type, wchar_t > s_converter;  // construction of this can be expensive (or even serialized) depending on locale
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						try
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return s_converter.to_bytes( in );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						catch ( ... )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return std::string();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string UTF16to8( const std::wstring & in ) { return UTF16to8( in.c_str() ); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::wstring UTF8to16(const char * in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static std::wstring_convert< convert_type, wchar_t > s_converter;  // construction of this can be expensive (or even serialized) depending on locale
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						try
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return s_converter.from_bytes( in );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						catch ( ... )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return std::wstring();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::wstring UTF8to16( const std::string & in ) { return UTF8to16( in.c_str() ); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Format string to std::string converter
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					std::string Format( const char *pchFormat, ... )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static constexpr size_t k_ulMaxStackString = 4096;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_list args;
 | 
				
			||||||
 | 
						char pchBuffer[k_ulMaxStackString];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_start( args, pchFormat );
 | 
				
			||||||
 | 
						int unSize = vsnprintf( pchBuffer, sizeof( pchBuffer ), pchFormat, args );
 | 
				
			||||||
 | 
						va_end( args );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Something went fairly wrong
 | 
				
			||||||
 | 
						if ( unSize < 0 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							//AssertMsg( false, "Format string parse failure" );
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Processing on the stack worked, success
 | 
				
			||||||
 | 
						if ( unSize < k_ulMaxStackString )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return pchBuffer;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// If processing on the stack failed, fallback to a dynamic allocation
 | 
				
			||||||
 | 
						std::vector< char > vecChar{};
 | 
				
			||||||
 | 
						vecChar.resize( unSize + 1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_start( args, pchFormat );
 | 
				
			||||||
 | 
						unSize = vsnprintf( vecChar.data(), vecChar.size(), pchFormat, args );
 | 
				
			||||||
 | 
						va_end( args );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Double check, just in case
 | 
				
			||||||
 | 
						if ( unSize < 0 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							//AssertMsg( false, "Format string parse failure" );
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return vecChar.data();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined( _WIN32 )
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Convert LPSTR in the default CodePage to UTF8
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					std::string DefaultACPtoUTF8( const char *pszStr )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ( GetACP() == CP_UTF8 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return pszStr;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							std::vector<wchar_t> vecBuf( strlen( pszStr ) + 1 ); // should be guaranteed to be enough
 | 
				
			||||||
 | 
							MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, pszStr, -1, vecBuf.data(), (int) vecBuf.size() );
 | 
				
			||||||
 | 
							return UTF16to8( vecBuf.data() );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// --------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose:
 | 
				
			||||||
 | 
					// --------------------------------------------------------------------
 | 
				
			||||||
 | 
					void strcpy_safe( char *pchBuffer, size_t unBufferSizeBytes, const char *pchSource )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						strncpy( pchBuffer, pchSource, unBufferSizeBytes - 1 );
 | 
				
			||||||
 | 
						pchBuffer[unBufferSizeBytes - 1] = '\0';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// --------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: converts a string to upper case
 | 
				
			||||||
 | 
					// --------------------------------------------------------------------
 | 
				
			||||||
 | 
					std::string StringToUpper( const std::string & sString )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string sOut;
 | 
				
			||||||
 | 
						sOut.reserve( sString.size() + 1 );
 | 
				
			||||||
 | 
						for( std::string::const_iterator i = sString.begin(); i != sString.end(); i++ )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							sOut.push_back( (char)toupper( *i ) );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sOut;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// --------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: converts a string to lower case
 | 
				
			||||||
 | 
					// --------------------------------------------------------------------
 | 
				
			||||||
 | 
					std::string StringToLower( const std::string & sString )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string sOut;
 | 
				
			||||||
 | 
						sOut.reserve( sString.size() + 1 );
 | 
				
			||||||
 | 
						for( std::string::const_iterator i = sString.begin(); i != sString.end(); i++ )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							sOut.push_back( (char)tolower( *i ) );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sOut;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t ReturnStdString( const std::string & sValue, char *pchBuffer, uint32_t unBufferLen )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t unLen = (uint32_t)sValue.length() + 1;
 | 
				
			||||||
 | 
						if( !pchBuffer || !unBufferLen )
 | 
				
			||||||
 | 
							return unLen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if( unBufferLen < unLen )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							pchBuffer[0] = '\0';
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							memcpy( pchBuffer, sValue.c_str(), unLen );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return unLen;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns a std::string from a uint64_t */
 | 
				
			||||||
 | 
					std::string Uint64ToString( uint64_t ulValue )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char buf[ 22 ];
 | 
				
			||||||
 | 
					#if defined( _WIN32 )
 | 
				
			||||||
 | 
						sprintf_s( buf, "%llu", ulValue );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    snprintf( buf, sizeof( buf ), "%llu", (long long unsigned int ) ulValue );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						return buf;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** returns a uint64_t from a string */
 | 
				
			||||||
 | 
					uint64_t StringToUint64( const std::string & sValue )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return strtoull( sValue.c_str(), NULL, 0 );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Helper for converting a numeric value to a hex digit, value should be 0-15.
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					char cIntToHexDigit( int nValue )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						//Assert( nValue >= 0 && nValue <= 15 );
 | 
				
			||||||
 | 
						return "0123456789ABCDEF"[ nValue & 15 ];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Helper for converting a hex char value to numeric, return -1 if the char
 | 
				
			||||||
 | 
					//          is not a valid hex digit.
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					int iHexCharToInt( char cValue )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int32_t iValue = cValue;
 | 
				
			||||||
 | 
						if ( (uint32_t)( iValue - '0' ) < 10 )
 | 
				
			||||||
 | 
							return iValue - '0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						iValue |= 0x20;
 | 
				
			||||||
 | 
						if ( (uint32_t)( iValue - 'a' ) < 6 )
 | 
				
			||||||
 | 
							return iValue - 'a' + 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: These define the set of characters to filter for components (which
 | 
				
			||||||
 | 
					//			need all the escaping we can muster) vs. paths (which don't want
 | 
				
			||||||
 | 
					//			/ and : escaped so we don't break less compliant URL handling code.
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					static bool CharNeedsEscape_Component( const char c )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (!(c >= 'a' && c <= 'z') && !(c >= 'A' && c <= 'Z') && !(c >= '0' && c <= '9')
 | 
				
			||||||
 | 
							&& c != '-' && c != '_' && c != '.');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static bool CharNeedsEscape_FullPath( const char c )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (!(c >= 'a' && c <= 'z') && !(c >= 'A' && c <= 'Z') && !(c >= '0' && c <= '9')
 | 
				
			||||||
 | 
							&& c != '-' && c != '_' && c != '.' && c != '/' && c != ':' );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Internal implementation of encode, works in the strict RFC manner, or
 | 
				
			||||||
 | 
					//          with spaces turned to + like HTML form encoding.
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					void V_URLEncodeInternal( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen, 
 | 
				
			||||||
 | 
						bool bUsePlusForSpace, std::function< bool(const char)> fnNeedsEscape )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						//AssertMsg( nDestLen > 3*nSourceLen, "Target buffer for V_URLEncode should be 3x source length, plus one for terminating null\n" );
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						int iDestPos = 0;
 | 
				
			||||||
 | 
						for ( int i=0; i < nSourceLen; ++i )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// worst case we need 3 additional chars
 | 
				
			||||||
 | 
							if( (iDestPos+3) > nDestLen  )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								pchDest[0] = '\0';
 | 
				
			||||||
 | 
					//			AssertMsg( false, "Target buffer too short\n" );
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// We allow only a-z, A-Z, 0-9, period, underscore, and hyphen to pass through unescaped.
 | 
				
			||||||
 | 
							// These are the characters allowed by both the original RFC 1738 and the latest RFC 3986.
 | 
				
			||||||
 | 
							// Current specs also allow '~', but that is forbidden under original RFC 1738.
 | 
				
			||||||
 | 
							if ( fnNeedsEscape( pchSource[i] ) )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if ( bUsePlusForSpace && pchSource[i] == ' ' )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									pchDest[iDestPos++] = '+';
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									pchDest[iDestPos++] = '%';
 | 
				
			||||||
 | 
									uint8_t iValue = pchSource[i];
 | 
				
			||||||
 | 
									if ( iValue == 0 )
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										pchDest[iDestPos++] = '0';
 | 
				
			||||||
 | 
										pchDest[iDestPos++] = '0';
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										char cHexDigit1 = cIntToHexDigit( iValue % 16 );
 | 
				
			||||||
 | 
										iValue /= 16;
 | 
				
			||||||
 | 
										char cHexDigit2 = cIntToHexDigit( iValue );
 | 
				
			||||||
 | 
										pchDest[iDestPos++] = cHexDigit2;
 | 
				
			||||||
 | 
										pchDest[iDestPos++] = cHexDigit1;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								pchDest[iDestPos++] = pchSource[i];
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if( (iDestPos+1) > nDestLen )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							pchDest[0] = '\0';
 | 
				
			||||||
 | 
							//AssertMsg( false, "Target buffer too short to terminate\n" );
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Null terminate
 | 
				
			||||||
 | 
						pchDest[iDestPos++] = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Internal implementation of decode, works in the strict RFC manner, or
 | 
				
			||||||
 | 
					//          with spaces turned to + like HTML form encoding.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//			Returns the amount of space used in the output buffer.
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					size_t V_URLDecodeInternal( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen, bool bUsePlusForSpace )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ( nDecodeDestLen < nEncodedSourceLen )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							//AssertMsg( false, "V_URLDecode needs a dest buffer at least as large as the source" );
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int iDestPos = 0;
 | 
				
			||||||
 | 
						for( int i=0; i < nEncodedSourceLen; ++i )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if ( bUsePlusForSpace && pchEncodedSource[i] == '+' )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								pchDecodeDest[ iDestPos++ ] = ' ';
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if ( pchEncodedSource[i] == '%' )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								// Percent signifies an encoded value, look ahead for the hex code, convert to numeric, and use that
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// First make sure we have 2 more chars
 | 
				
			||||||
 | 
								if ( i < nEncodedSourceLen - 2 )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									char cHexDigit1 = pchEncodedSource[i+1];
 | 
				
			||||||
 | 
									char cHexDigit2 = pchEncodedSource[i+2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// Turn the chars into a hex value, if they are not valid, then we'll
 | 
				
			||||||
 | 
									// just place the % and the following two chars direct into the string,
 | 
				
			||||||
 | 
									// even though this really shouldn't happen, who knows what bad clients
 | 
				
			||||||
 | 
									// may do with encoding.
 | 
				
			||||||
 | 
									bool bValid = false;
 | 
				
			||||||
 | 
									int iValue = iHexCharToInt( cHexDigit1 );
 | 
				
			||||||
 | 
									if ( iValue != -1 )
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										iValue *= 16;
 | 
				
			||||||
 | 
										int iValue2 = iHexCharToInt( cHexDigit2 );
 | 
				
			||||||
 | 
										if ( iValue2 != -1 )
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											iValue += iValue2;
 | 
				
			||||||
 | 
											pchDecodeDest[ iDestPos++ ] = (char)iValue;
 | 
				
			||||||
 | 
											bValid = true;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if ( !bValid )
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										pchDecodeDest[ iDestPos++ ] = '%';
 | 
				
			||||||
 | 
										pchDecodeDest[ iDestPos++ ] = cHexDigit1;
 | 
				
			||||||
 | 
										pchDecodeDest[ iDestPos++ ] = cHexDigit2;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Skip ahead
 | 
				
			||||||
 | 
								i += 2;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								pchDecodeDest[ iDestPos++ ] = pchEncodedSource[i];
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// We may not have extra room to NULL terminate, since this can be used on raw data, but if we do
 | 
				
			||||||
 | 
						// go ahead and do it as this can avoid bugs.
 | 
				
			||||||
 | 
						if ( iDestPos < nDecodeDestLen )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							pchDecodeDest[iDestPos] = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (size_t)iDestPos;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Encodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2.  
 | 
				
			||||||
 | 
					//          This version of the call isn't a strict RFC implementation, but uses + for space as is
 | 
				
			||||||
 | 
					//          the standard in HTML form encoding, despite it not being part of the RFC.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//          Dest buffer should be at least as large as source buffer to guarantee room for decode.
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					void V_URLEncode( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return V_URLEncodeInternal( pchDest, nDestLen, pchSource, nSourceLen, true, CharNeedsEscape_Component );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void V_URLEncodeNoPlusForSpace( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return V_URLEncodeInternal( pchDest, nDestLen, pchSource, nSourceLen, false, CharNeedsEscape_Component );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void V_URLEncodeFullPath( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return V_URLEncodeInternal( pchDest, nDestLen, pchSource, nSourceLen, false, CharNeedsEscape_FullPath );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Decodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2.  
 | 
				
			||||||
 | 
					//          This version of the call isn't a strict RFC implementation, but uses + for space as is
 | 
				
			||||||
 | 
					//          the standard in HTML form encoding, despite it not being part of the RFC.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//          Dest buffer should be at least as large as source buffer to guarantee room for decode.
 | 
				
			||||||
 | 
					//			Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed.
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					size_t V_URLDecode( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return V_URLDecodeInternal( pchDecodeDest, nDecodeDestLen, pchEncodedSource, nEncodedSourceLen, true );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t V_URLDecodeNoPlusForSpace( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return V_URLDecodeInternal( pchDecodeDest, nDecodeDestLen, pchEncodedSource, nEncodedSourceLen, false );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					void V_StripExtension( std::string &in )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Find the last dot. If it's followed by a dot or a slash, then it's part of a 
 | 
				
			||||||
 | 
						// directory specifier like ../../somedir/./blah.
 | 
				
			||||||
 | 
						std::string::size_type test = in.rfind( '.' );
 | 
				
			||||||
 | 
						if ( test != std::string::npos )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// This handles things like ".\blah" or "c:\my@email.com\abc\def\geh"
 | 
				
			||||||
 | 
							// Which would otherwise wind up with "" and "c:\my@email", respectively.
 | 
				
			||||||
 | 
							if ( in.rfind( '\\' ) < test && in.rfind( '/' ) < test )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								in.resize( test );
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Tokenizes a string into a vector of strings
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					std::vector<std::string> TokenizeString( const std::string & sString, char cToken )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::vector<std::string> vecStrings;
 | 
				
			||||||
 | 
						std::istringstream stream( sString );
 | 
				
			||||||
 | 
						std::string s;
 | 
				
			||||||
 | 
						while ( std::getline( stream, s, cToken ) )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							vecStrings.push_back( s );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( !sString.empty() && sString.back() == cToken )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							vecStrings.push_back( "" );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return vecStrings;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Repairs a should-be-UTF-8 string to a for-sure-is-UTF-8 string, plus return boolean if we subbed in '?' somewhere
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					bool RepairUTF8( const char *pbegin, const char *pend, std::string & sOutputUtf8 )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						typedef std::codecvt_utf8<char32_t> facet_type;
 | 
				
			||||||
 | 
						facet_type myfacet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::mbstate_t mystate = std::mbstate_t();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sOutputUtf8.clear();
 | 
				
			||||||
 | 
						sOutputUtf8.reserve( pend - pbegin );
 | 
				
			||||||
 | 
						bool bSqueakyClean = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const char *pmid = pbegin;
 | 
				
			||||||
 | 
						while ( pmid != pend )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							bool bHasError = false;
 | 
				
			||||||
 | 
							bool bHasValidData = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							char32_t out = 0xdeadbeef, *pout;
 | 
				
			||||||
 | 
							pbegin = pmid;
 | 
				
			||||||
 | 
							switch ( myfacet.in( mystate, pbegin, pend, pmid, &out, &out + 1, pout ) )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							case facet_type::ok:
 | 
				
			||||||
 | 
								bHasValidData = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case facet_type::noconv:
 | 
				
			||||||
 | 
								// unexpected! always converting type
 | 
				
			||||||
 | 
								bSqueakyClean = false;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case facet_type::partial:
 | 
				
			||||||
 | 
								bHasError = pbegin == pmid;
 | 
				
			||||||
 | 
								if ( bHasError )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									bSqueakyClean = false;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									bHasValidData = true;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case facet_type::error:
 | 
				
			||||||
 | 
								bHasError = true;
 | 
				
			||||||
 | 
								bSqueakyClean = false;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ( bHasValidData )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								// could convert back, but no need
 | 
				
			||||||
 | 
								for ( const char *p = pbegin; p != pmid; ++p )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									sOutputUtf8 += *p;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ( bHasError )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								sOutputUtf8 += '?';
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ( pmid == pbegin )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								pmid++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return bSqueakyClean;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Repairs a should-be-UTF-8 string to a for-sure-is-UTF-8 string, plus return boolean if we subbed in '?' somewhere
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					bool RepairUTF8( const std::string & sInputUtf8, std::string & sOutputUtf8 )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return RepairUTF8( sInputUtf8.data(), sInputUtf8.data() + sInputUtf8.size(), sOutputUtf8 );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										154
									
								
								contrib/openvr/src/vrcommon/strtools_public.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,154 @@
 | 
				
			||||||
 | 
					//========= Copyright Valve Corporation ============//
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** returns true if the string has the prefix */
 | 
				
			||||||
 | 
					bool StringHasPrefix( const std::string & sString, const std::string & sPrefix );
 | 
				
			||||||
 | 
					bool StringHasPrefixCaseSensitive( const std::string & sString, const std::string & sPrefix );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** returns if the string has the suffix */
 | 
				
			||||||
 | 
					bool StringHasSuffix( const std::string &sString, const std::string &sSuffix );
 | 
				
			||||||
 | 
					bool StringHasSuffixCaseSensitive( const std::string &sString, const std::string &sSuffix );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** converts a UTF-16 string to a UTF-8 string */
 | 
				
			||||||
 | 
					std::string UTF16to8( const wchar_t * in );
 | 
				
			||||||
 | 
					std::string UTF16to8( const std::wstring & in );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** converts a UTF-8 string to a UTF-16 string */
 | 
				
			||||||
 | 
					std::wstring UTF8to16(const char * in);
 | 
				
			||||||
 | 
					std::wstring UTF8to16( const std::string & in );
 | 
				
			||||||
 | 
					#define Utf16FromUtf8 UTF8to16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined( _WIN32 )
 | 
				
			||||||
 | 
					std::string DefaultACPtoUTF8( const char *pszStr );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Repairs a should-be-UTF-8 string to a for-sure-is-UTF-8 string, plus return boolean if we subbed in '?' somewhere */
 | 
				
			||||||
 | 
					bool RepairUTF8( const char *begin, const char *end, std::string & sOutputUtf8 );
 | 
				
			||||||
 | 
					bool RepairUTF8( const std::string & sInputUtf8, std::string & sOutputUtf8 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** safely copy a string into a buffer */
 | 
				
			||||||
 | 
					void strcpy_safe( char *pchBuffer, size_t unBufferSizeBytes, const char *pchSource );
 | 
				
			||||||
 | 
					template< size_t bufferSize >
 | 
				
			||||||
 | 
					void strcpy_safe( char (& buffer) [ bufferSize ], const char *pchSource ) 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						strcpy_safe( buffer, bufferSize, pchSource );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Turns printf-style format args into a std::string */
 | 
				
			||||||
 | 
					std::string Format( const char *pchFormat, ... );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** converts a string to upper case */
 | 
				
			||||||
 | 
					std::string StringToUpper( const std::string & sString );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** converts a string to lower case */
 | 
				
			||||||
 | 
					std::string StringToLower( const std::string & sString );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// we stricmp (from WIN) but it isn't POSIX - OSX/LINUX have strcasecmp so just inline bridge to it
 | 
				
			||||||
 | 
					#if defined( OSX ) || defined( LINUX )
 | 
				
			||||||
 | 
					int stricmp(const char *pStr1, const char *pStr2);
 | 
				
			||||||
 | 
					#ifndef _stricmp
 | 
				
			||||||
 | 
					#define _stricmp stricmp
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					int strnicmp( const char *pStr1, const char *pStr2, size_t unBufferLen );
 | 
				
			||||||
 | 
					#ifndef _strnicmp
 | 
				
			||||||
 | 
					#define _strnicmp strnicmp
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _vsnprintf_s
 | 
				
			||||||
 | 
					#define _vsnprintf_s vsnprintf
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define _TRUNCATE ((size_t)-1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined( OSX )
 | 
				
			||||||
 | 
					// behaviors ensure NULL-termination at least as well as _TRUNCATE does, but
 | 
				
			||||||
 | 
					// wcsncpy_s/strncpy_s can non-NULL-terminate, wcslcpy/strlcpy can not.
 | 
				
			||||||
 | 
					inline errno_t wcsncpy_s(wchar_t *strDest, size_t numberOfElements, const wchar_t *strSource, size_t count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return wcslcpy(strDest, strSource, numberOfElements);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline errno_t strncpy_s(char *strDest, size_t numberOfElements, const char *strSource, size_t count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return strlcpy(strDest, strSource, numberOfElements);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined( LINUX )
 | 
				
			||||||
 | 
					// this implementation does not return whether or not the destination was 
 | 
				
			||||||
 | 
					// truncated, but that is straightforward to fix if anybody actually needs the
 | 
				
			||||||
 | 
					// return code. 
 | 
				
			||||||
 | 
					#include "string.h"
 | 
				
			||||||
 | 
					inline void wcsncpy_s(wchar_t *strDest, size_t numberOfElements, const wchar_t *strSource, size_t count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						wcsncpy(strDest, strSource, numberOfElements);
 | 
				
			||||||
 | 
						strDest[numberOfElements-1] = '\0';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline void strncpy_s(char *strDest, size_t numberOfElements, const char *strSource, size_t count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						strncpy(strDest, strSource, numberOfElements);
 | 
				
			||||||
 | 
						strDest[numberOfElements-1] = '\0';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined( _WIN32 ) && _MSC_VER < 1800
 | 
				
			||||||
 | 
					inline uint64_t strtoull(const char *str, char **endptr, int base) { return _strtoui64( str, endptr, base ); }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Handles copying a std::string into a buffer as would be provided in an API */
 | 
				
			||||||
 | 
					uint32_t ReturnStdString( const std::string & sValue, char *pchBuffer, uint32_t unBufferLen );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns a std::string from a uint64_t */
 | 
				
			||||||
 | 
					std::string Uint64ToString( uint64_t ulValue );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** returns a uint64_t from a string */
 | 
				
			||||||
 | 
					uint64_t StringToUint64( const std::string & sValue );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Encodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2.  
 | 
				
			||||||
 | 
					//          This version of the call isn't a strict RFC implementation, but uses + for space as is
 | 
				
			||||||
 | 
					//          the standard in HTML form encoding, despite it not being part of the RFC.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//          Dest buffer should be at least as large as source buffer to guarantee room for decode.
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					void V_URLEncode( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Same as V_URLEncode, but without plus for space. */
 | 
				
			||||||
 | 
					void V_URLEncodeNoPlusForSpace( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Same as V_URLEncodeNoPlusForSpace, but without escaping / and : */
 | 
				
			||||||
 | 
					void V_URLEncodeFullPath( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Decodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2.  
 | 
				
			||||||
 | 
					//          This version of the call isn't a strict RFC implementation, but uses + for space as is
 | 
				
			||||||
 | 
					//          the standard in HTML form encoding, despite it not being part of the RFC.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//          Dest buffer should be at least as large as source buffer to guarantee room for decode.
 | 
				
			||||||
 | 
					//			Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed.
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					size_t V_URLDecode( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Same as V_URLDecode, but without plus for space. */
 | 
				
			||||||
 | 
					size_t V_URLDecodeNoPlusForSpace( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: strip extension from a path
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					void V_StripExtension( std::string &in );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Tokenizes a string into a vector of strings */
 | 
				
			||||||
 | 
					std::vector<std::string> TokenizeString( const std::string & sString, char cToken );
 | 
				
			||||||
							
								
								
									
										483
									
								
								contrib/openvr/src/vrcommon/vrpathregistry_public.cpp
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,483 @@
 | 
				
			||||||
 | 
					//========= Copyright Valve Corporation ============//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <vrcommon/vrpathregistry_public.h>
 | 
				
			||||||
 | 
					#include <json/json.h>
 | 
				
			||||||
 | 
					#include <vrcommon/pathtools_public.h>
 | 
				
			||||||
 | 
					#include <vrcommon/envvartools_public.h>
 | 
				
			||||||
 | 
					#include <vrcommon/strtools_public.h>
 | 
				
			||||||
 | 
					#include <vrcommon/dirtools_public.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					#include <windows.h>
 | 
				
			||||||
 | 
					#include <shlobj.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef GetEnvironmentVariable
 | 
				
			||||||
 | 
					#elif defined OSX
 | 
				
			||||||
 | 
					#include <Foundation/Foundation.h>
 | 
				
			||||||
 | 
					#include <AppKit/AppKit.h>
 | 
				
			||||||
 | 
					#elif defined(LINUX)
 | 
				
			||||||
 | 
					#include <dlfcn.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <algorithm>
 | 
				
			||||||
 | 
					#include <sstream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef VRLog
 | 
				
			||||||
 | 
						#if defined( __MINGW32__ )
 | 
				
			||||||
 | 
							#define VRLog(args...)		fprintf(stderr, args)
 | 
				
			||||||
 | 
						#elif defined( WIN32 )
 | 
				
			||||||
 | 
							#define VRLog(fmt, ...)		fprintf(stderr, fmt, __VA_ARGS__)
 | 
				
			||||||
 | 
						#else
 | 
				
			||||||
 | 
							#define VRLog(args...)		fprintf(stderr, args)
 | 
				
			||||||
 | 
						#endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns the root of the directory the system wants us to store user config data in */
 | 
				
			||||||
 | 
					static std::string GetAppSettingsPath()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
						WCHAR rwchPath[MAX_PATH];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if( !SUCCEEDED( SHGetFolderPathW( NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, rwchPath ) ) )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Convert the path to UTF-8 and store in the output
 | 
				
			||||||
 | 
						std::string sUserPath = UTF16to8( rwchPath );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sUserPath;
 | 
				
			||||||
 | 
					#elif defined( OSX )
 | 
				
			||||||
 | 
						std::string sSettingsDir;
 | 
				
			||||||
 | 
						@autoreleasepool {
 | 
				
			||||||
 | 
							// Search for the path
 | 
				
			||||||
 | 
							NSArray *paths = NSSearchPathForDirectoriesInDomains( NSApplicationSupportDirectory, NSUserDomainMask, YES );
 | 
				
			||||||
 | 
							if ( [paths count] == 0 )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return "";
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							NSString *resolvedPath = [paths objectAtIndex:0];
 | 
				
			||||||
 | 
							resolvedPath = [resolvedPath stringByAppendingPathComponent: @"OpenVR"];
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if ( ![[NSFileManager defaultManager] createDirectoryAtPath: resolvedPath withIntermediateDirectories:YES attributes:nil error:nil] )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return "";
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							sSettingsDir.assign( [resolvedPath UTF8String] );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return sSettingsDir;
 | 
				
			||||||
 | 
					#elif defined( LINUX )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// As defined by XDG Base Directory Specification 
 | 
				
			||||||
 | 
						// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const char *pchHome = getenv("XDG_CONFIG_HOME");
 | 
				
			||||||
 | 
						if ( ( pchHome != NULL) && ( pchHome[0] != '\0' ) )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return pchHome;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// XDG_CONFIG_HOME is not defined, use ~/.config instead
 | 
				
			||||||
 | 
						// 
 | 
				
			||||||
 | 
						pchHome = getenv( "HOME" );
 | 
				
			||||||
 | 
						if ( pchHome == NULL )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string sUserPath( pchHome );
 | 
				
			||||||
 | 
						sUserPath = Path_Join( sUserPath, ".config" );
 | 
				
			||||||
 | 
						return sUserPath;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						#warning "Unsupported platform"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Constructor
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					CVRPathRegistry_Public::CVRPathRegistry_Public()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Computes the registry filename
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					std::string CVRPathRegistry_Public::GetOpenVRConfigPath()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string sConfigPath = GetAppSettingsPath();
 | 
				
			||||||
 | 
						if( sConfigPath.empty() )
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined( _WIN32 ) || defined( LINUX )
 | 
				
			||||||
 | 
						sConfigPath = Path_Join( sConfigPath, "openvr" );
 | 
				
			||||||
 | 
					#elif defined ( OSX ) 
 | 
				
			||||||
 | 
						sConfigPath = Path_Join( sConfigPath, ".openvr" );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						#warning "Unsupported platform"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						sConfigPath = Path_FixSlashes( sConfigPath );
 | 
				
			||||||
 | 
						return sConfigPath;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose:
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					std::string CVRPathRegistry_Public::GetVRPathRegistryFilename()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string sOverridePath = GetEnvironmentVariable( "VR_PATHREG_OVERRIDE" );
 | 
				
			||||||
 | 
						if ( !sOverridePath.empty() )
 | 
				
			||||||
 | 
							return sOverridePath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string sPath = GetOpenVRConfigPath();
 | 
				
			||||||
 | 
						if ( sPath.empty() )
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined( _WIN32 )
 | 
				
			||||||
 | 
						sPath = Path_Join( sPath, "openvrpaths.vrpath" );
 | 
				
			||||||
 | 
					#elif defined ( POSIX ) 
 | 
				
			||||||
 | 
						sPath = Path_Join( sPath, "openvrpaths.vrpath" );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						#error "Unsupported platform"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						sPath = Path_FixSlashes( sPath );
 | 
				
			||||||
 | 
						return sPath;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Converts JSON to a history array
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					static void ParseStringListFromJson( std::vector< std::string > *pvecHistory, const Json::Value & root, const char *pchArrayName )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if( !root.isMember( pchArrayName ) )
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const Json::Value & arrayNode = root[ pchArrayName ];
 | 
				
			||||||
 | 
						if( !arrayNode )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							VRLog( "VR Path Registry node %s is not an array\n", pchArrayName );
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pvecHistory->clear();
 | 
				
			||||||
 | 
						pvecHistory->reserve( arrayNode.size() );
 | 
				
			||||||
 | 
						for( uint32_t unIndex = 0; unIndex < arrayNode.size(); unIndex++ )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							std::string sPath( arrayNode[ unIndex ].asString() );
 | 
				
			||||||
 | 
							pvecHistory->push_back( sPath );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Converts a history array to JSON
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					static void StringListToJson( const std::vector< std::string > & vecHistory, Json::Value & root, const char *pchArrayName )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Json::Value & arrayNode = root[ pchArrayName ];
 | 
				
			||||||
 | 
						for( auto i = vecHistory.begin(); i != vecHistory.end(); i++ )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							arrayNode.append( *i );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose:
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					bool CVRPathRegistry_Public::ToJsonString( std::string &sJsonString )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string sRegPath = GetVRPathRegistryFilename();
 | 
				
			||||||
 | 
						if( sRegPath.empty() )
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						std::string sRegistryContents = Path_ReadTextFile( sRegPath );
 | 
				
			||||||
 | 
						if( sRegistryContents.empty() )
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sJsonString = sRegistryContents;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Loads the config file from its well known location
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					bool CVRPathRegistry_Public::BLoadFromFile( std::string *psLoadError )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string sRegPath = GetVRPathRegistryFilename();
 | 
				
			||||||
 | 
						if( sRegPath.empty() )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if ( psLoadError )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*psLoadError = "Unable to determine VR Path Registry filename";
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string sRegistryContents = Path_ReadTextFile( sRegPath );
 | 
				
			||||||
 | 
						if( sRegistryContents.empty() )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if ( psLoadError )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*psLoadError = "Unable to read VR Path Registry from " + sRegPath;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Json::Value root;
 | 
				
			||||||
 | 
						Json::CharReaderBuilder builder;
 | 
				
			||||||
 | 
						std::istringstream istream( sRegistryContents );
 | 
				
			||||||
 | 
						std::string sErrors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						try {
 | 
				
			||||||
 | 
							if ( !parseFromStream( builder, istream, &root, &sErrors ) )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if ( psLoadError )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									*psLoadError = "Unable to parse " + sRegPath + ": " + sErrors;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ParseStringListFromJson( &m_vecRuntimePath, root, "runtime" );
 | 
				
			||||||
 | 
							ParseStringListFromJson( &m_vecConfigPath, root, "config" );
 | 
				
			||||||
 | 
							ParseStringListFromJson( &m_vecLogPath, root, "log" );
 | 
				
			||||||
 | 
							if ( root.isMember( "external_drivers" ) && root["external_drivers"].isArray() )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								ParseStringListFromJson( &m_vecExternalDrivers, root, "external_drivers" );
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						catch ( ... )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if ( psLoadError )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*psLoadError = "Unable to parse " + sRegPath + ": exception thrown in JSON library";
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Saves the config file to its well known location
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					bool CVRPathRegistry_Public::BSaveToFile() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string sRegPath = GetVRPathRegistryFilename();
 | 
				
			||||||
 | 
						if( sRegPath.empty() )
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						Json::Value root;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						root[ "version" ] = 1;
 | 
				
			||||||
 | 
						root[ "jsonid" ] = "vrpathreg";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						StringListToJson( m_vecRuntimePath, root, "runtime" );
 | 
				
			||||||
 | 
						StringListToJson( m_vecConfigPath, root, "config" );
 | 
				
			||||||
 | 
						StringListToJson( m_vecLogPath, root, "log" );
 | 
				
			||||||
 | 
						StringListToJson( m_vecExternalDrivers, root, "external_drivers" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Json::StreamWriterBuilder builder;
 | 
				
			||||||
 | 
						std::string sRegistryContents = Json::writeString( builder, root );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// make sure the directory we're writing into actually exists
 | 
				
			||||||
 | 
						std::string sRegDirectory = Path_StripFilename( sRegPath );
 | 
				
			||||||
 | 
						if( !BCreateDirectoryRecursive( sRegDirectory.c_str() ) )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							VRLog( "Unable to create path registry directory %s\n", sRegDirectory.c_str() );
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if( !Path_WriteStringToTextFile( sRegPath, sRegistryContents.c_str() ) )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							VRLog( "Unable to write VR path registry to %s\n", sRegPath.c_str() );
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Returns the current runtime path or NULL if no path is configured.
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					std::string CVRPathRegistry_Public::GetRuntimePath() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if( m_vecRuntimePath.empty() )
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return m_vecRuntimePath.front().c_str();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Returns the current config path or NULL if no path is configured.
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					std::string CVRPathRegistry_Public::GetConfigPath() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if( m_vecConfigPath.empty() )
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return m_vecConfigPath.front().c_str();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Returns the current log path or NULL if no path is configured.
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					std::string CVRPathRegistry_Public::GetLogPath() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if( m_vecLogPath.empty() )
 | 
				
			||||||
 | 
							return "";
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return m_vecLogPath.front().c_str();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// Purpose: Returns paths using the path registry and the provided override 
 | 
				
			||||||
 | 
					//			values. Pass NULL for any paths you don't care about.
 | 
				
			||||||
 | 
					// ---------------------------------------------------------------------------
 | 
				
			||||||
 | 
					bool CVRPathRegistry_Public::GetPaths( std::string *psRuntimePath, std::string *psConfigPath, std::string *psLogPath, const char *pchConfigPathOverride, const char *pchLogPathOverride, std::vector<std::string> *pvecExternalDrivers )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string sLoadError;
 | 
				
			||||||
 | 
						CVRPathRegistry_Public pathReg;
 | 
				
			||||||
 | 
						bool bLoadedRegistry = pathReg.BLoadFromFile( &sLoadError );
 | 
				
			||||||
 | 
						int nCountEnvironmentVariables = 0;
 | 
				
			||||||
 | 
						int nRequestedPaths = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if( psRuntimePath )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							nRequestedPaths++;
 | 
				
			||||||
 | 
							if ( GetEnvironmentVariable( k_pchRuntimeOverrideVar ).length() != 0 )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*psRuntimePath = GetEnvironmentVariable( k_pchRuntimeOverrideVar );
 | 
				
			||||||
 | 
								nCountEnvironmentVariables++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if( !pathReg.GetRuntimePath().empty() )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*psRuntimePath = pathReg.GetRuntimePath();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*psRuntimePath = "";
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if( psConfigPath )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							nRequestedPaths++;
 | 
				
			||||||
 | 
							if ( GetEnvironmentVariable( k_pchConfigOverrideVar ).length() != 0 )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*psConfigPath = GetEnvironmentVariable( k_pchConfigOverrideVar );
 | 
				
			||||||
 | 
								nCountEnvironmentVariables++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if( pchConfigPathOverride )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*psConfigPath = pchConfigPathOverride;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if( !pathReg.GetConfigPath().empty() )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*psConfigPath = pathReg.GetConfigPath();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*psConfigPath = "";
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if( psLogPath )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							nRequestedPaths++;
 | 
				
			||||||
 | 
							if ( GetEnvironmentVariable( k_pchLogOverrideVar ).length() != 0 )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*psLogPath = GetEnvironmentVariable( k_pchLogOverrideVar );
 | 
				
			||||||
 | 
								nCountEnvironmentVariables++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if( pchLogPathOverride )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*psLogPath = pchLogPathOverride;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if( !pathReg.GetLogPath().empty() )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*psLogPath = pathReg.GetLogPath();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*psLogPath = "";
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( pvecExternalDrivers )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							*pvecExternalDrivers = pathReg.m_vecExternalDrivers;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( nCountEnvironmentVariables == nRequestedPaths )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// all three environment variables were set, so we don't need the physical file
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if( !bLoadedRegistry )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							VRLog( "%s\n", sLoadError.c_str() );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return bLoadedRegistry;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					uint32_t CVRPathRegistry_Public::GetSteamAppId()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if !defined( REL_BRANCH_ONLY )
 | 
				
			||||||
 | 
						uint32_t nSteamAppId = k_unSteamVRMainAppId;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						uint32_t nSteamAppId = k_unSteamVRAppId;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nSteamAppId;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					bool CVRPathRegistry_Public::IsSteamVRMain()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined( REL_BRANCH_ONLY )
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					uint32_t CVRPathRegistry_Public::InitSteamAppId()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t nSteamAppId = CVRPathRegistry_Public::GetSteamAppId();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Forcefully setting to what it should be before SteamAPI_Init() since SteamVR is more often
 | 
				
			||||||
 | 
						// started as child processes of the game app and otherwise Steam then considers us as the
 | 
				
			||||||
 | 
						// wrong app id.
 | 
				
			||||||
 | 
						SetEnvironmentVariable( "SteamAppId", std::to_string( nSteamAppId ).c_str() );
 | 
				
			||||||
 | 
						SetEnvironmentVariable( "SteamGameId", std::to_string( nSteamAppId ).c_str() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nSteamAppId;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										52
									
								
								contrib/openvr/src/vrcommon/vrpathregistry_public.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,52 @@
 | 
				
			||||||
 | 
					//========= Copyright Valve Corporation ============//
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *k_pchRuntimeOverrideVar = "VR_OVERRIDE";
 | 
				
			||||||
 | 
					static const char *k_pchConfigOverrideVar = "VR_CONFIG_PATH";
 | 
				
			||||||
 | 
					static const char *k_pchLogOverrideVar = "VR_LOG_PATH";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const uint32_t k_unSteamVRAppId = 250820;
 | 
				
			||||||
 | 
					static const uint32_t k_unSteamVRMainAppId = 330050;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CVRPathRegistry_Public
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						static std::string GetVRPathRegistryFilename();
 | 
				
			||||||
 | 
						static std::string GetOpenVRConfigPath();
 | 
				
			||||||
 | 
						static uint32_t GetSteamAppId();
 | 
				
			||||||
 | 
						static bool IsSteamVRMain();
 | 
				
			||||||
 | 
						static uint32_t InitSteamAppId();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						CVRPathRegistry_Public();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** Returns paths using the path registry and the provided override values. Pass NULL for any paths you don't care about. 
 | 
				
			||||||
 | 
						* Returns false if the path registry could not be read. Valid paths might still be returned based on environment variables. */
 | 
				
			||||||
 | 
						static bool GetPaths( std::string *psRuntimePath, std::string *psConfigPath, std::string *psLogPath, const char *pchConfigPathOverride, const char *pchLogPathOverride, std::vector<std::string> *pvecExternalDrivers = NULL );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool BLoadFromFile( std::string *psError = nullptr );
 | 
				
			||||||
 | 
						bool BSaveToFile() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool ToJsonString( std::string &sJsonString );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// methods to get the current values
 | 
				
			||||||
 | 
						std::string GetRuntimePath() const;
 | 
				
			||||||
 | 
						std::string GetConfigPath() const;
 | 
				
			||||||
 | 
						std::string GetLogPath() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
						typedef std::vector< std::string > StringVector_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// index 0 is the current setting
 | 
				
			||||||
 | 
						StringVector_t m_vecRuntimePath;
 | 
				
			||||||
 | 
						StringVector_t m_vecLogPath;
 | 
				
			||||||
 | 
						StringVector_t m_vecConfigPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// full list of external drivers
 | 
				
			||||||
 | 
						StringVector_t m_vecExternalDrivers;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										1
									
								
								contrib/quirc
									
										
									
									
									
										Submodule
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					Subproject commit 9c0f555acb2531d818f2c405044418fc75379fb2
 | 
				
			||||||
| 
						 | 
					@ -5,16 +5,13 @@ set(CMAKE_AUTOUIC ON)
 | 
				
			||||||
# pthread
 | 
					# pthread
 | 
				
			||||||
find_package(Threads REQUIRED)
 | 
					find_package(Threads REQUIRED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui Network Svg Xml WebSockets)
 | 
					if(QML)
 | 
				
			||||||
 | 
					    # PNG
 | 
				
			||||||
 | 
					    find_package(ZLIB REQUIRED)
 | 
				
			||||||
 | 
					    find_package(PNG REQUIRED)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_subdirectory(libwalletqt)
 | 
					# Compile these source files (.h/.cpp)
 | 
				
			||||||
add_subdirectory(model)
 | 
					 | 
				
			||||||
add_subdirectory(utils)
 | 
					 | 
				
			||||||
add_subdirectory(openpgp)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
qt5_add_resources(RESOURCES assets.qrc)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Compile source files (.h/.cpp)
 | 
					 | 
				
			||||||
file(GLOB SOURCE_FILES
 | 
					file(GLOB SOURCE_FILES
 | 
				
			||||||
        "*.h"
 | 
					        "*.h"
 | 
				
			||||||
        "*.cpp"
 | 
					        "*.cpp"
 | 
				
			||||||
| 
						 | 
					@ -42,6 +39,37 @@ file(GLOB SOURCE_FILES
 | 
				
			||||||
        "dialog/*.cpp"
 | 
					        "dialog/*.cpp"
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(QML)
 | 
				
			||||||
 | 
					    find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui Network Svg Xml WebSockets Quick Qml QuickControls2 QmlImportScanner Multimedia)
 | 
				
			||||||
 | 
					else()
 | 
				
			||||||
 | 
					    find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui Network Svg Xml WebSockets Multimedia)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(OPENVR)
 | 
				
			||||||
 | 
					    # include some extra files
 | 
				
			||||||
 | 
					    qt5_add_resources(RESOURCES vr/qml.qrc)
 | 
				
			||||||
 | 
					    file(GLOB SOURCE_FILES_QML
 | 
				
			||||||
 | 
					            "vr/*.h"
 | 
				
			||||||
 | 
					            "vr/*.cpp"
 | 
				
			||||||
 | 
					            "vr/utils/*.h"
 | 
				
			||||||
 | 
					            "vr/utils/*.cpp"
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					    list(APPEND SOURCE_FILES ${SOURCE_FILES_QML})
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wno-deprecated-declarations")  # @TODO: removeme
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_subdirectory(libwalletqt)
 | 
				
			||||||
 | 
					add_subdirectory(model)
 | 
				
			||||||
 | 
					add_subdirectory(utils)
 | 
				
			||||||
 | 
					add_subdirectory(openpgp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(WITH_SCANNER)
 | 
				
			||||||
 | 
					    add_subdirectory(QR-Code-scanner)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qt5_add_resources(RESOURCES assets.qrc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(TOR_BIN)
 | 
					if(TOR_BIN)
 | 
				
			||||||
    if(APPLE)
 | 
					    if(APPLE)
 | 
				
			||||||
        set(ASSETS_TOR "assets_tor_macos.qrc")
 | 
					        set(ASSETS_TOR "assets_tor_macos.qrc")
 | 
				
			||||||
| 
						 | 
					@ -118,6 +146,10 @@ target_include_directories(wowlet PUBLIC
 | 
				
			||||||
        ${Qt5WebSockets_INCLUDE_DIRS}
 | 
					        ${Qt5WebSockets_INCLUDE_DIRS}
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(OPENVR)
 | 
				
			||||||
 | 
					    target_include_directories(wowlet PUBLIC ${CMAKE_SOURCE_DIR}/contrib/)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(DONATE_BEG)
 | 
					if(DONATE_BEG)
 | 
				
			||||||
    target_compile_definitions(wowlet PRIVATE DONATE_BEG=1)
 | 
					    target_compile_definitions(wowlet PRIVATE DONATE_BEG=1)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
| 
						 | 
					@ -130,6 +162,11 @@ if(XMRIG)
 | 
				
			||||||
    target_compile_definitions(wowlet PRIVATE HAS_XMRIG=1)
 | 
					    target_compile_definitions(wowlet PRIVATE HAS_XMRIG=1)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(OPENVR)
 | 
				
			||||||
 | 
					    target_compile_definitions(wowlet PRIVATE HAS_OPENVR=1)
 | 
				
			||||||
 | 
					    target_compile_definitions(wowlet PUBLIC VR_API_PUBLIC)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(HAVE_SYS_PRCTL_H)
 | 
					if(HAVE_SYS_PRCTL_H)
 | 
				
			||||||
    target_compile_definitions(wowlet PRIVATE HAVE_SYS_PRCTL_H=1)
 | 
					    target_compile_definitions(wowlet PRIVATE HAVE_SYS_PRCTL_H=1)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
| 
						 | 
					@ -150,6 +187,18 @@ if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
 | 
				
			||||||
    target_compile_definitions(wowlet PRIVATE QT_NO_DEBUG=1)
 | 
					    target_compile_definitions(wowlet PRIVATE QT_NO_DEBUG=1)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_definitions(${QT_DEFINITIONS})
 | 
				
			||||||
 | 
					if(NOT "${CMAKE_BUILD_TYPE}" EQUAL "Debug")
 | 
				
			||||||
 | 
					    add_definitions(-DQT_NO_DEBUG)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					target_compile_definitions(wowlet PUBLIC VR_API_PUBLIC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(QML)
 | 
				
			||||||
 | 
					    qt5_import_qml_plugins(${PROJECT_NAME})
 | 
				
			||||||
 | 
					    target_compile_definitions(wowlet PRIVATE HAS_QML=1)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target_compile_definitions(wowlet
 | 
					target_compile_definitions(wowlet
 | 
				
			||||||
        PUBLIC
 | 
					        PUBLIC
 | 
				
			||||||
        ${Qt5Core_DEFINITIONS}
 | 
					        ${Qt5Core_DEFINITIONS}
 | 
				
			||||||
| 
						 | 
					@ -166,12 +215,13 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
 | 
				
			||||||
if(UNIX AND NOT APPLE)
 | 
					if(UNIX AND NOT APPLE)
 | 
				
			||||||
    # https://stackoverflow.com/questions/57766620/cmake-add-library-doesnt-initialize-static-global-variable
 | 
					    # https://stackoverflow.com/questions/57766620/cmake-add-library-doesnt-initialize-static-global-variable
 | 
				
			||||||
    # so that contrib/monero-seed/src/gf_elem.cpp properly initializes. A better solution is welcome.
 | 
					    # so that contrib/monero-seed/src/gf_elem.cpp properly initializes. A better solution is welcome.
 | 
				
			||||||
    target_link_libraries(wowlet -Wl,--whole-archive monero-seed::monero-seed -Wl,--no-whole-archive)
 | 
					    target_link_libraries(wowlet PUBLIC -Wl,--whole-archive monero-seed::monero-seed -Wl,--no-whole-archive)
 | 
				
			||||||
else()
 | 
					else()
 | 
				
			||||||
    target_link_libraries(wowlet monero-seed::monero-seed)
 | 
					    target_link_libraries(wowlet PUBLIC monero-seed::monero-seed)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target_link_libraries(wowlet
 | 
					# Link Wownero core libraries
 | 
				
			||||||
 | 
					target_link_libraries(wowlet PUBLIC
 | 
				
			||||||
        wallet_merged
 | 
					        wallet_merged
 | 
				
			||||||
        ${LMDB_LIBRARY}
 | 
					        ${LMDB_LIBRARY}
 | 
				
			||||||
        epee
 | 
					        epee
 | 
				
			||||||
| 
						 | 
					@ -183,20 +233,66 @@ target_link_libraries(wowlet
 | 
				
			||||||
        ${Boost_LIBRARIES}
 | 
					        ${Boost_LIBRARIES}
 | 
				
			||||||
        ${OPENSSL_LIBRARIES}
 | 
					        ${OPENSSL_LIBRARIES}
 | 
				
			||||||
        ${CMAKE_DL_LIBS}
 | 
					        ${CMAKE_DL_LIBS}
 | 
				
			||||||
        ${EXTRA_LIBRARIES}
 | 
					        ${EXTRA_LIBRARIES})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Link Qt libraries
 | 
				
			||||||
 | 
					if(QML)
 | 
				
			||||||
 | 
					    target_link_libraries(wowlet PUBLIC
 | 
				
			||||||
 | 
					            Qt5::Core
 | 
				
			||||||
 | 
					            Qt5::Widgets
 | 
				
			||||||
 | 
					            Qt5::Gui
 | 
				
			||||||
 | 
					            Qt5::Network
 | 
				
			||||||
 | 
					            Qt5::Svg
 | 
				
			||||||
 | 
					            Qt5::QSvgPlugin
 | 
				
			||||||
 | 
					            Qt5::QSvgIconPlugin
 | 
				
			||||||
 | 
					            Qt5::Xml
 | 
				
			||||||
 | 
					            Qt5::WebSockets
 | 
				
			||||||
 | 
					            Qt5::Quick
 | 
				
			||||||
 | 
					            Qt5::Qml
 | 
				
			||||||
 | 
					            Qt5::QuickControls2)
 | 
				
			||||||
 | 
					else()
 | 
				
			||||||
 | 
					    target_link_libraries(wowlet PUBLIC
 | 
				
			||||||
            Qt5::Core
 | 
					            Qt5::Core
 | 
				
			||||||
            Qt5::Widgets
 | 
					            Qt5::Widgets
 | 
				
			||||||
            Qt5::Gui
 | 
					            Qt5::Gui
 | 
				
			||||||
            Qt5::Network
 | 
					            Qt5::Network
 | 
				
			||||||
            Qt5::Svg
 | 
					            Qt5::Svg
 | 
				
			||||||
            Qt5::Xml
 | 
					            Qt5::Xml
 | 
				
			||||||
        Qt5::WebSockets
 | 
					            Qt5::WebSockets)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Link random other stuff
 | 
				
			||||||
 | 
					target_link_libraries(wowlet PUBLIC
 | 
				
			||||||
        ${ICU_LIBRARIES}
 | 
					        ${ICU_LIBRARIES}
 | 
				
			||||||
        openpgp
 | 
					        openpgp
 | 
				
			||||||
        Threads::Threads
 | 
					        Threads::Threads
 | 
				
			||||||
        ${QRENCODE_LIBRARY}
 | 
					        ${QRENCODE_LIBRARY}
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Link scanner
 | 
				
			||||||
 | 
					if(WITH_SCANNER)
 | 
				
			||||||
 | 
					    target_link_libraries(wowlet PUBLIC qrdecoder qrscanner)
 | 
				
			||||||
 | 
					    if(LINUX AND NOT ANDROID)
 | 
				
			||||||
 | 
					        target_link_libraries(wowlet PUBLIC
 | 
				
			||||||
 | 
					                jpeg
 | 
				
			||||||
 | 
					                v4l2
 | 
				
			||||||
 | 
					                v4lconvert
 | 
				
			||||||
 | 
					                rt
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					    endif()
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Link OpenVR
 | 
				
			||||||
 | 
					if(OPENVR)
 | 
				
			||||||
 | 
					    if(MINGW)
 | 
				
			||||||
 | 
					        target_link_libraries(wowlet PUBLIC
 | 
				
			||||||
 | 
					                openvr_api64
 | 
				
			||||||
 | 
					                gcc stdc++ winpthread ssp glu32 opengl32 glmf32 -dynamic)
 | 
				
			||||||
 | 
					    else()
 | 
				
			||||||
 | 
					        target_link_libraries(wowlet PUBLIC openvr_api)
 | 
				
			||||||
 | 
					    endif()
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(APPLE)
 | 
					if(APPLE)
 | 
				
			||||||
    target_link_libraries(wowlet
 | 
					    target_link_libraries(wowlet
 | 
				
			||||||
            KDMacTouchBar
 | 
					            KDMacTouchBar
 | 
				
			||||||
| 
						 | 
					@ -206,24 +302,24 @@ if(APPLE)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(NOT APPLE)
 | 
					if(NOT APPLE)
 | 
				
			||||||
    target_link_libraries(wowlet
 | 
					    target_link_libraries(wowlet PUBLIC
 | 
				
			||||||
            Qt5::QSvgIconPlugin
 | 
					            Qt5::QSvgIconPlugin
 | 
				
			||||||
            Qt5::QSvgPlugin
 | 
					            Qt5::QSvgPlugin
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(STATIC)
 | 
					if(STATIC)
 | 
				
			||||||
    target_link_libraries(wowlet
 | 
					    target_link_libraries(wowlet PUBLIC
 | 
				
			||||||
            Qt5::QSvgIconPlugin
 | 
					            Qt5::QSvgIconPlugin
 | 
				
			||||||
            Qt5::QSvgPlugin)
 | 
					            Qt5::QSvgPlugin)
 | 
				
			||||||
    if(UNIX AND NOT APPLE)
 | 
					    if(UNIX AND NOT APPLE)
 | 
				
			||||||
        target_link_libraries(wowlet
 | 
						    target_link_libraries(wowlet PUBLIC
 | 
				
			||||||
            	Qt5::QXcbIntegrationPlugin)
 | 
					            	Qt5::QXcbIntegrationPlugin)
 | 
				
			||||||
    endif()
 | 
					    endif()
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(X11_FOUND)
 | 
					if(X11_FOUND)
 | 
				
			||||||
    target_link_libraries(wowlet ${X11_LIBRARIES})
 | 
					    target_link_libraries(wowlet PUBLIC ${X11_LIBRARIES})
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(APPLE)
 | 
					if(APPLE)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										22
									
								
								src/QR-Code-scanner/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,22 @@
 | 
				
			||||||
 | 
					add_library(qrdecoder STATIC
 | 
				
			||||||
 | 
					    Decoder.cpp
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					target_link_libraries(qrdecoder
 | 
				
			||||||
 | 
					    PUBLIC
 | 
				
			||||||
 | 
					        Qt5::Gui
 | 
				
			||||||
 | 
					        PNG::PNG
 | 
				
			||||||
 | 
					    PRIVATE
 | 
				
			||||||
 | 
					        quirc
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(WITH_SCANNER)
 | 
				
			||||||
 | 
					    add_library(qrscanner
 | 
				
			||||||
 | 
					        QrCodeScanner.cpp
 | 
				
			||||||
 | 
					        QrScanThread.cpp
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    target_link_libraries(qrscanner
 | 
				
			||||||
 | 
					        PUBLIC
 | 
				
			||||||
 | 
					            Qt5::Multimedia
 | 
				
			||||||
 | 
					            qrdecoder
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
							
								
								
									
										359
									
								
								src/QR-Code-scanner/Decoder.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,359 @@
 | 
				
			||||||
 | 
					// Copyright (c) 2020, The Monero Project
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// All rights reserved.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Redistribution and use in source and binary forms, with or without modification, are
 | 
				
			||||||
 | 
					// permitted provided that the following conditions are met:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 1. Redistributions of source code must retain the above copyright notice, this list of
 | 
				
			||||||
 | 
					//    conditions and the following disclaimer.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 2. Redistributions in binary form must reproduce the above copyright notice, this list
 | 
				
			||||||
 | 
					//    of conditions and the following disclaimer in the documentation and/or other
 | 
				
			||||||
 | 
					//    materials provided with the distribution.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 3. Neither the name of the copyright holder nor the names of its contributors may be
 | 
				
			||||||
 | 
					//    used to endorse or promote products derived from this software without specific
 | 
				
			||||||
 | 
					//    prior written permission.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 | 
				
			||||||
 | 
					// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 | 
				
			||||||
 | 
					// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
				
			||||||
 | 
					// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
				
			||||||
 | 
					// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
				
			||||||
 | 
					// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
				
			||||||
 | 
					// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 | 
				
			||||||
 | 
					// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <limits>
 | 
				
			||||||
 | 
					#include <QDebug>
 | 
				
			||||||
 | 
					#include <QString>
 | 
				
			||||||
 | 
					#include "Decoder.h"
 | 
				
			||||||
 | 
					#include "quirc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QrDecoder::QrDecoder()
 | 
				
			||||||
 | 
					        : m_qr(quirc_new())
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (m_qr == nullptr)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        throw std::runtime_error("QUIRC: failed to allocate memory");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QrDecoder::~QrDecoder()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    quirc_destroy(m_qr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::vector<std::string> QrDecoder::decode(const QImage &image)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (image.format() == QImage::Format_Grayscale8)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return decodeGrayscale8(image);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return decodeGrayscale8(image.convertToFormat(QImage::Format_Grayscale8));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::vector<std::string> QrDecoder::decodePNG(QString pngPath) {
 | 
				
			||||||
 | 
					    struct quirc *q;
 | 
				
			||||||
 | 
					    std::vector<std::string> result;
 | 
				
			||||||
 | 
					    auto pngPathStd = pngPath.toStdString();
 | 
				
			||||||
 | 
					    auto pngPathCstr = pngPathStd.c_str();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    q = quirc_new();
 | 
				
			||||||
 | 
					    if (!q) {
 | 
				
			||||||
 | 
					        qWarning() << "can't create quirc object";
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int status = -1;
 | 
				
			||||||
 | 
					    if (check_if_png(pngPathCstr)) {
 | 
				
			||||||
 | 
					        status = load_png(q, pngPathCstr);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        qWarning() << QString("Image is not a PNG: %1").arg(pngPath);
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (status < 0) {
 | 
				
			||||||
 | 
					        quirc_destroy(q);
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    quirc_end(q);
 | 
				
			||||||
 | 
					    auto count = quirc_count(q);
 | 
				
			||||||
 | 
					    result.reserve(static_cast<size_t>(count));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int index = 0; index < count; ++index)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        quirc_code code;
 | 
				
			||||||
 | 
					        quirc_extract(q, index, &code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        quirc_data data;
 | 
				
			||||||
 | 
					        const quirc_decode_error_t err = quirc_decode(&code, &data);
 | 
				
			||||||
 | 
					        if (err == QUIRC_SUCCESS)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            result.emplace_back(&data.payload[0], &data.payload[data.payload_len]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    quirc_destroy(q);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// I can't seem to get this function to work, we'll use dgbutil.h instead
 | 
				
			||||||
 | 
					std::vector<std::string> QrDecoder::decodeGrayscale8(const QImage &image)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (quirc_resize(m_qr, image.width(), image.height()) < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        throw std::runtime_error("QUIRC: failed to allocate video memory");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint8_t *rawImage = quirc_begin(m_qr, nullptr, nullptr);
 | 
				
			||||||
 | 
					    if (rawImage == nullptr)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        throw std::runtime_error("QUIRC: failed to get image buffer");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
 | 
				
			||||||
 | 
					    std::copy(image.constBits(), image.constBits() + image.sizeInBytes(), rawImage);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    std::copy(image.constBits(), image.constBits() + image.byteCount(), rawImage);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    quirc_end(m_qr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const int count = quirc_count(m_qr);
 | 
				
			||||||
 | 
					    if (count < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        throw std::runtime_error("QUIRC: failed to get the number of recognized QR-codes");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::vector<std::string> result;
 | 
				
			||||||
 | 
					    result.reserve(static_cast<size_t>(count));
 | 
				
			||||||
 | 
					    for (int index = 0; index < count; ++index)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        quirc_code code;
 | 
				
			||||||
 | 
					        quirc_extract(m_qr, index, &code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        quirc_data data;
 | 
				
			||||||
 | 
					        const quirc_decode_error_t err = quirc_decode(&code, &data);
 | 
				
			||||||
 | 
					        if (err == QUIRC_SUCCESS)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            result.emplace_back(&data.payload[0], &data.payload[data.payload_len]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* quirc -- QR-code recognition library
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
				
			||||||
 | 
					 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
				
			||||||
 | 
					 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *data_type_str(int dt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    switch (dt) {
 | 
				
			||||||
 | 
					        case QUIRC_DATA_TYPE_NUMERIC: return "NUMERIC";
 | 
				
			||||||
 | 
					        case QUIRC_DATA_TYPE_ALPHA:   return "ALPHA";
 | 
				
			||||||
 | 
					        case QUIRC_DATA_TYPE_BYTE:    return "BYTE";
 | 
				
			||||||
 | 
					        case QUIRC_DATA_TYPE_KANJI:   return "KANJI";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return "unknown";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void QrDecoder::dump_data(const struct quirc_data *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    printf("    Version: %d\n", data->version);
 | 
				
			||||||
 | 
					    printf("    ECC level: %c\n", "MLHQ"[data->ecc_level]);
 | 
				
			||||||
 | 
					    printf("    Mask: %d\n", data->mask);
 | 
				
			||||||
 | 
					    printf("    Data type: %d (%s)\n",
 | 
				
			||||||
 | 
					           data->data_type, data_type_str(data->data_type));
 | 
				
			||||||
 | 
					    printf("    Length: %d\n", data->payload_len);
 | 
				
			||||||
 | 
					    printf("    Payload: %s\n", data->payload);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (data->eci)
 | 
				
			||||||
 | 
					        printf("    ECI: %d\n", data->eci);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void QrDecoder::dump_cells(const struct quirc_code *code)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int u, v;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("    %d cells, corners:", code->size);
 | 
				
			||||||
 | 
					    for (u = 0; u < 4; u++)
 | 
				
			||||||
 | 
					        printf(" (%d,%d)", code->corners[u].x,
 | 
				
			||||||
 | 
					               code->corners[u].y);
 | 
				
			||||||
 | 
					    printf("\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (v = 0; v < code->size; v++) {
 | 
				
			||||||
 | 
					        printf("    ");
 | 
				
			||||||
 | 
					        for (u = 0; u < code->size; u++) {
 | 
				
			||||||
 | 
					            int p = v * code->size + u;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (code->cell_bitmap[p >> 3] & (1 << (p & 7)))
 | 
				
			||||||
 | 
					                printf("[]");
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                printf("  ");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        printf("\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* hacked from https://dev.w3.org/Amaya/libpng/example.c
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Check if a file is a PNG image using png_sig_cmp(). Returns 1 if the given
 | 
				
			||||||
 | 
					 * file is a PNG and 0 otherwise.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define PNG_BYTES_TO_CHECK 4
 | 
				
			||||||
 | 
					int QrDecoder::check_if_png(const char *filename)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret = 0;
 | 
				
			||||||
 | 
					    FILE *infile = NULL;
 | 
				
			||||||
 | 
					    unsigned char buf[PNG_BYTES_TO_CHECK];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Open the prospective PNG file. */
 | 
				
			||||||
 | 
					    if ((infile = fopen(filename, "rb")) == NULL)
 | 
				
			||||||
 | 
					        goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Read in some of the signature bytes */
 | 
				
			||||||
 | 
					    if (fread(buf, 1, PNG_BYTES_TO_CHECK, infile) != PNG_BYTES_TO_CHECK)
 | 
				
			||||||
 | 
					        goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Compare the first PNG_BYTES_TO_CHECK bytes of the signature.
 | 
				
			||||||
 | 
					     * png_sig_cmp() returns zero if the image is a PNG and nonzero if it
 | 
				
			||||||
 | 
					     * isn't a PNG.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    if (png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK) == 0)
 | 
				
			||||||
 | 
					        ret = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* FALLTHROUGH */
 | 
				
			||||||
 | 
					    out:
 | 
				
			||||||
 | 
					    if (infile)
 | 
				
			||||||
 | 
					        fclose(infile);
 | 
				
			||||||
 | 
					    return (ret);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int QrDecoder::load_png(struct quirc *q, const char *filename)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int width, height, rowbytes, interlace_type, number_passes = 1;
 | 
				
			||||||
 | 
					    png_uint_32 trns;
 | 
				
			||||||
 | 
					    png_byte color_type, bit_depth;
 | 
				
			||||||
 | 
					    png_structp png_ptr = NULL;
 | 
				
			||||||
 | 
					    png_infop info_ptr = NULL;
 | 
				
			||||||
 | 
					    FILE *infile = NULL;
 | 
				
			||||||
 | 
					    uint8_t *image;
 | 
				
			||||||
 | 
					    int ret = -1;
 | 
				
			||||||
 | 
					    int pass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((infile = fopen(filename, "rb")) == NULL)
 | 
				
			||||||
 | 
					        goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
 | 
				
			||||||
 | 
					    if (!png_ptr)
 | 
				
			||||||
 | 
					        goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    info_ptr = png_create_info_struct(png_ptr);
 | 
				
			||||||
 | 
					    if (!info_ptr)
 | 
				
			||||||
 | 
					        goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (setjmp(png_jmpbuf(png_ptr)))
 | 
				
			||||||
 | 
					        goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    png_init_io(png_ptr, infile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    png_read_info(png_ptr, info_ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    color_type     = png_get_color_type(png_ptr, info_ptr);
 | 
				
			||||||
 | 
					    bit_depth      = png_get_bit_depth(png_ptr, info_ptr);
 | 
				
			||||||
 | 
					    interlace_type = png_get_interlace_type(png_ptr, info_ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Read any color_type into 8bit depth, Grayscale format.
 | 
				
			||||||
 | 
					    // See http://www.libpng.org/pub/png/libpng-manual.txt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // PNG_COLOR_TYPE_GRAY_ALPHA is always 8 or 16bit depth.
 | 
				
			||||||
 | 
					    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
 | 
				
			||||||
 | 
					        png_set_expand_gray_1_2_4_to_8(png_ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((trns = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
 | 
				
			||||||
 | 
					        png_set_tRNS_to_alpha(png_ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (bit_depth == 16)
 | 
				
			||||||
 | 
					#if PNG_LIBPNG_VER >= 10504
 | 
				
			||||||
 | 
					        png_set_scale_16(png_ptr);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					        png_set_strip_16(png_ptr);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((trns) || color_type & PNG_COLOR_MASK_ALPHA)
 | 
				
			||||||
 | 
					        png_set_strip_alpha(png_ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (color_type == PNG_COLOR_TYPE_PALETTE)
 | 
				
			||||||
 | 
					        png_set_palette_to_rgb(png_ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (color_type == PNG_COLOR_TYPE_PALETTE ||
 | 
				
			||||||
 | 
					        color_type == PNG_COLOR_TYPE_RGB ||
 | 
				
			||||||
 | 
					        color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
 | 
				
			||||||
 | 
					        png_set_rgb_to_gray_fixed(png_ptr, 1, -1, -1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (interlace_type != PNG_INTERLACE_NONE)
 | 
				
			||||||
 | 
					        number_passes = png_set_interlace_handling(png_ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    png_read_update_info(png_ptr, info_ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    width    = png_get_image_width(png_ptr, info_ptr);
 | 
				
			||||||
 | 
					    height   = png_get_image_height(png_ptr, info_ptr);
 | 
				
			||||||
 | 
					    rowbytes = png_get_rowbytes(png_ptr, info_ptr);
 | 
				
			||||||
 | 
					    if (rowbytes != width) {
 | 
				
			||||||
 | 
					        fprintf(stderr,
 | 
				
			||||||
 | 
					                "load_png: expected rowbytes to be %u but got %u\n",
 | 
				
			||||||
 | 
					                width, rowbytes);
 | 
				
			||||||
 | 
					        goto out;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (quirc_resize(q, width, height) < 0)
 | 
				
			||||||
 | 
					        goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    image = quirc_begin(q, NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (pass = 0; pass < number_passes; pass++) {
 | 
				
			||||||
 | 
					        int y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (y = 0; y < height; y++) {
 | 
				
			||||||
 | 
					            png_bytep row_pointer = image + y * width;
 | 
				
			||||||
 | 
					            png_read_rows(png_ptr, &row_pointer, NULL, 1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    png_read_end(png_ptr, info_ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = 0;
 | 
				
			||||||
 | 
					    /* FALLTHROUGH */
 | 
				
			||||||
 | 
					    out:
 | 
				
			||||||
 | 
					    /* cleanup */
 | 
				
			||||||
 | 
					    if (png_ptr) {
 | 
				
			||||||
 | 
					        if (info_ptr)
 | 
				
			||||||
 | 
					            png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (infile)
 | 
				
			||||||
 | 
					        fclose(infile);
 | 
				
			||||||
 | 
					    return (ret);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										72
									
								
								src/QR-Code-scanner/Decoder.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,72 @@
 | 
				
			||||||
 | 
					// Copyright (c) 2020, The Monero Project
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// All rights reserved.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Redistribution and use in source and binary forms, with or without modification, are
 | 
				
			||||||
 | 
					// permitted provided that the following conditions are met:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 1. Redistributions of source code must retain the above copyright notice, this list of
 | 
				
			||||||
 | 
					//    conditions and the following disclaimer.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 2. Redistributions in binary form must reproduce the above copyright notice, this list
 | 
				
			||||||
 | 
					//    of conditions and the following disclaimer in the documentation and/or other
 | 
				
			||||||
 | 
					//    materials provided with the distribution.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 3. Neither the name of the copyright holder nor the names of its contributors may be
 | 
				
			||||||
 | 
					//    used to endorse or promote products derived from this software without specific
 | 
				
			||||||
 | 
					//    prior written permission.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 | 
				
			||||||
 | 
					// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 | 
				
			||||||
 | 
					// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
				
			||||||
 | 
					// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
				
			||||||
 | 
					// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
				
			||||||
 | 
					// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
				
			||||||
 | 
					// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 | 
				
			||||||
 | 
					// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QImage>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <png.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct quirc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class QrDecoder
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    QrDecoder(const QrDecoder &) = delete;
 | 
				
			||||||
 | 
					    QrDecoder &operator=(const QrDecoder &) = delete;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QrDecoder();
 | 
				
			||||||
 | 
					    ~QrDecoder();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::vector<std::string> decode(const QImage &image);
 | 
				
			||||||
 | 
					    std::vector<std::string> decodePNG(QString pngPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    /* Dump decoded information on stdout. */
 | 
				
			||||||
 | 
					    void dump_data(const struct quirc_data *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Dump a grid cell map on stdout. */
 | 
				
			||||||
 | 
					    void dump_cells(const struct quirc_code *code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Check if a file is a PNG image.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * returns 1 if the given file is a PNG and 0 otherwise.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    int check_if_png(const char *filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Read a PNG image into the decoder.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Note that you must call quirc_end() if the function returns
 | 
				
			||||||
 | 
					     * successfully (0).
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    int load_png(struct quirc *q, const char *filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    std::vector<std::string> decodeGrayscale8(const QImage &image);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    quirc *m_qr;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										92
									
								
								src/QR-Code-scanner/QrCodeScanner.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,92 @@
 | 
				
			||||||
 | 
					// Copyright (c) 2014-2019, The Monero Project
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// All rights reserved.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Redistribution and use in source and binary forms, with or without modification, are
 | 
				
			||||||
 | 
					// permitted provided that the following conditions are met:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 1. Redistributions of source code must retain the above copyright notice, this list of
 | 
				
			||||||
 | 
					//    conditions and the following disclaimer.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 2. Redistributions in binary form must reproduce the above copyright notice, this list
 | 
				
			||||||
 | 
					//    of conditions and the following disclaimer in the documentation and/or other
 | 
				
			||||||
 | 
					//    materials provided with the distribution.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 3. Neither the name of the copyright holder nor the names of its contributors may be
 | 
				
			||||||
 | 
					//    used to endorse or promote products derived from this software without specific
 | 
				
			||||||
 | 
					//    prior written permission.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 | 
				
			||||||
 | 
					// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 | 
				
			||||||
 | 
					// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
				
			||||||
 | 
					// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
				
			||||||
 | 
					// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
				
			||||||
 | 
					// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
				
			||||||
 | 
					// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 | 
				
			||||||
 | 
					// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "QrCodeScanner.h"
 | 
				
			||||||
 | 
					#include <QVideoProbe>
 | 
				
			||||||
 | 
					#include <QCamera>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QrCodeScanner::QrCodeScanner(QObject *parent)
 | 
				
			||||||
 | 
					    : QObject(parent)
 | 
				
			||||||
 | 
					    , m_processTimerId(-1)
 | 
				
			||||||
 | 
					    , m_processInterval(750)
 | 
				
			||||||
 | 
					    , m_enabled(true)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    m_probe = new QVideoProbe(this);
 | 
				
			||||||
 | 
					    m_thread = new QrScanThread(this);
 | 
				
			||||||
 | 
					    m_thread->start();
 | 
				
			||||||
 | 
					    QObject::connect(m_thread, SIGNAL(decoded(QString)), this, SIGNAL(decoded(QString)));
 | 
				
			||||||
 | 
					    QObject::connect(m_thread, SIGNAL(notifyError(const QString &, bool)), this, SIGNAL(notifyError(const QString &, bool)));
 | 
				
			||||||
 | 
					    connect(m_probe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(processFrame(QVideoFrame)));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void QrCodeScanner::setSource(QCamera *camera)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    m_probe->setSource(camera);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void QrCodeScanner::processFrame(QVideoFrame frame)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(frame.isValid()){
 | 
				
			||||||
 | 
					        m_curFrame = frame;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool QrCodeScanner::enabled() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return m_enabled;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void QrCodeScanner::setEnabled(bool enabled)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    m_enabled = enabled;
 | 
				
			||||||
 | 
					    if(!enabled && (m_processTimerId != -1) )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        this->killTimer(m_processTimerId);
 | 
				
			||||||
 | 
					        m_processTimerId = -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (enabled && (m_processTimerId == -1) )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        m_processTimerId = this->startTimer(m_processInterval);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    emit enabledChanged();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void QrCodeScanner::timerEvent(QTimerEvent *event)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if( (event->timerId() == m_processTimerId) ){
 | 
				
			||||||
 | 
					        m_thread->addFrame(m_curFrame);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QrCodeScanner::~QrCodeScanner()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    m_thread->stop();
 | 
				
			||||||
 | 
					    m_thread->quit();
 | 
				
			||||||
 | 
					    if(!m_thread->wait(5000))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        m_thread->terminate();
 | 
				
			||||||
 | 
					        m_thread->wait();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										73
									
								
								src/QR-Code-scanner/QrCodeScanner.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,73 @@
 | 
				
			||||||
 | 
					// Copyright (c) 2014-2019, The Monero Project
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// All rights reserved.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Redistribution and use in source and binary forms, with or without modification, are
 | 
				
			||||||
 | 
					// permitted provided that the following conditions are met:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 1. Redistributions of source code must retain the above copyright notice, this list of
 | 
				
			||||||
 | 
					//    conditions and the following disclaimer.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 2. Redistributions in binary form must reproduce the above copyright notice, this list
 | 
				
			||||||
 | 
					//    of conditions and the following disclaimer in the documentation and/or other
 | 
				
			||||||
 | 
					//    materials provided with the distribution.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 3. Neither the name of the copyright holder nor the names of its contributors may be
 | 
				
			||||||
 | 
					//    used to endorse or promote products derived from this software without specific
 | 
				
			||||||
 | 
					//    prior written permission.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 | 
				
			||||||
 | 
					// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 | 
				
			||||||
 | 
					// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
				
			||||||
 | 
					// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
				
			||||||
 | 
					// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
				
			||||||
 | 
					// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
				
			||||||
 | 
					// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 | 
				
			||||||
 | 
					// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef QRCODESCANNER_H_
 | 
				
			||||||
 | 
					#define QRCODESCANNER_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QImage>
 | 
				
			||||||
 | 
					#include <QVideoFrame>
 | 
				
			||||||
 | 
					#include "QrScanThread.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class QVideoProbe;
 | 
				
			||||||
 | 
					class QCamera;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class QrCodeScanner : public QObject
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Q_OBJECT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    QrCodeScanner(QObject *parent = Q_NULLPTR);
 | 
				
			||||||
 | 
					    ~QrCodeScanner();
 | 
				
			||||||
 | 
					    void setSource(QCamera*);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool enabled() const;
 | 
				
			||||||
 | 
					    void setEnabled(bool enabled);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public Q_SLOTS:
 | 
				
			||||||
 | 
					    void processFrame(QVideoFrame);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Q_SIGNALS:
 | 
				
			||||||
 | 
					    void enabledChanged();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void decoded(const QString &data);
 | 
				
			||||||
 | 
					    void notifyError(const QString &error, bool warning = false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					    void timerEvent(QTimerEvent *);
 | 
				
			||||||
 | 
					    QrScanThread *m_thread;
 | 
				
			||||||
 | 
					    int m_processTimerId;
 | 
				
			||||||
 | 
					    int m_processInterval;
 | 
				
			||||||
 | 
					    int m_enabled;
 | 
				
			||||||
 | 
					    QVideoFrame m_curFrame;
 | 
				
			||||||
 | 
					    QVideoProbe *m_probe;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										90
									
								
								src/QR-Code-scanner/QrScanThread.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,90 @@
 | 
				
			||||||
 | 
					// Copyright (c) 2014-2019, The Monero Project
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// All rights reserved.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Redistribution and use in source and binary forms, with or without modification, are
 | 
				
			||||||
 | 
					// permitted provided that the following conditions are met:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 1. Redistributions of source code must retain the above copyright notice, this list of
 | 
				
			||||||
 | 
					//    conditions and the following disclaimer.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 2. Redistributions in binary form must reproduce the above copyright notice, this list
 | 
				
			||||||
 | 
					//    of conditions and the following disclaimer in the documentation and/or other
 | 
				
			||||||
 | 
					//    materials provided with the distribution.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 3. Neither the name of the copyright holder nor the names of its contributors may be
 | 
				
			||||||
 | 
					//    used to endorse or promote products derived from this software without specific
 | 
				
			||||||
 | 
					//    prior written permission.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 | 
				
			||||||
 | 
					// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 | 
				
			||||||
 | 
					// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
				
			||||||
 | 
					// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
				
			||||||
 | 
					// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
				
			||||||
 | 
					// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
				
			||||||
 | 
					// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 | 
				
			||||||
 | 
					// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "QrScanThread.h"
 | 
				
			||||||
 | 
					#include <QtGlobal>
 | 
				
			||||||
 | 
					#include <QDebug>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
 | 
				
			||||||
 | 
					extern QImage qt_imageFromVideoFrame(const QVideoFrame &f);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QrScanThread::QrScanThread(QObject *parent)
 | 
				
			||||||
 | 
					      : QThread(parent)
 | 
				
			||||||
 | 
					       ,m_running(true)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void QrScanThread::processQImage(const QImage &qimg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        for (const std::string &code : m_decoder.decode(qimg))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            emit decoded(QString::fromStdString(code));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    catch(std::exception &e) {
 | 
				
			||||||
 | 
					        qDebug() << "ERROR: " << e.what();
 | 
				
			||||||
 | 
					        emit notifyError(e.what());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void QrScanThread::processVideoFrame(const QVideoFrame &frame)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
 | 
				
			||||||
 | 
					    processQImage( qt_imageFromVideoFrame(frame) );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    processQImage(frame.image());
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void QrScanThread::stop()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    m_running = false;
 | 
				
			||||||
 | 
					    m_waitCondition.wakeOne();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void QrScanThread::addFrame(const QVideoFrame &frame)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    QMutexLocker locker(&m_mutex);
 | 
				
			||||||
 | 
					    m_queue.append(frame);
 | 
				
			||||||
 | 
					    m_waitCondition.wakeOne();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void QrScanThread::run()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    QVideoFrame frame;
 | 
				
			||||||
 | 
					    while(m_running) {
 | 
				
			||||||
 | 
					        QMutexLocker locker(&m_mutex);
 | 
				
			||||||
 | 
					        while(m_queue.isEmpty() && m_running)
 | 
				
			||||||
 | 
					            m_waitCondition.wait(&m_mutex);
 | 
				
			||||||
 | 
					        if(!m_queue.isEmpty())
 | 
				
			||||||
 | 
					            processVideoFrame(m_queue.takeFirst());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										66
									
								
								src/QR-Code-scanner/QrScanThread.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,66 @@
 | 
				
			||||||
 | 
					// Copyright (c) 2014-2019, The Monero Project
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// All rights reserved.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Redistribution and use in source and binary forms, with or without modification, are
 | 
				
			||||||
 | 
					// permitted provided that the following conditions are met:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 1. Redistributions of source code must retain the above copyright notice, this list of
 | 
				
			||||||
 | 
					//    conditions and the following disclaimer.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 2. Redistributions in binary form must reproduce the above copyright notice, this list
 | 
				
			||||||
 | 
					//    of conditions and the following disclaimer in the documentation and/or other
 | 
				
			||||||
 | 
					//    materials provided with the distribution.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 3. Neither the name of the copyright holder nor the names of its contributors may be
 | 
				
			||||||
 | 
					//    used to endorse or promote products derived from this software without specific
 | 
				
			||||||
 | 
					//    prior written permission.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 | 
				
			||||||
 | 
					// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 | 
				
			||||||
 | 
					// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
				
			||||||
 | 
					// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
				
			||||||
 | 
					// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
				
			||||||
 | 
					// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
				
			||||||
 | 
					// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 | 
				
			||||||
 | 
					// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _QRSCANTHREAD_H_
 | 
				
			||||||
 | 
					#define _QRSCANTHREAD_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QThread>
 | 
				
			||||||
 | 
					#include <QMutex>
 | 
				
			||||||
 | 
					#include <QWaitCondition>
 | 
				
			||||||
 | 
					#include <QEvent>
 | 
				
			||||||
 | 
					#include <QVideoFrame>
 | 
				
			||||||
 | 
					#include <QCamera>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "Decoder.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class QrScanThread : public QThread
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Q_OBJECT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    QrScanThread(QObject *parent = Q_NULLPTR);
 | 
				
			||||||
 | 
					    void addFrame(const QVideoFrame &frame);
 | 
				
			||||||
 | 
					    virtual void stop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Q_SIGNALS:
 | 
				
			||||||
 | 
					    void decoded(const QString &data);
 | 
				
			||||||
 | 
					    void notifyError(const QString &error, bool warning = false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					    virtual void run();
 | 
				
			||||||
 | 
					    void processVideoFrame(const QVideoFrame &);
 | 
				
			||||||
 | 
					    void processQImage(const QImage &);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    QrDecoder m_decoder;
 | 
				
			||||||
 | 
					    bool m_running;
 | 
				
			||||||
 | 
					    QMutex m_mutex;
 | 
				
			||||||
 | 
					    QWaitCondition m_waitCondition;
 | 
				
			||||||
 | 
					    QList<QVideoFrame> m_queue;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -21,12 +21,14 @@ TxFiatHistory *AppContext::txFiatHistory = nullptr;
 | 
				
			||||||
double AppContext::balance = 0;
 | 
					double AppContext::balance = 0;
 | 
				
			||||||
QMap<QString, QString> AppContext::txDescriptionCache;
 | 
					QMap<QString, QString> AppContext::txDescriptionCache;
 | 
				
			||||||
QMap<QString, QString> AppContext::txCache;
 | 
					QMap<QString, QString> AppContext::txCache;
 | 
				
			||||||
 | 
					bool AppContext::isQML = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AppContext::AppContext(QCommandLineParser *cmdargs) {
 | 
					AppContext::AppContext(QCommandLineParser *cmdargs) {
 | 
				
			||||||
    this->m_walletKeysFilesModel = new WalletKeysFilesModel(this, this);
 | 
					    this->m_walletKeysFilesModel = new WalletKeysFilesModel(this, this);
 | 
				
			||||||
    this->network = new QNetworkAccessManager();
 | 
					    this->network = new QNetworkAccessManager();
 | 
				
			||||||
    this->networkClearnet = new QNetworkAccessManager();
 | 
					    this->networkClearnet = new QNetworkAccessManager();
 | 
				
			||||||
    this->cmdargs = cmdargs;
 | 
					    this->cmdargs = cmdargs;
 | 
				
			||||||
 | 
					    AppContext::isQML = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(Q_OS_MAC)
 | 
					#if defined(Q_OS_MAC)
 | 
				
			||||||
    this->isTorSocks = qgetenv("DYLD_INSERT_LIBRARIES").indexOf("libtorsocks") >= 0;
 | 
					    this->isTorSocks = qgetenv("DYLD_INSERT_LIBRARIES").indexOf("libtorsocks") >= 0;
 | 
				
			||||||
| 
						 | 
					@ -87,8 +89,9 @@ AppContext::AppContext(QCommandLineParser *cmdargs) {
 | 
				
			||||||
    if(!this->configDirectory.endsWith('/'))
 | 
					    if(!this->configDirectory.endsWith('/'))
 | 
				
			||||||
        this->configDirectory = QString("%1/").arg(this->configDirectory);
 | 
					        this->configDirectory = QString("%1/").arg(this->configDirectory);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					    this->configDirectoryVR = QString("%1%2").arg(this->configDirectory, "vr");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Config
 | 
					    // Create some directories
 | 
				
			||||||
    createConfigDirectory(this->configDirectory);
 | 
					    createConfigDirectory(this->configDirectory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//    if(this->cmdargs->isSet("stagenet"))
 | 
					//    if(this->cmdargs->isSet("stagenet"))
 | 
				
			||||||
| 
						 | 
					@ -105,8 +108,10 @@ AppContext::AppContext(QCommandLineParser *cmdargs) {
 | 
				
			||||||
    connect(this, &AppContext::setCustomNodes, this->nodes, &Nodes::setCustomNodes);
 | 
					    connect(this, &AppContext::setCustomNodes, this->nodes, &Nodes::setCustomNodes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Tor & socks proxy
 | 
					    // Tor & socks proxy
 | 
				
			||||||
    this->ws = new WSClient(this, m_wsUrl);
 | 
					    this->ws = new WSClient(this, wsUrl);
 | 
				
			||||||
    connect(this->ws, &WSClient::WSMessage, this, &AppContext::onWSMessage);
 | 
					    connect(this->ws, &WSClient::WSMessage, this, &AppContext::onWSMessage);
 | 
				
			||||||
 | 
					    connect(this->ws, &WSClient::connectionEstablished, this, &AppContext::wsConnected);
 | 
				
			||||||
 | 
					    connect(this->ws, &WSClient::closed, this, &AppContext::wsDisconnected);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Store the wallet every 2 minutes
 | 
					    // Store the wallet every 2 minutes
 | 
				
			||||||
    m_storeTimer.start(2 * 60 * 1000);
 | 
					    m_storeTimer.start(2 * 60 * 1000);
 | 
				
			||||||
| 
						 | 
					@ -161,10 +166,9 @@ void AppContext::initTor() {
 | 
				
			||||||
    this->tor = new Tor(this, this);
 | 
					    this->tor = new Tor(this, this);
 | 
				
			||||||
    this->tor->start();
 | 
					    this->tor->start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!(isWhonix)) {
 | 
					    if (!isWhonix && wsUrl.contains(".onion")) {
 | 
				
			||||||
        this->networkProxy = new QNetworkProxy(QNetworkProxy::Socks5Proxy, Tor::torHost, Tor::torPort);
 | 
					        this->networkProxy = new QNetworkProxy(QNetworkProxy::Socks5Proxy, Tor::torHost, Tor::torPort);
 | 
				
			||||||
        this->network->setProxy(*networkProxy);
 | 
					        this->network->setProxy(*networkProxy);
 | 
				
			||||||
        if (m_wsUrl.host().endsWith(".onion"))
 | 
					 | 
				
			||||||
        this->ws->webSocket.setProxy(*networkProxy);
 | 
					        this->ws->webSocket.setProxy(*networkProxy);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -330,6 +334,8 @@ void AppContext::onWalletOpened(Wallet *wallet) {
 | 
				
			||||||
    this->refreshed = false;
 | 
					    this->refreshed = false;
 | 
				
			||||||
    this->currentWallet = wallet;
 | 
					    this->currentWallet = wallet;
 | 
				
			||||||
    this->walletPath = this->currentWallet->path() + ".keys";
 | 
					    this->walletPath = this->currentWallet->path() + ".keys";
 | 
				
			||||||
 | 
					    QFileInfo fileInfo(this->currentWallet->path());
 | 
				
			||||||
 | 
					    this->walletName = fileInfo.fileName();
 | 
				
			||||||
    this->walletViewOnly = this->currentWallet->viewOnly();
 | 
					    this->walletViewOnly = this->currentWallet->viewOnly();
 | 
				
			||||||
    config()->set(Config::walletPath, this->walletPath);
 | 
					    config()->set(Config::walletPath, this->walletPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -405,7 +411,7 @@ void AppContext::onWSMessage(const QJsonObject &msg) {
 | 
				
			||||||
            emit blockHeightWSUpdated(this->heights);
 | 
					            emit blockHeightWSUpdated(this->heights);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    else if(cmd == "nodes") {
 | 
					    else if(cmd == "rpc_nodes") {
 | 
				
			||||||
        this->onWSNodes(msg.value("data").toArray());
 | 
					        this->onWSNodes(msg.value("data").toArray());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#if defined(HAS_XMRIG)
 | 
					#if defined(HAS_XMRIG)
 | 
				
			||||||
| 
						 | 
					@ -427,7 +433,7 @@ void AppContext::onWSMessage(const QJsonObject &msg) {
 | 
				
			||||||
        this->onWSReddit(reddit_data);
 | 
					        this->onWSReddit(reddit_data);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    else if(cmd == "wfs") {
 | 
					    else if(cmd == "funding_proposals") {
 | 
				
			||||||
        auto ccs_data = msg.value("data").toArray();
 | 
					        auto ccs_data = msg.value("data").toArray();
 | 
				
			||||||
        this->onWSCCS(ccs_data);
 | 
					        this->onWSCCS(ccs_data);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -441,6 +447,23 @@ void AppContext::onWSMessage(const QJsonObject &msg) {
 | 
				
			||||||
        auto txFiatHistory_data = msg.value("data").toObject();
 | 
					        auto txFiatHistory_data = msg.value("data").toObject();
 | 
				
			||||||
        AppContext::txFiatHistory->onWSData(txFiatHistory_data);
 | 
					        AppContext::txFiatHistory->onWSData(txFiatHistory_data);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					#if defined(HAS_OPENVR)
 | 
				
			||||||
 | 
					    else if(cmd == "requestPIN") {
 | 
				
			||||||
 | 
					        auto pin = msg.value("data").toString();
 | 
				
			||||||
 | 
					        emit pinReceived(pin);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    else if(cmd == "lookupPIN") {
 | 
				
			||||||
 | 
					        auto lookup_data = msg.value("data").toObject();
 | 
				
			||||||
 | 
					        auto address = lookup_data.value("address").toString();
 | 
				
			||||||
 | 
					        auto pin = lookup_data.value("PIN").toString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(address.isEmpty())
 | 
				
			||||||
 | 
					            emit pinLookupErrorReceived();
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            emit pinLookupReceived(address, pin);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AppContext::onWSNodes(const QJsonArray &nodes) {
 | 
					void AppContext::onWSNodes(const QJsonArray &nodes) {
 | 
				
			||||||
| 
						 | 
					@ -523,8 +546,8 @@ void AppContext::onWSCCS(const QJsonArray &ccs_data) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AppContext::createConfigDirectory(const QString &dir) {
 | 
					void AppContext::createConfigDirectory(const QString &dir) {
 | 
				
			||||||
    QString config_dir_tor = QString("%1%2").arg(dir).arg("tor");
 | 
					    auto config_dir_tor = QString("%1%2").arg(dir).arg("tor");
 | 
				
			||||||
    QString config_dir_tordata = QString("%1%2").arg(dir).arg("tor/data");
 | 
					    auto config_dir_tordata = QString("%1%2").arg(dir).arg("tor/data");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QStringList createDirs({dir, config_dir_tor, config_dir_tordata});
 | 
					    QStringList createDirs({dir, config_dir_tor, config_dir_tordata});
 | 
				
			||||||
    for(const auto &d: createDirs) {
 | 
					    for(const auto &d: createDirs) {
 | 
				
			||||||
| 
						 | 
					@ -534,6 +557,19 @@ void AppContext::createConfigDirectory(const QString &dir) {
 | 
				
			||||||
                throw std::runtime_error("Could not create directory " + d.toStdString());
 | 
					                throw std::runtime_error("Could not create directory " + d.toStdString());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto config_dir_vr = QString("%1%2").arg(dir, "vr");
 | 
				
			||||||
 | 
					    if(!Utils::dirExists(config_dir_vr)) {
 | 
				
			||||||
 | 
					        qDebug() << QString("Creating directory: %1").arg(config_dir_vr);
 | 
				
			||||||
 | 
					        if (!QDir().mkpath(config_dir_vr))
 | 
				
			||||||
 | 
					            throw std::runtime_error("Could not create directory " + config_dir_vr.toStdString());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AppContext::createWalletWithoutSpecifyingSeed(const QString &name, const QString &password) {
 | 
				
			||||||
 | 
					    WowletSeed seed = WowletSeed(this->restoreHeights[this->networkType], this->coinName, this->seedLanguage);
 | 
				
			||||||
 | 
					    auto path = QDir(this->defaultWalletDir).filePath(name);
 | 
				
			||||||
 | 
					    this->createWallet(seed, path, password);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AppContext::createWallet(WowletSeed seed, const QString &path, const QString &password) {
 | 
					void AppContext::createWallet(WowletSeed seed, const QString &path, const QString &password) {
 | 
				
			||||||
| 
						 | 
					@ -605,6 +641,9 @@ void AppContext::createWalletFinish(const QString &password) {
 | 
				
			||||||
    this->currentWallet->store();
 | 
					    this->currentWallet->store();
 | 
				
			||||||
    this->walletPassword = password;
 | 
					    this->walletPassword = password;
 | 
				
			||||||
    emit walletCreated(this->currentWallet);
 | 
					    emit walletCreated(this->currentWallet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // emit signal on behalf of walletManager, open wallet
 | 
				
			||||||
 | 
					    this->walletManager->walletOpened(this->currentWallet);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AppContext::initRestoreHeights() {
 | 
					void AppContext::initRestoreHeights() {
 | 
				
			||||||
| 
						 | 
					@ -798,6 +837,53 @@ void AppContext::onTransactionCreated(PendingTransaction *tx, const QVector<QStr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // tx created, but not sent yet. ask user to verify first.
 | 
					    // tx created, but not sent yet. ask user to verify first.
 | 
				
			||||||
    emit createTransactionSuccess(tx, address);
 | 
					    emit createTransactionSuccess(tx, address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(this->autoCommitTx) {
 | 
				
			||||||
 | 
					        this->currentWallet->commitTransactionAsync(tx);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString AppContext::getAddress(quint32 accountIndex, quint32 addressIndex) {
 | 
				
			||||||
 | 
					    return this->currentWallet->address(accountIndex, addressIndex);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AppContext::onAskReceivingPIN() {
 | 
				
			||||||
 | 
					    // request new receiving PIN from wowlet-backend
 | 
				
			||||||
 | 
					    if(this->currentWallet == nullptr)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto address = this->currentWallet->address(0, 1);
 | 
				
			||||||
 | 
					    QString signature = this->currentWallet->signMessage(address, false, address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QJsonObject data;
 | 
				
			||||||
 | 
					    data["signature"] = signature;
 | 
				
			||||||
 | 
					    data["address"] = address;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QJsonObject obj;
 | 
				
			||||||
 | 
					    obj["cmd"] = "requestPIN";
 | 
				
			||||||
 | 
					    obj["data"] = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QJsonDocument doc = QJsonDocument(obj);
 | 
				
			||||||
 | 
					    this->ws->sendMsg(doc.toJson(QJsonDocument::Compact));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AppContext::onLookupReceivingPIN(QString pin) {
 | 
				
			||||||
 | 
					    // lookup PIN -> address
 | 
				
			||||||
 | 
					    if(this->currentWallet == nullptr)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto address = this->currentWallet->address(0, 1);
 | 
				
			||||||
 | 
					    QString signature = this->currentWallet->signMessage(address, false, address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QJsonObject data;
 | 
				
			||||||
 | 
					    data["PIN"] = pin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QJsonObject obj;
 | 
				
			||||||
 | 
					    obj["cmd"] = "lookupPIN";
 | 
				
			||||||
 | 
					    obj["data"] = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QJsonDocument doc = QJsonDocument(obj);
 | 
				
			||||||
 | 
					    this->ws->sendMsg(doc.toJson(QJsonDocument::Compact));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AppContext::onTransactionCommitted(bool status, PendingTransaction *tx, const QStringList& txid){
 | 
					void AppContext::onTransactionCommitted(bool status, PendingTransaction *tx, const QStringList& txid){
 | 
				
			||||||
| 
						 | 
					@ -835,7 +921,13 @@ void AppContext::updateBalance() {
 | 
				
			||||||
    AppContext::balance = balance_u / globals::cdiv;
 | 
					    AppContext::balance = balance_u / globals::cdiv;
 | 
				
			||||||
    double spendable = this->currentWallet->unlockedBalance();
 | 
					    double spendable = this->currentWallet->unlockedBalance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // formatted
 | 
				
			||||||
 | 
					    QString fmt_str = QString("Balance: %1 WOW").arg(Utils::balanceFormat(spendable));
 | 
				
			||||||
 | 
					    if (balance > spendable)
 | 
				
			||||||
 | 
					        fmt_str += QString(" (+%1 WOW unconfirmed)").arg(Utils::balanceFormat(balance - spendable));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    emit balanceUpdated(balance_u, spendable);
 | 
					    emit balanceUpdated(balance_u, spendable);
 | 
				
			||||||
 | 
					    emit balanceUpdatedFormatted(fmt_str);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AppContext::syncStatusUpdated(quint64 height, quint64 target) {
 | 
					void AppContext::syncStatusUpdated(quint64 height, quint64 target) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,15 +54,20 @@ public:
 | 
				
			||||||
    QString accountName;
 | 
					    QString accountName;
 | 
				
			||||||
    QString configRoot;
 | 
					    QString configRoot;
 | 
				
			||||||
    QString configDirectory;
 | 
					    QString configDirectory;
 | 
				
			||||||
 | 
					    QString configDirectoryVR;
 | 
				
			||||||
    QString defaultWalletDir;
 | 
					    QString defaultWalletDir;
 | 
				
			||||||
    QString defaultWalletDirRoot;
 | 
					    QString defaultWalletDirRoot;
 | 
				
			||||||
    QString tmpTxDescription;
 | 
					    QString tmpTxDescription;
 | 
				
			||||||
 | 
					    QString wsUrl = "6wku2m4zrv6j666crlo7lzofv6ud6enzllyhou3ijeigpukymi37caad.onion";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QString walletPath;
 | 
					    QString walletPath;
 | 
				
			||||||
    QString walletPassword = "";
 | 
					    QString walletPassword = "";
 | 
				
			||||||
 | 
					    QString walletName;
 | 
				
			||||||
    bool walletViewOnly = false;
 | 
					    bool walletViewOnly = false;
 | 
				
			||||||
    NetworkType::Type networkType;
 | 
					    NetworkType::Type networkType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Q_PROPERTY(QString walletName MEMBER walletName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QString applicationPath;
 | 
					    QString applicationPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static void createConfigDirectory(const QString &dir) ;
 | 
					    static void createConfigDirectory(const QString &dir) ;
 | 
				
			||||||
| 
						 | 
					@ -73,6 +78,11 @@ public:
 | 
				
			||||||
    PendingTransaction::Priority tx_priority = PendingTransaction::Priority::Priority_Low;
 | 
					    PendingTransaction::Priority tx_priority = PendingTransaction::Priority::Priority_Low;
 | 
				
			||||||
    quint32 tx_mixin = static_cast<const quint32 &>(10);
 | 
					    quint32 tx_mixin = static_cast<const quint32 &>(10);
 | 
				
			||||||
    QString seedLanguage = "English";  // 14 word `monero-seed` only has English
 | 
					    QString seedLanguage = "English";  // 14 word `monero-seed` only has English
 | 
				
			||||||
 | 
					    // turn this on if you want to auto commit tx's after they have
 | 
				
			||||||
 | 
					    // been created. Caution while using this setting is advised. This
 | 
				
			||||||
 | 
					    // probably also breaks the default QtWidgets GUI. It is meant for
 | 
				
			||||||
 | 
					    // alternative users of AppContext.
 | 
				
			||||||
 | 
					    bool autoCommitTx = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QNetworkAccessManager *network;
 | 
					    QNetworkAccessManager *network;
 | 
				
			||||||
    QNetworkAccessManager *networkClearnet;
 | 
					    QNetworkAccessManager *networkClearnet;
 | 
				
			||||||
| 
						 | 
					@ -88,35 +98,45 @@ public:
 | 
				
			||||||
    static QMap<QString, QString> txDescriptionCache;
 | 
					    static QMap<QString, QString> txDescriptionCache;
 | 
				
			||||||
    static QMap<QString, QString> txCache;
 | 
					    static QMap<QString, QString> txCache;
 | 
				
			||||||
    static TxFiatHistory *txFiatHistory;
 | 
					    static TxFiatHistory *txFiatHistory;
 | 
				
			||||||
 | 
					    static bool isQML;
 | 
				
			||||||
    QList<WalletKeysFiles> listWallets() {
 | 
					 | 
				
			||||||
        // return listing of wallet .keys items
 | 
					 | 
				
			||||||
        m_walletKeysFilesModel->refresh();
 | 
					 | 
				
			||||||
        return m_walletKeysFilesModel->listWallets();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // libwalletqt
 | 
					    // libwalletqt
 | 
				
			||||||
    bool refreshed = false;
 | 
					    bool refreshed = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    WalletManager *walletManager;
 | 
					    WalletManager *walletManager;
 | 
				
			||||||
    Wallet *currentWallet = nullptr;
 | 
					    Wallet *currentWallet = nullptr;
 | 
				
			||||||
    void createWallet(WowletSeed seed, const QString &path, const QString &password);
 | 
					    void createWallet(WowletSeed seed, const QString &path, const QString &password);
 | 
				
			||||||
 | 
					    Q_INVOKABLE void createWalletWithoutSpecifyingSeed(const QString &name, const QString &password);
 | 
				
			||||||
    void createWalletViewOnly(const QString &path, const QString &password, const QString &address, const QString &viewkey, const QString &spendkey, quint64 restoreHeight);
 | 
					    void createWalletViewOnly(const QString &path, const QString &password, const QString &address, const QString &viewkey, const QString &spendkey, quint64 restoreHeight);
 | 
				
			||||||
    void createWalletFinish(const QString &password);
 | 
					    void createWalletFinish(const QString &password);
 | 
				
			||||||
    void syncStatusUpdated(quint64 height, quint64 target);
 | 
					    void syncStatusUpdated(quint64 height, quint64 target);
 | 
				
			||||||
    void updateBalance();
 | 
					    void updateBalance();
 | 
				
			||||||
    void initTor();
 | 
					    Q_INVOKABLE void initTor();
 | 
				
			||||||
 | 
					    Q_INVOKABLE void initWS();
 | 
				
			||||||
    void initRestoreHeights();
 | 
					    void initRestoreHeights();
 | 
				
			||||||
    void initWS();
 | 
					 | 
				
			||||||
    void donateBeg();
 | 
					    void donateBeg();
 | 
				
			||||||
    void refreshModels();
 | 
					    void refreshModels();
 | 
				
			||||||
    void setWindowTitle(bool mining = false);
 | 
					    void setWindowTitle(bool mining = false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Closes the currently opened wallet
 | 
					    // Closes the currently opened wallet
 | 
				
			||||||
    void closeWallet(bool emitClosedSignal = true, bool storeWallet = false);
 | 
					    Q_INVOKABLE void closeWallet(bool emitClosedSignal = true, bool storeWallet = false);
 | 
				
			||||||
    void storeWallet();
 | 
					    void storeWallet();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Q_INVOKABLE QVariantList listWallets() {
 | 
				
			||||||
 | 
					        m_walletKeysFilesModel->refresh();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        QVariantList list;
 | 
				
			||||||
 | 
					        for(const WalletKeysFiles &wallet: m_walletKeysFilesModel->listWallets())
 | 
				
			||||||
 | 
					            list << wallet.toVariant();
 | 
				
			||||||
 | 
					        return list;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Q_INVOKABLE QString displayAmount(quint64 amount) {
 | 
				
			||||||
 | 
					        return Utils::balanceFormat(amount);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public slots:
 | 
					public slots:
 | 
				
			||||||
    void onOpenWallet(const QString& path, const QString &password);
 | 
					    Q_INVOKABLE void onOpenWallet(const QString& path, const QString &password);
 | 
				
			||||||
    void onCreateTransaction(QString address, quint64 amount, const QString description, bool all);
 | 
					    void onCreateTransaction(QString address, quint64 amount, const QString description, bool all);
 | 
				
			||||||
    void onCreateTransactionMultiDest(const QVector<QString> &addresses, const QVector<quint64> &amounts, const QString &description);
 | 
					    void onCreateTransactionMultiDest(const QVector<QString> &addresses, const QVector<quint64> &amounts, const QString &description);
 | 
				
			||||||
    void onCancelTransaction(PendingTransaction *tx, const QVector<QString> &address);
 | 
					    void onCancelTransaction(PendingTransaction *tx, const QVector<QString> &address);
 | 
				
			||||||
| 
						 | 
					@ -125,6 +145,9 @@ public slots:
 | 
				
			||||||
    void onOpenAliasResolve(const QString &openAlias);
 | 
					    void onOpenAliasResolve(const QString &openAlias);
 | 
				
			||||||
    void onSetRestoreHeight(quint64 height);
 | 
					    void onSetRestoreHeight(quint64 height);
 | 
				
			||||||
    void onPreferredFiatCurrencyChanged(const QString &symbol);
 | 
					    void onPreferredFiatCurrencyChanged(const QString &symbol);
 | 
				
			||||||
 | 
					    Q_INVOKABLE void onAskReceivingPIN();
 | 
				
			||||||
 | 
					    Q_INVOKABLE void onLookupReceivingPIN(QString pin);
 | 
				
			||||||
 | 
					    Q_INVOKABLE QString getAddress(quint32 accountIndex, quint32 addressIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private slots:
 | 
					private slots:
 | 
				
			||||||
    void onWSNodes(const QJsonArray &nodes);
 | 
					    void onWSNodes(const QJsonArray &nodes);
 | 
				
			||||||
| 
						 | 
					@ -151,6 +174,7 @@ signals:
 | 
				
			||||||
    void walletClosed();
 | 
					    void walletClosed();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void balanceUpdated(quint64 balance, quint64 spendable);
 | 
					    void balanceUpdated(quint64 balance, quint64 spendable);
 | 
				
			||||||
 | 
					    void balanceUpdatedFormatted(QString fmt);
 | 
				
			||||||
    void blockchainSync(int height, int target);
 | 
					    void blockchainSync(int height, int target);
 | 
				
			||||||
    void refreshSync(int height, int target);
 | 
					    void refreshSync(int height, int target);
 | 
				
			||||||
    void synchronized();
 | 
					    void synchronized();
 | 
				
			||||||
| 
						 | 
					@ -165,12 +189,17 @@ signals:
 | 
				
			||||||
    void createTransactionError(QString message);
 | 
					    void createTransactionError(QString message);
 | 
				
			||||||
    void createTransactionCancelled(const QVector<QString> &address, double amount);
 | 
					    void createTransactionCancelled(const QVector<QString> &address, double amount);
 | 
				
			||||||
    void createTransactionSuccess(PendingTransaction *tx, const QVector<QString> &address);
 | 
					    void createTransactionSuccess(PendingTransaction *tx, const QVector<QString> &address);
 | 
				
			||||||
 | 
					    void wsConnected();
 | 
				
			||||||
 | 
					    void wsDisconnected();
 | 
				
			||||||
    void redditUpdated(QList<QSharedPointer<RedditPost>> &posts);
 | 
					    void redditUpdated(QList<QSharedPointer<RedditPost>> &posts);
 | 
				
			||||||
    void nodesUpdated(QList<QSharedPointer<WowletNode>> &nodes);
 | 
					    void nodesUpdated(QList<QSharedPointer<WowletNode>> &nodes);
 | 
				
			||||||
    void ccsUpdated(QList<QSharedPointer<CCSEntry>> &entries);
 | 
					    void ccsUpdated(QList<QSharedPointer<CCSEntry>> &entries);
 | 
				
			||||||
    void suchWowUpdated(const QJsonArray &such_data);
 | 
					    void suchWowUpdated(const QJsonArray &such_data);
 | 
				
			||||||
    void nodeSourceChanged(NodeSource nodeSource);
 | 
					    void nodeSourceChanged(NodeSource nodeSource);
 | 
				
			||||||
    void XMRigDownloads(const QJsonObject &data);
 | 
					    void XMRigDownloads(const QJsonObject &data);
 | 
				
			||||||
 | 
					    void pinLookupReceived(QString address, QString pin);
 | 
				
			||||||
 | 
					    void pinLookupErrorReceived();
 | 
				
			||||||
 | 
					    void pinReceived(QString pin);
 | 
				
			||||||
    void setCustomNodes(QList<WowletNode> nodes);
 | 
					    void setCustomNodes(QList<WowletNode> nodes);
 | 
				
			||||||
    void openAliasResolveError(const QString &msg);
 | 
					    void openAliasResolveError(const QString &msg);
 | 
				
			||||||
    void openAliasResolved(const QString &address, const QString &openAlias);
 | 
					    void openAliasResolved(const QString &address, const QString &openAlias);
 | 
				
			||||||
| 
						 | 
					@ -186,8 +215,6 @@ private:
 | 
				
			||||||
    WalletKeysFilesModel *m_walletKeysFilesModel;
 | 
					    WalletKeysFilesModel *m_walletKeysFilesModel;
 | 
				
			||||||
    const int m_donationBoundary = 15;
 | 
					    const int m_donationBoundary = 15;
 | 
				
			||||||
    QTimer m_storeTimer;
 | 
					    QTimer m_storeTimer;
 | 
				
			||||||
    // @TODO: Replace url
 | 
					 | 
				
			||||||
    QUrl m_wsUrl = QUrl(QStringLiteral("ws://feathercitimllbmdktu6cmjo3fizgmyfrntntqzu6xguqa2rlq5cgid.onion/ws"));
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif //WOWLET_APPCONTEXT_H
 | 
					#endif //WOWLET_APPCONTEXT_H
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,8 +36,10 @@ public:
 | 
				
			||||||
        LogLevel_Min = Monero::WalletManagerFactory::LogLevel_Min,
 | 
					        LogLevel_Min = Monero::WalletManagerFactory::LogLevel_Min,
 | 
				
			||||||
        LogLevel_Max = Monero::WalletManagerFactory::LogLevel_Max,
 | 
					        LogLevel_Max = Monero::WalletManagerFactory::LogLevel_Max,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					    explicit WalletManager(QObject *parent = nullptr);
 | 
				
			||||||
    static WalletManager * instance();
 | 
					    static WalletManager * instance();
 | 
				
			||||||
 | 
					    ~WalletManager();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // wizard: createWallet path;
 | 
					    // wizard: createWallet path;
 | 
				
			||||||
    Q_INVOKABLE Wallet * createWallet(const QString &path, const QString &password,
 | 
					    Q_INVOKABLE Wallet * createWallet(const QString &path, const QString &password,
 | 
				
			||||||
                                      const QString &language, NetworkType::Type nettype = NetworkType::MAINNET, quint64 kdfRounds = 1);
 | 
					                                      const QString &language, NetworkType::Type nettype = NetworkType::MAINNET, quint64 kdfRounds = 1);
 | 
				
			||||||
| 
						 | 
					@ -187,9 +189,6 @@ public slots:
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    friend class WalletPassphraseListenerImpl;
 | 
					    friend class WalletPassphraseListenerImpl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    explicit WalletManager(QObject *parent = 0);
 | 
					 | 
				
			||||||
    ~WalletManager();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool isMining() const;
 | 
					    bool isMining() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static WalletManager * m_instance;
 | 
					    static WalletManager * m_instance;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										34
									
								
								src/main.cpp
									
										
									
									
									
								
							
							
						
						| 
						 | 
					@ -10,6 +10,10 @@
 | 
				
			||||||
#include "mainwindow.h"
 | 
					#include "mainwindow.h"
 | 
				
			||||||
#include "cli.h"
 | 
					#include "cli.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAS_OPENVR
 | 
				
			||||||
 | 
					#include "vr/main.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(Q_OS_WIN)
 | 
					#if defined(Q_OS_WIN)
 | 
				
			||||||
#include <windows.h>
 | 
					#include <windows.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -84,6 +88,12 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
 | 
				
			||||||
    QCommandLineOption backgroundPasswordOption(QStringList() << "daemon-password", "Password for connecting to the wowlet websocket service", "backgroundPassword");
 | 
					    QCommandLineOption backgroundPasswordOption(QStringList() << "daemon-password", "Password for connecting to the wowlet websocket service", "backgroundPassword");
 | 
				
			||||||
    parser.addOption(backgroundPasswordOption);
 | 
					    parser.addOption(backgroundPasswordOption);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QCommandLineOption openVROption(QStringList() << "openvr", "Start Wowlet OpenVR");
 | 
				
			||||||
 | 
					    parser.addOption(openVROption);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QCommandLineOption openVRDebugOption(QStringList() << "openvr-debug", "Start the Wowlet VR interface without initializing OpenVR - for debugging purposes.");
 | 
				
			||||||
 | 
					    parser.addOption(openVRDebugOption);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto parsed = parser.parse(argv_);
 | 
					    auto parsed = parser.parse(argv_);
 | 
				
			||||||
    if(!parsed) {
 | 
					    if(!parsed) {
 | 
				
			||||||
        qCritical() << parser.errorText();
 | 
					        qCritical() << parser.errorText();
 | 
				
			||||||
| 
						 | 
					@ -99,17 +109,39 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
 | 
				
			||||||
    bool exportContacts = parser.isSet(exportContactsOption);
 | 
					    bool exportContacts = parser.isSet(exportContactsOption);
 | 
				
			||||||
    bool exportTxHistory = parser.isSet(exportTxHistoryOption);
 | 
					    bool exportTxHistory = parser.isSet(exportTxHistoryOption);
 | 
				
			||||||
    bool backgroundAddressEnabled = parser.isSet(backgroundOption);
 | 
					    bool backgroundAddressEnabled = parser.isSet(backgroundOption);
 | 
				
			||||||
 | 
					    bool openVREnabled = parser.isSet(openVROption);
 | 
				
			||||||
    bool cliMode = exportContacts || exportTxHistory || backgroundAddressEnabled;
 | 
					    bool cliMode = exportContacts || exportTxHistory || backgroundAddressEnabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qRegisterMetaType<QVector<QString>>();
 | 
					    qRegisterMetaType<QVector<QString>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAS_QML
 | 
				
			||||||
 | 
					    qputenv("QML_DISABLE_DISK_CACHE", "1");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(openVREnabled) {
 | 
				
			||||||
 | 
					#ifdef HAS_OPENVR
 | 
				
			||||||
 | 
					        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
 | 
				
			||||||
 | 
					        QApplication vr_app(argc, argv);
 | 
				
			||||||
 | 
					        auto *ctx = new AppContext(&parser);
 | 
				
			||||||
 | 
					        auto *vr = new wowletvr::WowletVR(ctx, &parser, &vr_app);
 | 
				
			||||||
 | 
					        if(vr->errors.length() > 0)
 | 
				
			||||||
 | 
					            return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        vr->render();
 | 
				
			||||||
 | 
					        return vr_app.exec();
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					        qCritical() << "Wowlet compiled without OpenVR support.";
 | 
				
			||||||
 | 
					        exit(1);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(cliMode) {
 | 
					    if(cliMode) {
 | 
				
			||||||
 | 
					        auto *ctx = new AppContext(&parser);
 | 
				
			||||||
        QCoreApplication cli_app(argc, argv);
 | 
					        QCoreApplication cli_app(argc, argv);
 | 
				
			||||||
        QCoreApplication::setApplicationName("wowlet");
 | 
					        QCoreApplication::setApplicationName("wowlet");
 | 
				
			||||||
        QCoreApplication::setOrganizationDomain("wownero.org");
 | 
					        QCoreApplication::setOrganizationDomain("wownero.org");
 | 
				
			||||||
        QCoreApplication::setOrganizationName("wownero.org");
 | 
					        QCoreApplication::setOrganizationName("wownero.org");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        auto *ctx = new AppContext(&parser);
 | 
					 | 
				
			||||||
        ctx->applicationPath = QString(argv[0]);
 | 
					        ctx->applicationPath = QString(argv[0]);
 | 
				
			||||||
        ctx->isDebug = debugMode;
 | 
					        ctx->isDebug = debugMode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -574,8 +574,6 @@ void MainWindow::onWalletOpenedError(const QString &err) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWindow::onWalletCreated(Wallet *wallet) {
 | 
					void MainWindow::onWalletCreated(Wallet *wallet) {
 | 
				
			||||||
    qDebug() << Q_FUNC_INFO;
 | 
					    qDebug() << Q_FUNC_INFO;
 | 
				
			||||||
    // emit signal on behalf of walletManager
 | 
					 | 
				
			||||||
    m_ctx->walletManager->walletOpened(wallet);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWindow::onWalletOpened(Wallet *wallet) {
 | 
					void MainWindow::onWalletOpened(Wallet *wallet) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,7 @@
 | 
				
			||||||
    <x>0</x>
 | 
					    <x>0</x>
 | 
				
			||||||
    <y>0</y>
 | 
					    <y>0</y>
 | 
				
			||||||
    <width>1156</width>
 | 
					    <width>1156</width>
 | 
				
			||||||
    <height>496</height>
 | 
					    <height>502</height>
 | 
				
			||||||
   </rect>
 | 
					   </rect>
 | 
				
			||||||
  </property>
 | 
					  </property>
 | 
				
			||||||
  <property name="sizePolicy">
 | 
					  <property name="sizePolicy">
 | 
				
			||||||
| 
						 | 
					@ -101,6 +101,28 @@
 | 
				
			||||||
          <property name="documentMode">
 | 
					          <property name="documentMode">
 | 
				
			||||||
           <bool>true</bool>
 | 
					           <bool>true</bool>
 | 
				
			||||||
          </property>
 | 
					          </property>
 | 
				
			||||||
 | 
					          <widget class="QWidget" name="tab_2">
 | 
				
			||||||
 | 
					           <attribute name="title">
 | 
				
			||||||
 | 
					            <string>/r/Wownero</string>
 | 
				
			||||||
 | 
					           </attribute>
 | 
				
			||||||
 | 
					           <layout class="QVBoxLayout" name="verticalLayout_7">
 | 
				
			||||||
 | 
					            <property name="leftMargin">
 | 
				
			||||||
 | 
					             <number>0</number>
 | 
				
			||||||
 | 
					            </property>
 | 
				
			||||||
 | 
					            <property name="topMargin">
 | 
				
			||||||
 | 
					             <number>0</number>
 | 
				
			||||||
 | 
					            </property>
 | 
				
			||||||
 | 
					            <property name="rightMargin">
 | 
				
			||||||
 | 
					             <number>0</number>
 | 
				
			||||||
 | 
					            </property>
 | 
				
			||||||
 | 
					            <property name="bottomMargin">
 | 
				
			||||||
 | 
					             <number>0</number>
 | 
				
			||||||
 | 
					            </property>
 | 
				
			||||||
 | 
					            <item>
 | 
				
			||||||
 | 
					             <widget class="RedditWidget" name="redditWidget" native="true"/>
 | 
				
			||||||
 | 
					            </item>
 | 
				
			||||||
 | 
					           </layout>
 | 
				
			||||||
 | 
					          </widget>
 | 
				
			||||||
          <widget class="QWidget" name="tab_3">
 | 
					          <widget class="QWidget" name="tab_3">
 | 
				
			||||||
           <attribute name="title">
 | 
					           <attribute name="title">
 | 
				
			||||||
            <string>SuchWow</string>
 | 
					            <string>SuchWow</string>
 | 
				
			||||||
| 
						 | 
					@ -152,28 +174,6 @@
 | 
				
			||||||
            </item>
 | 
					            </item>
 | 
				
			||||||
           </layout>
 | 
					           </layout>
 | 
				
			||||||
          </widget>
 | 
					          </widget>
 | 
				
			||||||
          <widget class="QWidget" name="tab_2">
 | 
					 | 
				
			||||||
           <attribute name="title">
 | 
					 | 
				
			||||||
            <string>/r/Wownero</string>
 | 
					 | 
				
			||||||
           </attribute>
 | 
					 | 
				
			||||||
           <layout class="QVBoxLayout" name="verticalLayout_7">
 | 
					 | 
				
			||||||
            <property name="leftMargin">
 | 
					 | 
				
			||||||
             <number>0</number>
 | 
					 | 
				
			||||||
            </property>
 | 
					 | 
				
			||||||
            <property name="topMargin">
 | 
					 | 
				
			||||||
             <number>0</number>
 | 
					 | 
				
			||||||
            </property>
 | 
					 | 
				
			||||||
            <property name="rightMargin">
 | 
					 | 
				
			||||||
             <number>0</number>
 | 
					 | 
				
			||||||
            </property>
 | 
					 | 
				
			||||||
            <property name="bottomMargin">
 | 
					 | 
				
			||||||
             <number>0</number>
 | 
					 | 
				
			||||||
            </property>
 | 
					 | 
				
			||||||
            <item>
 | 
					 | 
				
			||||||
             <widget class="RedditWidget" name="redditWidget" native="true"/>
 | 
					 | 
				
			||||||
            </item>
 | 
					 | 
				
			||||||
           </layout>
 | 
					 | 
				
			||||||
          </widget>
 | 
					 | 
				
			||||||
         </widget>
 | 
					         </widget>
 | 
				
			||||||
        </item>
 | 
					        </item>
 | 
				
			||||||
       </layout>
 | 
					       </layout>
 | 
				
			||||||
| 
						 | 
					@ -326,7 +326,7 @@
 | 
				
			||||||
     <x>0</x>
 | 
					     <x>0</x>
 | 
				
			||||||
     <y>0</y>
 | 
					     <y>0</y>
 | 
				
			||||||
     <width>1156</width>
 | 
					     <width>1156</width>
 | 
				
			||||||
     <height>30</height>
 | 
					     <height>20</height>
 | 
				
			||||||
    </rect>
 | 
					    </rect>
 | 
				
			||||||
   </property>
 | 
					   </property>
 | 
				
			||||||
   <widget class="QMenu" name="menuFile">
 | 
					   <widget class="QMenu" name="menuFile">
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,7 +51,12 @@ int TransactionHistoryModel::columnCount(const QModelIndex &parent) const {
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return Column::COUNT;
 | 
					    // When wowlet is in QtWidgets mode, it will only use the first 5 columns,
 | 
				
			||||||
 | 
					    // the rest should be hidden, because it shows in the GUI. So by default we'll
 | 
				
			||||||
 | 
					    // use 5 as column count. When in QtQuick (QML) mode, we want to expose more columns
 | 
				
			||||||
 | 
					    // so we can change the column count here.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return AppContext::isQML ? this->COUNT : 5;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const {
 | 
					QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const {
 | 
				
			||||||
| 
						 | 
					@ -70,14 +75,14 @@ QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (role == Qt::TextAlignmentRole) {
 | 
					        else if (role == Qt::TextAlignmentRole) {
 | 
				
			||||||
            switch (index.column()) {
 | 
					            switch (index.column()) {
 | 
				
			||||||
                case Column::Amount:
 | 
					                case TransactionInfoRole::Amount:
 | 
				
			||||||
                case Column::FiatAmount:
 | 
					                case TransactionInfoRole::FiatAmount:
 | 
				
			||||||
                    result = Qt::AlignRight;
 | 
					                    result = Qt::AlignRight;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (role == Qt::DecorationRole) {
 | 
					        else if (role == Qt::DecorationRole) {
 | 
				
			||||||
            switch (index.column()) {
 | 
					            switch (index.column()) {
 | 
				
			||||||
                case Column::Date:
 | 
					                case TransactionInfoRole::Date:
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (tInfo.isFailed())
 | 
					                    if (tInfo.isFailed())
 | 
				
			||||||
                        result = QVariant(m_warning);
 | 
					                        result = QVariant(m_warning);
 | 
				
			||||||
| 
						 | 
					@ -100,7 +105,7 @@ QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (role == Qt::ToolTipRole) {
 | 
					        else if (role == Qt::ToolTipRole) {
 | 
				
			||||||
            switch(index.column()) {
 | 
					            switch(index.column()) {
 | 
				
			||||||
                case Column::Date:
 | 
					                case TransactionInfoRole::Date:
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (tInfo.isFailed())
 | 
					                    if (tInfo.isFailed())
 | 
				
			||||||
                        result = "Transaction failed";
 | 
					                        result = "Transaction failed";
 | 
				
			||||||
| 
						 | 
					@ -113,8 +118,8 @@ QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (role == Qt::ForegroundRole) {
 | 
					        else if (role == Qt::ForegroundRole) {
 | 
				
			||||||
            switch(index.column()) {
 | 
					            switch(index.column()) {
 | 
				
			||||||
                case Column::FiatAmount:
 | 
					                case TransactionInfoRole::FiatAmount:
 | 
				
			||||||
                case Column::Amount:
 | 
					                case TransactionInfoRole::Amount:
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (tInfo.direction() == TransactionInfo::Direction_Out) {
 | 
					                    if (tInfo.direction() == TransactionInfo::Direction_Out) {
 | 
				
			||||||
                        result = QVariant(QColor("#BC1E1E"));
 | 
					                        result = QVariant(QColor("#BC1E1E"));
 | 
				
			||||||
| 
						 | 
					@ -134,9 +139,19 @@ QVariant TransactionHistoryModel::parseTransactionInfo(const TransactionInfo &tI
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    switch (column)
 | 
					    switch (column)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        case Column::Date:
 | 
					        case TransactionInfoRole::TransactionFailedRole:
 | 
				
			||||||
 | 
					            return tInfo.isFailed();
 | 
				
			||||||
 | 
					        case TransactionInfoRole::TransactionPendingRole:
 | 
				
			||||||
 | 
					            return tInfo.isPending();
 | 
				
			||||||
 | 
					        case TransactionInfoRole::TransactionConfirmationsRole:
 | 
				
			||||||
 | 
					            return tInfo.confirmations();
 | 
				
			||||||
 | 
					        case TransactionInfoRole::TransactionConfirmationsRequiredRole:
 | 
				
			||||||
 | 
					            return tInfo.confirmationsRequired();
 | 
				
			||||||
 | 
					        case TransactionInfoRole::Date:
 | 
				
			||||||
            return tInfo.timestamp().toString("yyyy-MM-dd HH:mm");
 | 
					            return tInfo.timestamp().toString("yyyy-MM-dd HH:mm");
 | 
				
			||||||
        case Column::Description: {
 | 
					        case TransactionInfoRole::TransactionIsOutRole:
 | 
				
			||||||
 | 
					            return tInfo.direction() == TransactionInfo::Direction_Out;
 | 
				
			||||||
 | 
					        case TransactionInfoRole::Description: {
 | 
				
			||||||
            // if this tx is still in the pool, then we wont get the
 | 
					            // if this tx is still in the pool, then we wont get the
 | 
				
			||||||
            // description. We've cached it inside `AppContext::txDescriptionCache`
 | 
					            // description. We've cached it inside `AppContext::txDescriptionCache`
 | 
				
			||||||
            // for the time being.
 | 
					            // for the time being.
 | 
				
			||||||
| 
						 | 
					@ -147,15 +162,15 @@ QVariant TransactionHistoryModel::parseTransactionInfo(const TransactionInfo &tI
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return tInfo.description();
 | 
					            return tInfo.description();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        case Column::Amount:
 | 
					        case TransactionInfoRole::Amount:
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            QString amount = QString::number(tInfo.balanceDelta() / globals::cdiv, 'f', 4);
 | 
					            QString amount = QString::number(tInfo.balanceDelta() / globals::cdiv, 'f', 4);
 | 
				
			||||||
            amount = (tInfo.direction() == TransactionInfo::Direction_Out) ? "-" + amount : "+" + amount;
 | 
					            amount = (tInfo.direction() == TransactionInfo::Direction_Out) ? "-" + amount : "+" + amount;
 | 
				
			||||||
            return amount;
 | 
					            return amount;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        case Column::TxID:
 | 
					        case TransactionInfoRole::TxID:
 | 
				
			||||||
            return tInfo.hash();
 | 
					            return tInfo.hash();
 | 
				
			||||||
        case Column::FiatAmount:
 | 
					        case TransactionInfoRole::FiatAmount:
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            double usd_price = AppContext::txFiatHistory->get(tInfo.timestamp().toString("yyyyMMdd"));
 | 
					            double usd_price = AppContext::txFiatHistory->get(tInfo.timestamp().toString("yyyyMMdd"));
 | 
				
			||||||
            if (usd_price == 0.0)
 | 
					            if (usd_price == 0.0)
 | 
				
			||||||
| 
						 | 
					@ -183,15 +198,15 @@ QVariant TransactionHistoryModel::headerData(int section, Qt::Orientation orient
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (orientation == Qt::Horizontal) {
 | 
					    if (orientation == Qt::Horizontal) {
 | 
				
			||||||
        switch(section) {
 | 
					        switch(section) {
 | 
				
			||||||
            case Column::Date:
 | 
					            case TransactionInfoRole::Date:
 | 
				
			||||||
                return QString("Date");
 | 
					                return QString("Date");
 | 
				
			||||||
            case Column::Description:
 | 
					            case TransactionInfoRole::Description:
 | 
				
			||||||
                return QString("Description");
 | 
					                return QString("Description");
 | 
				
			||||||
            case Column::Amount:
 | 
					            case TransactionInfoRole::Amount:
 | 
				
			||||||
                return QString("Amount");
 | 
					                return QString("Amount");
 | 
				
			||||||
            case Column::TxID:
 | 
					            case TransactionInfoRole::TxID:
 | 
				
			||||||
                return QString("Txid");
 | 
					                return QString("Txid");
 | 
				
			||||||
            case Column::FiatAmount:
 | 
					            case TransactionInfoRole::FiatAmount:
 | 
				
			||||||
                return QString("Fiat");
 | 
					                return QString("Fiat");
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
                return QVariant();
 | 
					                return QVariant();
 | 
				
			||||||
| 
						 | 
					@ -205,7 +220,7 @@ bool TransactionHistoryModel::setData(const QModelIndex &index, const QVariant &
 | 
				
			||||||
        QString hash;
 | 
					        QString hash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        switch (index.column()) {
 | 
					        switch (index.column()) {
 | 
				
			||||||
            case Column::Description:
 | 
					            case TransactionInfoRole::Description:
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                m_transactionHistory->transaction(index.row(), [this, &hash, &value](const TransactionInfo &tInfo){
 | 
					                m_transactionHistory->transaction(index.row(), [this, &hash, &value](const TransactionInfo &tInfo){
 | 
				
			||||||
                    hash = tInfo.hash();
 | 
					                    hash = tInfo.hash();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,15 +21,21 @@ class TransactionHistoryModel : public QAbstractTableModel
 | 
				
			||||||
    Q_PROPERTY(TransactionHistory * transactionHistory READ transactionHistory WRITE setTransactionHistory NOTIFY transactionHistoryChanged)
 | 
					    Q_PROPERTY(TransactionHistory * transactionHistory READ transactionHistory WRITE setTransactionHistory NOTIFY transactionHistoryChanged)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    enum Column
 | 
					    enum TransactionInfoRole
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Date = 0,
 | 
					        Date = 0,
 | 
				
			||||||
        Description,
 | 
					        Description,
 | 
				
			||||||
        Amount,
 | 
					        Amount,
 | 
				
			||||||
        TxID,
 | 
					        TxID,
 | 
				
			||||||
        FiatAmount,
 | 
					        FiatAmount,
 | 
				
			||||||
 | 
					        TransactionIsOutRole,
 | 
				
			||||||
 | 
					        TransactionFailedRole,
 | 
				
			||||||
 | 
					        TransactionPendingRole,
 | 
				
			||||||
 | 
					        TransactionConfirmationsRole,
 | 
				
			||||||
 | 
					        TransactionConfirmationsRequiredRole,
 | 
				
			||||||
        COUNT
 | 
					        COUNT
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					    Q_ENUM(TransactionInfoRole)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    explicit TransactionHistoryModel(QObject * parent = nullptr);
 | 
					    explicit TransactionHistoryModel(QObject * parent = nullptr);
 | 
				
			||||||
    void setTransactionHistory(TransactionHistory * th);
 | 
					    void setTransactionHistory(TransactionHistory * th);
 | 
				
			||||||
| 
						 | 
					@ -44,6 +50,7 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool setData(const QModelIndex &index, const QVariant &value, int role) override;
 | 
					    bool setData(const QModelIndex &index, const QVariant &value, int role) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int customColumnCount = 5;
 | 
				
			||||||
signals:
 | 
					signals:
 | 
				
			||||||
    void transactionHistoryChanged();
 | 
					    void transactionHistoryChanged();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,8 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {
 | 
				
			||||||
        {Config::homeWidget,{QS("homeWidget"), "ccs"}},
 | 
					        {Config::homeWidget,{QS("homeWidget"), "ccs"}},
 | 
				
			||||||
        {Config::donateBeg,{QS("donateBeg"), 1}},
 | 
					        {Config::donateBeg,{QS("donateBeg"), 1}},
 | 
				
			||||||
        {Config::skin,{QS("skin"), "light"}},
 | 
					        {Config::skin,{QS("skin"), "light"}},
 | 
				
			||||||
 | 
					        {Config::openVRSkin,{QS("openVRSkin"), "default"}},
 | 
				
			||||||
 | 
					        {Config::openVRStreamerMode,{QS("openVRStreamerMode"), false}},
 | 
				
			||||||
        {Config::preferredFiatCurrency,{QS("preferredFiatCurrency"), "USD"}},
 | 
					        {Config::preferredFiatCurrency,{QS("preferredFiatCurrency"), "USD"}},
 | 
				
			||||||
        {Config::blockExplorer,{QS("blockExplorer"), "explore.wownero.com"}},
 | 
					        {Config::blockExplorer,{QS("blockExplorer"), "explore.wownero.com"}},
 | 
				
			||||||
        {Config::walletDirectory,{QS("walletDirectory"), ""}},
 | 
					        {Config::walletDirectory,{QS("walletDirectory"), ""}},
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,6 +28,8 @@ public:
 | 
				
			||||||
        donateBeg,
 | 
					        donateBeg,
 | 
				
			||||||
        autoOpenWalletPath,
 | 
					        autoOpenWalletPath,
 | 
				
			||||||
        skin,
 | 
					        skin,
 | 
				
			||||||
 | 
					        openVRSkin,
 | 
				
			||||||
 | 
					        openVRStreamerMode,
 | 
				
			||||||
        preferredFiatCurrency,
 | 
					        preferredFiatCurrency,
 | 
				
			||||||
        blockExplorer,
 | 
					        blockExplorer,
 | 
				
			||||||
        walletDirectory,
 | 
					        walletDirectory,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,6 +13,7 @@
 | 
				
			||||||
using namespace std::chrono;
 | 
					using namespace std::chrono;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WalletKeysFiles::WalletKeysFiles() = default;  // to please Q_DECLARE_METATYPE
 | 
				
			||||||
WalletKeysFiles::WalletKeysFiles(const QFileInfo &info, int networkType, QString address) :
 | 
					WalletKeysFiles::WalletKeysFiles(const QFileInfo &info, int networkType, QString address) :
 | 
				
			||||||
        m_fileName(info.fileName()),
 | 
					        m_fileName(info.fileName()),
 | 
				
			||||||
        m_modified(info.lastModified().toSecsSinceEpoch()),
 | 
					        m_modified(info.lastModified().toSecsSinceEpoch()),
 | 
				
			||||||
| 
						 | 
					@ -47,6 +48,10 @@ int WalletKeysFiles::networkType() const {
 | 
				
			||||||
    return m_networkType;
 | 
					    return m_networkType;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QVariant WalletKeysFiles::toVariant() const {
 | 
				
			||||||
 | 
					    return QVariant::fromValue<WalletKeysFiles>(*this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QJsonObject WalletKeysFiles::toJsonObject() const {
 | 
					QJsonObject WalletKeysFiles::toJsonObject() const {
 | 
				
			||||||
    auto item = QJsonObject();
 | 
					    auto item = QJsonObject();
 | 
				
			||||||
    item["fileName"] = m_fileName;
 | 
					    item["fileName"] = m_fileName;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,9 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class WalletKeysFiles
 | 
					class WalletKeysFiles
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Q_GADGET
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					    WalletKeysFiles();
 | 
				
			||||||
    WalletKeysFiles(const QFileInfo &info, int networkType, QString address);
 | 
					    WalletKeysFiles(const QFileInfo &info, int networkType, QString address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QString fileName() const;
 | 
					    QString fileName() const;
 | 
				
			||||||
| 
						 | 
					@ -20,6 +22,13 @@ public:
 | 
				
			||||||
    QString address() const;
 | 
					    QString address() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QJsonObject toJsonObject() const;
 | 
					    QJsonObject toJsonObject() const;
 | 
				
			||||||
 | 
					    QVariant toVariant() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Q_PROPERTY(qint64 modified READ modified)
 | 
				
			||||||
 | 
					    Q_PROPERTY(QString fileName READ fileName)
 | 
				
			||||||
 | 
					    Q_PROPERTY(QString path READ path)
 | 
				
			||||||
 | 
					    Q_PROPERTY(QString address READ address)
 | 
				
			||||||
 | 
					    Q_PROPERTY(int networkType READ networkType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    QString m_fileName;
 | 
					    QString m_fileName;
 | 
				
			||||||
| 
						 | 
					@ -28,6 +37,8 @@ private:
 | 
				
			||||||
    int m_networkType;
 | 
					    int m_networkType;
 | 
				
			||||||
    QString m_address;
 | 
					    QString m_address;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					Q_DECLARE_METATYPE(WalletKeysFiles)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class WalletKeysFilesModel : public QAbstractTableModel
 | 
					class WalletKeysFilesModel : public QAbstractTableModel
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,7 +38,7 @@ void Prices::cryptoPricesReceived(const QJsonArray &data) {
 | 
				
			||||||
    for(auto &&entry: data) {
 | 
					    for(auto &&entry: data) {
 | 
				
			||||||
        marketStruct ms;
 | 
					        marketStruct ms;
 | 
				
			||||||
        QJsonObject obj = entry.toObject();
 | 
					        QJsonObject obj = entry.toObject();
 | 
				
			||||||
        ms.symbol = obj.value("symbol").toString();
 | 
					        ms.symbol = obj.value("symbol").toString().toUpper();
 | 
				
			||||||
        ms.image = obj.value("image").toString();
 | 
					        ms.image = obj.value("image").toString();
 | 
				
			||||||
        ms.name = obj.value("name").toString();
 | 
					        ms.name = obj.value("name").toString();
 | 
				
			||||||
        ms.price_usd = obj.value("current_price").toDouble();
 | 
					        ms.price_usd = obj.value("current_price").toDouble();
 | 
				
			||||||
| 
						 | 
					@ -85,9 +85,8 @@ double Prices::convert(const QString &symbolFrom, const QString &symbolTo, doubl
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Prices::fiatPricesReceived(const QJsonObject &data) {
 | 
					void Prices::fiatPricesReceived(const QJsonObject &data) {
 | 
				
			||||||
    QJsonObject rates = data.value("rates").toObject();
 | 
					 | 
				
			||||||
    for(const auto ¤cy: fiat.keys())
 | 
					    for(const auto ¤cy: fiat.keys())
 | 
				
			||||||
        if(rates.contains(currency))
 | 
					        if(data.contains(currency))
 | 
				
			||||||
            this->rates.insert(currency, rates.value(currency).toDouble());
 | 
					            this->rates.insert(currency, data.value(currency).toDouble());
 | 
				
			||||||
    emit fiatPricesUpdated();
 | 
					    emit fiatPricesUpdated();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,6 +42,12 @@ QByteArray Utils::fileOpen(const QString &path) {
 | 
				
			||||||
    return data;
 | 
					    return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qint64 Utils::fileModifiedAge(const QString &path) {
 | 
				
			||||||
 | 
					    QFileInfo fileInfo;
 | 
				
			||||||
 | 
					    fileInfo.setFile(path);
 | 
				
			||||||
 | 
					    return (QDateTime::currentSecsSinceEpoch() - fileInfo.lastModified().toSecsSinceEpoch());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QByteArray Utils::fileOpenQRC(const QString &path) {
 | 
					QByteArray Utils::fileOpenQRC(const QString &path) {
 | 
				
			||||||
    QFile file(path);
 | 
					    QFile file(path);
 | 
				
			||||||
    if(!file.open(QIODevice::ReadOnly)) {
 | 
					    if(!file.open(QIODevice::ReadOnly)) {
 | 
				
			||||||
| 
						 | 
					@ -399,6 +405,11 @@ QLocale Utils::getCurrencyLocale(const QString ¤cyCode) {
 | 
				
			||||||
    return locale;
 | 
					    return locale;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					double Utils::roundUp(double value, int decimal_places) {
 | 
				
			||||||
 | 
					    const double multiplier = std::pow(10.0, decimal_places);
 | 
				
			||||||
 | 
					    return std::ceil(value * multiplier) / multiplier;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QString Utils::amountToCurrencyString(double amount, const QString ¤cyCode) {
 | 
					QString Utils::amountToCurrencyString(double amount, const QString ¤cyCode) {
 | 
				
			||||||
    QLocale locale = getCurrencyLocale(currencyCode);
 | 
					    QLocale locale = getCurrencyLocale(currencyCode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,6 +46,7 @@ public:
 | 
				
			||||||
    static bool fileExists(const QString &path);
 | 
					    static bool fileExists(const QString &path);
 | 
				
			||||||
    static QByteArray fileOpen(const QString &path);
 | 
					    static QByteArray fileOpen(const QString &path);
 | 
				
			||||||
    static QByteArray fileOpenQRC(const QString &path);
 | 
					    static QByteArray fileOpenQRC(const QString &path);
 | 
				
			||||||
 | 
					    static qint64 fileModifiedAge(const QString &path);
 | 
				
			||||||
    static void desktopNotify(const QString &title, const QString &message, int duration);
 | 
					    static void desktopNotify(const QString &title, const QString &message, int duration);
 | 
				
			||||||
    static bool fileWrite(const QString &path, const QString &data);
 | 
					    static bool fileWrite(const QString &path, const QString &data);
 | 
				
			||||||
    static QStringList fileFind(const QRegExp &pattern, const QString &baseDir, int level, int depth, int maxPerDir);
 | 
					    static QStringList fileFind(const QRegExp &pattern, const QString &baseDir, int level, int depth, int maxPerDir);
 | 
				
			||||||
| 
						 | 
					@ -73,6 +74,7 @@ public:
 | 
				
			||||||
    static QLocale getCurrencyLocale(const QString ¤cyCode);
 | 
					    static QLocale getCurrencyLocale(const QString ¤cyCode);
 | 
				
			||||||
    static QString amountToCurrencyString(double amount, const QString ¤cyCode);
 | 
					    static QString amountToCurrencyString(double amount, const QString ¤cyCode);
 | 
				
			||||||
    static int maxLength(const QVector<QString> &array);
 | 
					    static int maxLength(const QVector<QString> &array);
 | 
				
			||||||
 | 
					    static double roundUp(double value, int decimal_places);
 | 
				
			||||||
    static QMap<QString, QLocale> localeCache;
 | 
					    static QMap<QString, QLocale> localeCache;
 | 
				
			||||||
    static QString balanceFormat(quint64 balance);
 | 
					    static QString balanceFormat(quint64 balance);
 | 
				
			||||||
    static QTextCharFormat addressTextFormat(const SubaddressIndex &index);
 | 
					    static QTextCharFormat addressTextFormat(const SubaddressIndex &index);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,16 +8,16 @@
 | 
				
			||||||
#include "wsclient.h"
 | 
					#include "wsclient.h"
 | 
				
			||||||
#include "appcontext.h"
 | 
					#include "appcontext.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WSClient::WSClient(AppContext *ctx, const QUrl &url, QObject *parent) :
 | 
					WSClient::WSClient(AppContext *ctx, const QString &url, QObject *parent) :
 | 
				
			||||||
        QObject(parent),
 | 
					        QObject(parent),
 | 
				
			||||||
        url(url),
 | 
					 | 
				
			||||||
        m_ctx(ctx) {
 | 
					        m_ctx(ctx) {
 | 
				
			||||||
    connect(&this->webSocket, &QWebSocket::binaryMessageReceived, this, &WSClient::onbinaryMessageReceived);
 | 
					    connect(&this->webSocket, &QWebSocket::binaryMessageReceived, this, &WSClient::onbinaryMessageReceived);
 | 
				
			||||||
    connect(&this->webSocket, &QWebSocket::connected, this, &WSClient::onConnected);
 | 
					    connect(&this->webSocket, &QWebSocket::connected, this, &WSClient::onConnected);
 | 
				
			||||||
    connect(&this->webSocket, &QWebSocket::disconnected, this, &WSClient::closed);
 | 
					    connect(&this->webSocket, &QWebSocket::disconnected, this, &WSClient::closed);
 | 
				
			||||||
    connect(&this->webSocket, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error), this, &WSClient::onError);
 | 
					    connect(&this->webSocket, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error), this, &WSClient::onError);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    m_tor = url.host().endsWith(".onion");
 | 
					    m_tor = url.contains(".onion");
 | 
				
			||||||
 | 
					    this->url = QString("ws://%1/ws").arg(url);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Keep websocket connection alive
 | 
					    // Keep websocket connection alive
 | 
				
			||||||
    connect(&m_pingTimer, &QTimer::timeout, [this]{
 | 
					    connect(&m_pingTimer, &QTimer::timeout, [this]{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,11 +14,11 @@ class WSClient : public QObject
 | 
				
			||||||
    Q_OBJECT
 | 
					    Q_OBJECT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    explicit WSClient(AppContext *ctx, const QUrl &url, QObject *parent = nullptr);
 | 
					    explicit WSClient(AppContext *ctx, const QString &url, QObject *parent = nullptr);
 | 
				
			||||||
    void start();
 | 
					    void start();
 | 
				
			||||||
    void sendMsg(const QByteArray &data);
 | 
					    void sendMsg(const QByteArray &data);
 | 
				
			||||||
    QWebSocket webSocket;
 | 
					    QWebSocket webSocket;
 | 
				
			||||||
    QUrl url;
 | 
					    QString url;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
signals:
 | 
					signals:
 | 
				
			||||||
    void closed();
 | 
					    void closed();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,6 +38,9 @@ WSServer::WSServer(AppContext *ctx, const QHostAddress &host, const quint16 port
 | 
				
			||||||
    if (!m_pWebSocketServer->listen(QHostAddress::Any, port))
 | 
					    if (!m_pWebSocketServer->listen(QHostAddress::Any, port))
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // turn on auto tx commits
 | 
				
			||||||
 | 
					    ctx->autoCommitTx = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qDebug() << "websocket server listening on port" << port;
 | 
					    qDebug() << "websocket server listening on port" << port;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    connect(m_pWebSocketServer, &QWebSocketServer::newConnection, this, &WSServer::onNewConnection);
 | 
					    connect(m_pWebSocketServer, &QWebSocketServer::newConnection, this, &WSServer::onNewConnection);
 | 
				
			||||||
| 
						 | 
					@ -80,8 +83,8 @@ void WSServer::onNewConnection() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // blast wallet listing on connect
 | 
					    // blast wallet listing on connect
 | 
				
			||||||
    QJsonArray arr;
 | 
					    QJsonArray arr;
 | 
				
			||||||
    for(const WalletKeysFiles &wallet: m_ctx->listWallets())
 | 
					    for(const QVariant &wallet: m_ctx->listWallets())
 | 
				
			||||||
        arr << wallet.toJsonObject();
 | 
					        arr << wallet.value<WalletKeysFiles>().toJsonObject();
 | 
				
			||||||
    auto welcomeWalletMessage = WSServer::createWSMessage("walletList", arr);
 | 
					    auto welcomeWalletMessage = WSServer::createWSMessage("walletList", arr);
 | 
				
			||||||
    pSocket->sendBinaryMessage(welcomeWalletMessage);
 | 
					    pSocket->sendBinaryMessage(welcomeWalletMessage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -336,9 +339,6 @@ void WSServer::onWalletCreatedError(const QString &err) {
 | 
				
			||||||
void WSServer::onWalletCreated(Wallet *wallet) {
 | 
					void WSServer::onWalletCreated(Wallet *wallet) {
 | 
				
			||||||
    auto obj = wallet->toJsonObject();
 | 
					    auto obj = wallet->toJsonObject();
 | 
				
			||||||
    sendAll("walletCreated", obj);
 | 
					    sendAll("walletCreated", obj);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // emit signal on behalf of walletManager
 | 
					 | 
				
			||||||
    m_ctx->walletManager->walletOpened(wallet);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void WSServer::onSynchronized() {
 | 
					void WSServer::onSynchronized() {
 | 
				
			||||||
| 
						 | 
					@ -350,7 +350,7 @@ void WSServer::onWalletOpenPasswordRequired(bool invalidPassword, const QString
 | 
				
			||||||
    QJsonObject obj;
 | 
					    QJsonObject obj;
 | 
				
			||||||
    obj["invalidPassword"] = invalidPassword;
 | 
					    obj["invalidPassword"] = invalidPassword;
 | 
				
			||||||
    obj["path"] = path;
 | 
					    obj["path"] = path;
 | 
				
			||||||
    sendAll("synchronized", obj);
 | 
					    sendAll("walletOpenPasswordRequired", obj);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void WSServer::onConnectionStatusChanged(int status) {
 | 
					void WSServer::onConnectionStatusChanged(int status) {
 | 
				
			||||||
| 
						 | 
					@ -367,8 +367,7 @@ void WSServer::onCreateTransactionError(const QString &message) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void WSServer::onCreateTransactionSuccess(PendingTransaction *tx, const QVector<QString> &address) {
 | 
					void WSServer::onCreateTransactionSuccess(PendingTransaction *tx, const QVector<QString> &address) {
 | 
				
			||||||
    // auto-commit all tx's
 | 
					
 | 
				
			||||||
    m_ctx->currentWallet->commitTransactionAsync(tx);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void WSServer::onTransactionCommitted(bool status, PendingTransaction *tx, const QStringList &txid) {
 | 
					void WSServer::onTransactionCommitted(bool status, PendingTransaction *tx, const QStringList &txid) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/alarm/alarm_activated.png
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.6 KiB  | 
							
								
								
									
										12
									
								
								src/vr/assets/img/audio/media_keys/outline_play_pause_white_24dp.svg
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
 | 
				
			||||||
 | 
					<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
 | 
				
			||||||
 | 
						 viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
 | 
				
			||||||
 | 
					<style type="text/css">
 | 
				
			||||||
 | 
						.st0{fill:none;}
 | 
				
			||||||
 | 
						.st1{fill:#FFFFFF;}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					<path class="st0" d="M0,0h24v24H0V0z"/>
 | 
				
			||||||
 | 
					<path class="st1" d="M5,8.6l5.3,3.4L5,15.4V8.6 M3,5v14l11-7L3,5z"/>
 | 
				
			||||||
 | 
					<path class="st1" d="M14,19h2.3V5H14V19z M18.7,5v14H21V5H18.7z"/>
 | 
				
			||||||
 | 
					</svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 598 B  | 
							
								
								
									
										1
									
								
								src/vr/assets/img/audio/media_keys/outline_skip_next_white_24dp.svg
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path fill="white" d="M6 18l8.5-6L6 6v12zm2-8.14L11.03 12 8 14.14V9.86zM16 6h2v12h-2z"/></svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 216 B  | 
							
								
								
									
										1
									
								
								src/vr/assets/img/audio/media_keys/outline_skip_previous_white_24dp.svg
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path fill="white" d="M6 6h2v12H6zm3.5 6l8.5 6V6l-8.5 6zm6.5 2.14L12.97 12 16 9.86v4.28z"/></svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 219 B  | 
							
								
								
									
										1
									
								
								src/vr/assets/img/audio/media_keys/outline_stop_white_24dp.svg
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path fill="white" d="M16 8v8H8V8h8m2-2H6v12h12V6z"/></svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 181 B  | 
							
								
								
									
										75
									
								
								src/vr/assets/img/audio/microphone/mic_off.svg
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,75 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
				
			||||||
 | 
					<svg
 | 
				
			||||||
 | 
					   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
				
			||||||
 | 
					   xmlns:cc="http://creativecommons.org/ns#"
 | 
				
			||||||
 | 
					   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
				
			||||||
 | 
					   xmlns:svg="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
				
			||||||
 | 
					   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
				
			||||||
 | 
					   viewBox="0 0 22 22"
 | 
				
			||||||
 | 
					   id="svg2"
 | 
				
			||||||
 | 
					   version="1.1"
 | 
				
			||||||
 | 
					   inkscape:version="0.91 r13725"
 | 
				
			||||||
 | 
					   sodipodi:docname="mic_off.svg">
 | 
				
			||||||
 | 
					  <metadata
 | 
				
			||||||
 | 
					     id="metadata20">
 | 
				
			||||||
 | 
					    <rdf:RDF>
 | 
				
			||||||
 | 
					      <cc:Work
 | 
				
			||||||
 | 
					         rdf:about="">
 | 
				
			||||||
 | 
					        <dc:format>image/svg+xml</dc:format>
 | 
				
			||||||
 | 
					        <dc:type
 | 
				
			||||||
 | 
					           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
				
			||||||
 | 
					      </cc:Work>
 | 
				
			||||||
 | 
					    </rdf:RDF>
 | 
				
			||||||
 | 
					  </metadata>
 | 
				
			||||||
 | 
					  <sodipodi:namedview
 | 
				
			||||||
 | 
					     pagecolor="#ffffff"
 | 
				
			||||||
 | 
					     bordercolor="#666666"
 | 
				
			||||||
 | 
					     borderopacity="1"
 | 
				
			||||||
 | 
					     objecttolerance="10"
 | 
				
			||||||
 | 
					     gridtolerance="10"
 | 
				
			||||||
 | 
					     guidetolerance="10"
 | 
				
			||||||
 | 
					     inkscape:pageopacity="0"
 | 
				
			||||||
 | 
					     inkscape:pageshadow="2"
 | 
				
			||||||
 | 
					     inkscape:window-width="1920"
 | 
				
			||||||
 | 
					     inkscape:window-height="1137"
 | 
				
			||||||
 | 
					     id="namedview18"
 | 
				
			||||||
 | 
					     showgrid="false"
 | 
				
			||||||
 | 
					     inkscape:zoom="10.727273"
 | 
				
			||||||
 | 
					     inkscape:cx="-0.51271186"
 | 
				
			||||||
 | 
					     inkscape:cy="11"
 | 
				
			||||||
 | 
					     inkscape:window-x="-8"
 | 
				
			||||||
 | 
					     inkscape:window-y="-8"
 | 
				
			||||||
 | 
					     inkscape:window-maximized="1"
 | 
				
			||||||
 | 
					     inkscape:current-layer="svg2" />
 | 
				
			||||||
 | 
					  <defs
 | 
				
			||||||
 | 
					     id="defs4">
 | 
				
			||||||
 | 
					    <clipPath
 | 
				
			||||||
 | 
					       id="clipPath6">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         d="m69.63 12.145h-.052c-22.727-.292-46.47 4.077-46.709 4.122-2.424.451-4.946 2.974-5.397 5.397-.044.237-4.414 23.983-4.122 46.71-.292 22.777 4.078 46.523 4.122 46.761.451 2.423 2.974 4.945 5.398 5.398.237.044 23.982 4.413 46.709 4.121 22.779.292 46.524-4.077 46.761-4.121 2.423-.452 4.946-2.976 5.398-5.399.044-.236 4.413-23.981 4.121-46.709.292-22.777-4.077-46.523-4.121-46.761-.453-2.423-2.976-4.946-5.398-5.397-.238-.045-23.984-4.414-46.71-4.122"
 | 
				
			||||||
 | 
					         id="path8" />
 | 
				
			||||||
 | 
					    </clipPath>
 | 
				
			||||||
 | 
					  </defs>
 | 
				
			||||||
 | 
					  <g
 | 
				
			||||||
 | 
					     transform="matrix(0.1327649,0,0,0.1327649,3.5653647,1.971854)"
 | 
				
			||||||
 | 
					     id="g10"
 | 
				
			||||||
 | 
					     style="fill:#ffffff">
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       d="M 20.722,77.21 C 19.907,73.951 19.5,70.883 19.5,68.004 l 0,-10.43 c 0,-1.412 -0.516,-2.634 -1.548,-3.666 -1.032,-1.032 -2.254,-1.548 -3.666,-1.548 -1.413,0 -2.635,0.516 -3.667,1.548 -1.032,1.032 -1.548,2.254 -1.548,3.666 l 0,10.429 c 0,6.03 1.141,11.841 3.422,17.437 l 8.229,-8.23"
 | 
				
			||||||
 | 
					       id="path12"
 | 
				
			||||||
 | 
					       style="fill:#ffffff"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       d="m 56,94.07 c 7.17,0 13.309,-2.553 18.412,-7.657 C 79.517,81.309 82.07,75.17 82.07,68 l 0,-10.429 29.412,-29.412 c 0.543,-0.543 0.815,-1.168 0.815,-1.874 0,-0.706 -0.271,-1.331 -0.815,-1.874 l -6.68,-6.681 c -0.544,-0.544 -1.168,-0.815 -1.875,-0.815 -0.705,0 -1.33,0.271 -1.873,0.815 L 0.514,118.27 c -0.543,0.543 -0.814,1.168 -0.814,1.873 0,0.707 0.271,1.332 0.814,1.875 l 6.681,6.681 c 0.543,0.543 1.168,0.814 1.874,0.814 0.706,0 1.331,-0.271 1.874,-0.814 l 20.694,-20.694 c 5.974,3.695 12.356,5.895 19.15,6.6 l 0,10.756 -20.857,0 c -1.412,0 -2.635,0.516 -3.666,1.548 -1.032,1.032 -1.549,2.254 -1.549,3.666 0,1.411 0.517,2.635 1.549,3.666 1.031,1.032 2.254,1.549 3.666,1.549 l 52.14,0 c 1.412,0 2.635,-0.517 3.666,-1.549 1.033,-1.031 1.549,-2.255 1.549,-3.666 0,-1.412 -0.516,-2.634 -1.549,-3.666 -1.031,-1.032 -2.254,-1.548 -3.666,-1.548 l -20.856,0 0,-10.756 C 73,113.302 82.899,108.21 90.911,99.33 98.921,90.45 102.931,80.008 102.931,68 l 0,-10.431 c 0,-1.412 -0.516,-2.634 -1.547,-3.666 -1.033,-1.032 -2.255,-1.548 -3.667,-1.548 -1.412,0 -2.634,0.516 -3.666,1.548 -1.032,1.032 -1.548,2.254 -1.548,3.666 l 0,10.429 c 0,10.05 -3.572,18.643 -10.714,25.785 -7.142,7.142 -15.738,10.714 -25.786,10.714 -5.866,0 -11.433,-1.384 -16.702,-4.155 l 7.821,-7.82 c 2.934,1.031 5.894,1.546 8.881,1.546"
 | 
				
			||||||
 | 
					       id="path14"
 | 
				
			||||||
 | 
					       style="fill:#ffffff"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       d="M 71.03,5.02 C 66.549,1.815 61.538,0.212 56,0.212 c -7.17,0 -13.308,2.554 -18.413,7.659 -5.105,5.105 -7.658,11.243 -7.658,18.413 l 0,41.714 50.594,-50.595 C 78.676,12.353 75.513,8.224 71.032,5.02"
 | 
				
			||||||
 | 
					       id="path16"
 | 
				
			||||||
 | 
					       style="fill:#ffffff"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					  </g>
 | 
				
			||||||
 | 
					</svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 4.1 KiB  | 
							
								
								
									
										70
									
								
								src/vr/assets/img/audio/microphone/mic_on.svg
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,70 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
				
			||||||
 | 
					<svg
 | 
				
			||||||
 | 
					   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
				
			||||||
 | 
					   xmlns:cc="http://creativecommons.org/ns#"
 | 
				
			||||||
 | 
					   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
				
			||||||
 | 
					   xmlns:svg="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
				
			||||||
 | 
					   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
				
			||||||
 | 
					   viewBox="0 0 22 22"
 | 
				
			||||||
 | 
					   id="svg2"
 | 
				
			||||||
 | 
					   version="1.1"
 | 
				
			||||||
 | 
					   inkscape:version="0.91 r13725"
 | 
				
			||||||
 | 
					   sodipodi:docname="mic_on.svg">
 | 
				
			||||||
 | 
					  <metadata
 | 
				
			||||||
 | 
					     id="metadata18">
 | 
				
			||||||
 | 
					    <rdf:RDF>
 | 
				
			||||||
 | 
					      <cc:Work
 | 
				
			||||||
 | 
					         rdf:about="">
 | 
				
			||||||
 | 
					        <dc:format>image/svg+xml</dc:format>
 | 
				
			||||||
 | 
					        <dc:type
 | 
				
			||||||
 | 
					           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
				
			||||||
 | 
					      </cc:Work>
 | 
				
			||||||
 | 
					    </rdf:RDF>
 | 
				
			||||||
 | 
					  </metadata>
 | 
				
			||||||
 | 
					  <sodipodi:namedview
 | 
				
			||||||
 | 
					     pagecolor="#ffffff"
 | 
				
			||||||
 | 
					     bordercolor="#666666"
 | 
				
			||||||
 | 
					     borderopacity="1"
 | 
				
			||||||
 | 
					     objecttolerance="10"
 | 
				
			||||||
 | 
					     gridtolerance="10"
 | 
				
			||||||
 | 
					     guidetolerance="10"
 | 
				
			||||||
 | 
					     inkscape:pageopacity="0"
 | 
				
			||||||
 | 
					     inkscape:pageshadow="2"
 | 
				
			||||||
 | 
					     inkscape:window-width="1920"
 | 
				
			||||||
 | 
					     inkscape:window-height="1137"
 | 
				
			||||||
 | 
					     id="namedview16"
 | 
				
			||||||
 | 
					     showgrid="false"
 | 
				
			||||||
 | 
					     inkscape:zoom="10.727273"
 | 
				
			||||||
 | 
					     inkscape:cx="-0.51271186"
 | 
				
			||||||
 | 
					     inkscape:cy="11"
 | 
				
			||||||
 | 
					     inkscape:window-x="1912"
 | 
				
			||||||
 | 
					     inkscape:window-y="-8"
 | 
				
			||||||
 | 
					     inkscape:window-maximized="1"
 | 
				
			||||||
 | 
					     inkscape:current-layer="svg2" />
 | 
				
			||||||
 | 
					  <defs
 | 
				
			||||||
 | 
					     id="defs4">
 | 
				
			||||||
 | 
					    <clipPath
 | 
				
			||||||
 | 
					       id="clipPath6">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         d="m69.63 12.145h-.052c-22.727-.292-46.47 4.077-46.709 4.122-2.424.451-4.946 2.974-5.397 5.397-.044.237-4.414 23.983-4.122 46.71-.292 22.777 4.078 46.523 4.122 46.761.451 2.423 2.974 4.945 5.398 5.398.237.044 23.982 4.413 46.709 4.121 22.779.292 46.524-4.077 46.761-4.121 2.423-.452 4.946-2.976 5.398-5.399.044-.236 4.413-23.981 4.121-46.709.292-22.777-4.077-46.523-4.121-46.761-.453-2.423-2.976-4.946-5.398-5.397-.238-.045-23.984-4.414-46.71-4.122"
 | 
				
			||||||
 | 
					         id="path8" />
 | 
				
			||||||
 | 
					    </clipPath>
 | 
				
			||||||
 | 
					  </defs>
 | 
				
			||||||
 | 
					  <g
 | 
				
			||||||
 | 
					     transform="matrix(0.13276686,0,0,0.13276686,4.7597584,1.971588)"
 | 
				
			||||||
 | 
					     id="g10"
 | 
				
			||||||
 | 
					     style="fill:#ffffff">
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       d="m 47,94.07 c 7.17,0 13.307,-2.553 18.412,-7.657 C 70.517,81.309 73.07,75.17 73.07,68 l 0,-41.714 C 73.07,19.116 70.519,12.979 65.412,7.873 60.307,2.768 54.17,0.214 47,0.214 c -7.17,0 -13.307,2.554 -18.413,7.659 -5.106,5.105 -7.659,11.243 -7.659,18.413 l 0,41.714 c 0,7.17 2.554,13.309 7.659,18.413 C 33.692,91.517 39.83,94.07 47,94.07"
 | 
				
			||||||
 | 
					       id="path12"
 | 
				
			||||||
 | 
					       style="fill:#ffffff"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       d="m 92.38,53.905 c -1.03,-1.032 -2.254,-1.548 -3.666,-1.548 -1.412,0 -2.634,0.516 -3.666,1.548 -1.032,1.032 -1.548,2.254 -1.548,3.666 L 83.5,68 C 83.5,78.05 79.928,86.643 72.786,93.786 65.645,100.929 57.049,104.5 47,104.5 36.95,104.5 28.356,100.929 21.213,93.786 14.071,86.645 10.5,78.049 10.5,68 l 0,-10.429 C 10.5,56.159 9.984,54.937 8.952,53.905 7.92,52.873 6.699,52.357 5.286,52.357 c -1.413,0 -2.635,0.516 -3.667,1.548 -1.032,1.032 -1.548,2.254 -1.548,3.666 l 0,10.429 c 0,12 4.01,22.446 12.02,31.33 8.01,8.88 17.91,13.972 29.697,15.275 l 0,10.756 -20.857,0 c -1.412,0 -2.634,0.516 -3.666,1.548 -1.032,1.032 -1.548,2.254 -1.548,3.666 0,1.411 0.516,2.635 1.548,3.666 1.032,1.032 2.254,1.549 3.666,1.549 l 52.14,0 c 1.412,0 2.636,-0.517 3.666,-1.549 1.033,-1.031 1.55,-2.255 1.55,-3.666 0,-1.412 -0.517,-2.634 -1.55,-3.666 -1.03,-1.032 -2.254,-1.548 -3.666,-1.548 l -20.855,0 0,-10.756 C 64.001,113.302 73.9,108.21 81.912,99.33 89.922,90.45 93.932,80.008 93.932,68 l 0,-10.429 c 0,-1.412 -0.517,-2.633 -1.55,-3.666"
 | 
				
			||||||
 | 
					       id="path14"
 | 
				
			||||||
 | 
					       style="fill:#ffffff"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					  </g>
 | 
				
			||||||
 | 
					</svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 3.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/audio/microphone/ptm_notification.png
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/audio/microphone/ptt_notification.png
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.9 KiB  | 
							
								
								
									
										85
									
								
								src/vr/assets/img/audio/microphone/ptt_notification.svg
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,85 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
				
			||||||
 | 
					<svg
 | 
				
			||||||
 | 
					   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
				
			||||||
 | 
					   xmlns:cc="http://creativecommons.org/ns#"
 | 
				
			||||||
 | 
					   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
				
			||||||
 | 
					   xmlns:svg="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
				
			||||||
 | 
					   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
				
			||||||
 | 
					   viewBox="0 0 16 22"
 | 
				
			||||||
 | 
					   id="svg2"
 | 
				
			||||||
 | 
					   version="1.1"
 | 
				
			||||||
 | 
					   inkscape:version="0.91 r13725"
 | 
				
			||||||
 | 
					   sodipodi:docname="ptt_notification.dvg.svg"
 | 
				
			||||||
 | 
					   width="16"
 | 
				
			||||||
 | 
					   height="22">
 | 
				
			||||||
 | 
					  <metadata
 | 
				
			||||||
 | 
					     id="metadata18">
 | 
				
			||||||
 | 
					    <rdf:RDF>
 | 
				
			||||||
 | 
					      <cc:Work
 | 
				
			||||||
 | 
					         rdf:about="">
 | 
				
			||||||
 | 
					        <dc:format>image/svg+xml</dc:format>
 | 
				
			||||||
 | 
					        <dc:type
 | 
				
			||||||
 | 
					           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
				
			||||||
 | 
					        <dc:title></dc:title>
 | 
				
			||||||
 | 
					      </cc:Work>
 | 
				
			||||||
 | 
					    </rdf:RDF>
 | 
				
			||||||
 | 
					  </metadata>
 | 
				
			||||||
 | 
					  <sodipodi:namedview
 | 
				
			||||||
 | 
					     pagecolor="#1b2939"
 | 
				
			||||||
 | 
					     bordercolor="#666666"
 | 
				
			||||||
 | 
					     borderopacity="1"
 | 
				
			||||||
 | 
					     objecttolerance="10"
 | 
				
			||||||
 | 
					     gridtolerance="10"
 | 
				
			||||||
 | 
					     guidetolerance="10"
 | 
				
			||||||
 | 
					     inkscape:pageopacity="1"
 | 
				
			||||||
 | 
					     inkscape:pageshadow="2"
 | 
				
			||||||
 | 
					     inkscape:window-width="1920"
 | 
				
			||||||
 | 
					     inkscape:window-height="1137"
 | 
				
			||||||
 | 
					     id="namedview16"
 | 
				
			||||||
 | 
					     showgrid="false"
 | 
				
			||||||
 | 
					     inkscape:zoom="10.727273"
 | 
				
			||||||
 | 
					     inkscape:cx="-5.3865047"
 | 
				
			||||||
 | 
					     inkscape:cy="11"
 | 
				
			||||||
 | 
					     inkscape:window-x="1912"
 | 
				
			||||||
 | 
					     inkscape:window-y="-8"
 | 
				
			||||||
 | 
					     inkscape:window-maximized="1"
 | 
				
			||||||
 | 
					     inkscape:current-layer="svg2" />
 | 
				
			||||||
 | 
					  <defs
 | 
				
			||||||
 | 
					     id="defs4">
 | 
				
			||||||
 | 
					    <clipPath
 | 
				
			||||||
 | 
					       id="clipPath6">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         d="m 69.63,12.145 -0.052,0 c -22.727,-0.292 -46.47,4.077 -46.709,4.122 -2.424,0.451 -4.946,2.974 -5.397,5.397 -0.044,0.237 -4.414,23.983 -4.122,46.71 -0.292,22.777 4.078,46.523 4.122,46.761 0.451,2.423 2.974,4.945 5.398,5.398 0.237,0.044 23.982,4.413 46.709,4.121 22.779,0.292 46.524,-4.077 46.761,-4.121 2.423,-0.452 4.946,-2.976 5.398,-5.399 0.044,-0.236 4.413,-23.981 4.121,-46.709 0.292,-22.777 -4.077,-46.523 -4.121,-46.761 -0.453,-2.423 -2.976,-4.946 -5.398,-5.397 -0.238,-0.045 -23.984,-4.414 -46.71,-4.122"
 | 
				
			||||||
 | 
					         id="path8"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </clipPath>
 | 
				
			||||||
 | 
					  </defs>
 | 
				
			||||||
 | 
					  <g
 | 
				
			||||||
 | 
					     transform="matrix(0.12612852,0,0,0.12612852,2.0717705,2.4230086)"
 | 
				
			||||||
 | 
					     id="g10"
 | 
				
			||||||
 | 
					     style="fill:#ffffff">
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       id="g4141"
 | 
				
			||||||
 | 
					       transform="matrix(1.1111111,0,0,1.1111111,-5.2223894,-7.5557786)">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         style="fill:#ffffff"
 | 
				
			||||||
 | 
					         id="path12"
 | 
				
			||||||
 | 
					         d="m 47,94.07 c 7.17,0 13.307,-2.553 18.412,-7.657 C 70.517,81.309 73.07,75.17 73.07,68 l 0,-41.714 C 73.07,19.116 70.519,12.979 65.412,7.873 60.307,2.768 54.17,0.214 47,0.214 c -7.17,0 -13.307,2.554 -18.413,7.659 -5.106,5.105 -7.659,11.243 -7.659,18.413 l 0,41.714 c 0,7.17 2.554,13.309 7.659,18.413 C 33.692,91.517 39.83,94.07 47,94.07" />
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         style="fill:#ffffff"
 | 
				
			||||||
 | 
					         id="path14"
 | 
				
			||||||
 | 
					         d="m 92.38,53.905 c -1.03,-1.032 -2.254,-1.548 -3.666,-1.548 -1.412,0 -2.634,0.516 -3.666,1.548 -1.032,1.032 -1.548,2.254 -1.548,3.666 L 83.5,68 C 83.5,78.05 79.928,86.643 72.786,93.786 65.645,100.929 57.049,104.5 47,104.5 36.95,104.5 28.356,100.929 21.213,93.786 14.071,86.645 10.5,78.049 10.5,68 l 0,-10.429 C 10.5,56.159 9.984,54.937 8.952,53.905 7.92,52.873 6.699,52.357 5.286,52.357 c -1.413,0 -2.635,0.516 -3.667,1.548 -1.032,1.032 -1.548,2.254 -1.548,3.666 l 0,10.429 c 0,12 4.01,22.446 12.02,31.33 8.01,8.88 17.91,13.972 29.697,15.275 l 0,10.756 -20.857,0 c -1.412,0 -2.634,0.516 -3.666,1.548 -1.032,1.032 -1.548,2.254 -1.548,3.666 0,1.411 0.516,2.635 1.548,3.666 1.032,1.032 2.254,1.549 3.666,1.549 l 52.14,0 c 1.412,0 2.636,-0.517 3.666,-1.549 1.033,-1.031 1.55,-2.255 1.55,-3.666 0,-1.412 -0.517,-2.634 -1.55,-3.666 -1.03,-1.032 -2.254,-1.548 -3.666,-1.548 l -20.855,0 0,-10.756 C 64.001,113.302 73.9,108.21 81.912,99.33 89.922,90.45 93.932,80.008 93.932,68 l 0,-10.429 c 0,-1.412 -0.517,-2.633 -1.55,-3.666" />
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					  </g>
 | 
				
			||||||
 | 
					  <rect
 | 
				
			||||||
 | 
					     style="fill:none;stroke:#3b607a;stroke-width:0.29646081;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
 | 
				
			||||||
 | 
					     id="rect3337"
 | 
				
			||||||
 | 
					     width="15.012013"
 | 
				
			||||||
 | 
					     height="21.071335"
 | 
				
			||||||
 | 
					     x="0.49399328"
 | 
				
			||||||
 | 
					     y="0.46433258" />
 | 
				
			||||||
 | 
					</svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 4.1 KiB  | 
							
								
								
									
										1
									
								
								src/vr/assets/img/audio/speaker/speaker_off.svg
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22"><g transform="matrix(.13811 0 0 .13811 4.955 5.808)" fill-opacity=".8"><g transform="matrix(6.5167 0 0 6.5167-28.01-34.23)"><g transform="matrix(1.17633 0 0 1.17633 1 1.589)" stroke-opacity=".85" fill="#000" stroke="none" fill-opacity="0" stroke-width=".73"><path d="m11.243 12.993c-.192 0-.384-.073-.53-.22-.293-.293-.293-.768 0-1.061 2.047-2.047 2.047-5.378 0-7.425-.293-.293-.293-.768 0-1.061.293-.293.768-.293 1.061 0 1.275 1.275 1.977 2.97 1.977 4.773 0 1.803-.702 3.498-1.977 4.773-.146.146-.338.22-.53.22z"/><path d="m8.578 11.578c-.192 0-.384-.073-.53-.22-.293-.293-.293-.768 0-1.061 1.267-1.267 1.267-3.329 0-4.596-.293-.293-.293-.768 0-1.061.293-.293.768-.293 1.061 0 1.852 1.852 1.852 4.865 0 6.718-.146.146-.338.22-.53.22z"/></g><g transform="translate(16 4)"><g fill="#f2f2f2" fill-opacity="0"><path d="m-1.773 12.874c-.226 0-.452-.086-.623-.259-.345-.345-.345-.903 0-1.248 2.408-2.408 2.408-6.326 0-8.734-.345-.345-.345-.903 0-1.248.345-.345.903-.345 1.248 0 1.5 1.5 2.326 3.494 2.326 5.615 0 2.121-.826 4.115-2.326 5.615-.172.172-.398.259-.623.259z"/><path d="m-4.908 11.209c-.226 0-.452-.086-.623-.259-.345-.345-.345-.903 0-1.248 1.49-1.49 1.49-3.916 0-5.406-.345-.345-.345-.903 0-1.248.345-.345.903-.345 1.248 0 2.179 2.179 2.179 5.723 0 7.903-.172.172-.398.259-.623.259z"/></g><path d="m-7.353 15.235c-.153 0-.303-.06-.416-.172l-4.534-4.534h-2.109c-.325 0-.588-.263-.588-.588v-5.882c0-.325.263-.588.588-.588h2.109l4.534-4.534c.168-.168.421-.219.641-.127.22.092.363.306.363.543v15.292c0 .238-.144.453-.363.543-.073.031-.149.045-.225.045" fill="#fff" fill-opacity="1"/></g></g><path d="m14.75 9.674v1.326h-1.326l-1.674-1.674-1.674 1.674h-1.326v-1.326l1.674-1.674-1.674-1.674v-1.326h1.326l1.674 1.674 1.674-1.674h1.326v1.326l-1.674 1.674 1.674 1.674" fill="#fff" fill-opacity="1" transform="matrix(8.22579 0 0 8.22579-32.543-28.351)"/></g></svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 1.9 KiB  | 
							
								
								
									
										1
									
								
								src/vr/assets/img/audio/speaker/speaker_on.svg
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22"><g transform="matrix(.90003 0 0 .90003 15.507 4.708)" fill-opacity="1" fill="#fff"><path d="m1.36 14.537c-.226 0-.452-.086-.623-.259-.345-.345-.345-.903 0-1.248 1.61-1.61 2.497-3.752 2.497-6.03 0-2.279-.887-4.419-2.497-6.03-.345-.345-.345-.903 0-1.248.345-.345.903-.345 1.248 0 1.944 1.944 3.01 4.529 3.01 7.278 0 2.749-1.07 5.333-3.01 7.278-.172.172-.398.259-.623.259"/><path d="m-1.773 12.874c-.226 0-.452-.086-.623-.259-.345-.345-.345-.903 0-1.248 2.408-2.408 2.408-6.326 0-8.734-.345-.345-.345-.903 0-1.248.345-.345.903-.345 1.248 0 1.5 1.5 2.326 3.494 2.326 5.615 0 2.121-.826 4.115-2.326 5.615-.172.172-.398.259-.623.259z"/><path d="m-4.908 11.209c-.226 0-.452-.086-.623-.259-.345-.345-.345-.903 0-1.248 1.49-1.49 1.49-3.916 0-5.406-.345-.345-.345-.903 0-1.248.345-.345.903-.345 1.248 0 2.179 2.179 2.179 5.723 0 7.903-.172.172-.398.259-.623.259z"/><path d="m-7.353 15.235c-.153 0-.303-.06-.416-.172l-4.534-4.534h-2.109c-.325 0-.588-.263-.588-.588v-5.882c0-.325.263-.588.588-.588h2.109l4.534-4.534c.168-.168.421-.219.641-.127.22.092.363.306.363.543v15.292c0 .238-.144.453-.363.543-.073.031-.149.045-.225.045"/></g></svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/battery/battery_0.png
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 26 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/battery/battery_1.png
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 28 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/battery/battery_2.png
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 28 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/battery/battery_3.png
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 29 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/battery/battery_4.png
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 29 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/battery/battery_5.png
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 29 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/chaperone/centermark.png
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/chaperone/centermarkl1.png
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/chaperone/centermarkl2.png
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/chaperone/centermarkl3.png
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/chaperone/centermarkr1.png
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/chaperone/centermarkr2.png
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/chaperone/centermarkr3.png
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/chest.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 112 KiB  | 
							
								
								
									
										76
									
								
								src/vr/assets/img/common/backarrow.svg
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,76 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
				
			||||||
 | 
					<svg
 | 
				
			||||||
 | 
					   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
				
			||||||
 | 
					   xmlns:cc="http://creativecommons.org/ns#"
 | 
				
			||||||
 | 
					   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
				
			||||||
 | 
					   xmlns:svg="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
				
			||||||
 | 
					   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
				
			||||||
 | 
					   width="20"
 | 
				
			||||||
 | 
					   height="20"
 | 
				
			||||||
 | 
					   id="svg3026"
 | 
				
			||||||
 | 
					   version="1.1"
 | 
				
			||||||
 | 
					   inkscape:version="0.91 r13725"
 | 
				
			||||||
 | 
					   sodipodi:docname="backarrow.svg">
 | 
				
			||||||
 | 
					  <metadata
 | 
				
			||||||
 | 
					     id="metadata3038">
 | 
				
			||||||
 | 
					    <rdf:RDF>
 | 
				
			||||||
 | 
					      <cc:Work
 | 
				
			||||||
 | 
					         rdf:about="">
 | 
				
			||||||
 | 
					        <dc:format>image/svg+xml</dc:format>
 | 
				
			||||||
 | 
					        <dc:type
 | 
				
			||||||
 | 
					           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
				
			||||||
 | 
					        <dc:title />
 | 
				
			||||||
 | 
					      </cc:Work>
 | 
				
			||||||
 | 
					    </rdf:RDF>
 | 
				
			||||||
 | 
					  </metadata>
 | 
				
			||||||
 | 
					  <defs
 | 
				
			||||||
 | 
					     id="defs3036">
 | 
				
			||||||
 | 
					    <linearGradient
 | 
				
			||||||
 | 
					       id="linearGradient4006">
 | 
				
			||||||
 | 
					      <stop
 | 
				
			||||||
 | 
					         style="stop-color:#252525;stop-opacity:1;"
 | 
				
			||||||
 | 
					         offset="0"
 | 
				
			||||||
 | 
					         id="stop4008" />
 | 
				
			||||||
 | 
					      <stop
 | 
				
			||||||
 | 
					         style="stop-color:#4a4a4a;stop-opacity:1;"
 | 
				
			||||||
 | 
					         offset="1"
 | 
				
			||||||
 | 
					         id="stop4010" />
 | 
				
			||||||
 | 
					    </linearGradient>
 | 
				
			||||||
 | 
					  </defs>
 | 
				
			||||||
 | 
					  <sodipodi:namedview
 | 
				
			||||||
 | 
					     pagecolor="#ffffff"
 | 
				
			||||||
 | 
					     bordercolor="#666666"
 | 
				
			||||||
 | 
					     borderopacity="1"
 | 
				
			||||||
 | 
					     objecttolerance="10"
 | 
				
			||||||
 | 
					     gridtolerance="10"
 | 
				
			||||||
 | 
					     guidetolerance="10"
 | 
				
			||||||
 | 
					     inkscape:pageopacity="0"
 | 
				
			||||||
 | 
					     inkscape:pageshadow="2"
 | 
				
			||||||
 | 
					     inkscape:window-width="1920"
 | 
				
			||||||
 | 
					     inkscape:window-height="1137"
 | 
				
			||||||
 | 
					     id="namedview3034"
 | 
				
			||||||
 | 
					     showgrid="true"
 | 
				
			||||||
 | 
					     inkscape:zoom="26.304372"
 | 
				
			||||||
 | 
					     inkscape:cx="11.841239"
 | 
				
			||||||
 | 
					     inkscape:cy="6.8249439"
 | 
				
			||||||
 | 
					     inkscape:window-x="1912"
 | 
				
			||||||
 | 
					     inkscape:window-y="-8"
 | 
				
			||||||
 | 
					     inkscape:window-maximized="1"
 | 
				
			||||||
 | 
					     inkscape:current-layer="g3028">
 | 
				
			||||||
 | 
					    <inkscape:grid
 | 
				
			||||||
 | 
					       type="xygrid"
 | 
				
			||||||
 | 
					       id="grid3040" />
 | 
				
			||||||
 | 
					  </sodipodi:namedview>
 | 
				
			||||||
 | 
					  <g
 | 
				
			||||||
 | 
					     id="g3028"
 | 
				
			||||||
 | 
					     stroke-width="2.23"
 | 
				
			||||||
 | 
					     stroke="#d40000">
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					       id="path4003"
 | 
				
			||||||
 | 
					       style="font-size:11.38508987px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#f9f9f9;fill-opacity:1;stroke:none;font-family:Segoe UI Symbol;-inkscape-font-specification:Segoe UI Symbol"
 | 
				
			||||||
 | 
					       d="m 1.731867,9.9956035 c 2e-5,0.7560365 0.09966,1.4842425 0.298902,2.1846165 0.199287,0.700357 0.477675,1.358232 0.835165,1.973627 0.357528,0.615372 0.786831,1.175079 1.287912,1.67912 0.501116,0.504017 1.057891,0.936251 1.67033,1.296703 0.612469,0.360426 1.270344,0.640279 1.973627,0.839561 0.703309,0.199253 1.432978,0.298886 2.18901,0.298901 0.756055,-1.5e-5 1.484259,-0.09965 2.184616,-0.298901 0.700375,-0.199282 1.355319,-0.479135 1.964834,-0.839561 0.609531,-0.360452 1.167773,-0.792686 1.674726,-1.296703 0.506965,-0.504041 0.940664,-1.063748 1.301099,-1.67912 0.360444,-0.615395 0.641762,-1.27327 0.843956,-1.973627 0.202201,-0.700374 0.3033,-1.42858 0.303296,-2.1846165 4e-6,-0.756049 -0.09963,-1.484254 -0.298901,-2.184615 -0.199263,-0.70037 -0.479116,-1.356779 -0.83956,-1.969231 -0.360435,-0.612454 -0.792669,-1.169231 -1.296704,-1.67033 -0.504022,-0.501098 -1.063729,-0.931867 -1.67912,-1.292307 -0.615377,-0.360439 -1.273251,-0.640292 -1.973626,-0.839561 -0.700357,-0.199264 -1.428561,-0.298899 -2.184616,-0.2989 -0.756032,10e-7 -1.485701,0.09964 -2.18901,0.2989 -0.703283,0.199269 -1.361158,0.477658 -1.973627,0.835165 -0.612439,0.357511 -1.169214,0.786814 -1.67033,1.287912 -0.501081,0.501099 -0.930384,1.05934 -1.287912,1.674726 -0.35749,0.615382 -0.635878,1.273256 -0.835165,1.973626 -0.199247,0.700361 -0.298882,1.428566 -0.298902,2.184615 z m 2.769231,0.035172 0,-0.035172 4.026374,-4.210988 2.918682,0 -3.068132,3.138462 6.672527,0 0,2.1802195 -6.672527,0 3.068132,3.138461 -2.918682,0 z M 0,9.9868115 c 2.0999981e-5,-0.90843 0.120171,-1.784619 0.360439,-2.628572 0.240315,-0.843958 0.58024,-1.636632 1.01978,-2.378021 0.43958,-0.741393 0.964123,-1.416851 1.573627,-2.026375 C 3.563387,2.3443225 4.238845,1.8197795 4.980218,1.3802185 5.721627,0.94065953 6.515765,0.60073453 7.362637,0.36043753 8.209538,0.12014953 9.087192,2.5255985e-6 9.995604,-4.7440151e-7 10.90404,2.5255985e-6 11.781694,0.12015453 12.628571,0.36043853 c 0.846895,0.240297 1.641033,0.577292 2.382418,1.01098997 0.741398,0.433701 1.41832,0.955312 2.030769,1.564835 0.612458,0.609524 1.138465,1.284982 1.578022,2.026374 0.439563,0.74139 0.77949,1.535528 1.01978,2.382416 0.240295,0.846883 0.360442,1.727468 0.36044,2.641759 2e-6,0.9084175 -0.120145,1.7860735 -0.36044,2.6329675 -0.24029,0.846877 -0.580217,1.641015 -1.01978,2.382417 -0.439557,0.74138 -0.965564,1.418303 -1.578022,2.03077 -0.612449,0.61244 -1.289371,1.138447 -2.030769,1.578022 -0.741385,0.439545 -1.535523,0.780937 -2.382418,1.024176 C 11.781694,19.878372 10.90404,19.999984 9.995604,20 9.087192,19.999984 8.209538,19.879837 7.362637,19.63956 6.515765,19.399252 5.721627,19.06079 4.980218,18.624176 4.238845,18.187531 3.563387,17.66299 2.953846,17.050549 2.344342,16.438082 1.819799,15.761159 1.380219,15.019779 0.940679,14.278377 0.600754,13.482774 0.360439,12.632967 0.120168,11.783143 2.0999981e-5,10.901091 0,9.9868125 z" />
 | 
				
			||||||
 | 
					  </g>
 | 
				
			||||||
 | 
					</svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 5.1 KiB  | 
							
								
								
									
										1
									
								
								src/vr/assets/img/common/check.svg
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					<svg xmlns="http://www.w3.org/2000/svg" width="270" height="270"><path d="M30 180l60 60L240 30" stroke="#000" stroke-width="30" fill="none"/></svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 147 B  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/confirmed.png
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 53 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/cpus.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 165 KiB  | 
							
								
								
									
										1
									
								
								src/vr/assets/img/cpus.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 621 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/dog.gif
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 23 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/dog2.gif
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 31 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/expired.png
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 28 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/grass.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 7.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/hypnotoad.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 21 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/vr/assets/img/icons/advicon256px.ico
									
										
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 41 KiB  |