diff --git a/.editorconfig b/.editorconfig index 97edcc4b60..fd9587922a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -22,7 +22,7 @@ charset = utf-8 indent_size = 2 [*.py] -indent_size = 4 +indent_size = 2 [Makefile] indent_style = tab @@ -38,4 +38,4 @@ indent_brace_style = Stroustrup indent_style = tab [*.{c++,cc,cxx}] -indent_brace_style = Allman +indent_brace_style = Stroustrup diff --git a/.gitignore b/.gitignore index af235a9ae1..4b0694eed0 100644 --- a/.gitignore +++ b/.gitignore @@ -11,17 +11,21 @@ xcuserdata node-v0.12.7-darwin-x64 temp/* build/* +bld/* gl2d* apinames src/obj/ src/.vscode/ + +examples/pxScene2d/external/giflib-5.1.9/*.obj +examples/pxScene2d/external/giflib-5.1.9/*.lib + examples/pxScene2d/external/libpng-1.6.12/Makefile examples/pxScene2d/external/libpng-1.6.12/config.h examples/pxScene2d/external/libpng-1.6.12/config.status examples/pxScene2d/external/libpng-1.6.12/libtool/* examples/pxScene2d/external/libpng-1.6.12/libtool examples/pxScene2d/external/libpng-1.6.12/arm/* - examples/pxScene2d/external/libpng-1.6.28/Makefile examples/pxScene2d/external/libpng-1.6.28/config.h examples/pxScene2d/external/libpng-1.6.28/config.status @@ -39,6 +43,7 @@ examples/pxScene2d/external/freetype-2.5.3/builds/unix/ftconfig.h examples/pxScene2d/external/jpeg-9a/jconfig.h +examples/pxScene2d/external/sqlite-autoconf-3280000 examples/pxScene2d/external/curl-7.40.0/config.log examples/pxScene2d/external/curl-7.40.0/config.status @@ -91,6 +96,9 @@ examples/pxScene2d/external/curl-7.40.0/include/curl/curlbuild.h examples/pxScene2d/external/zlib-1.2.11/Makefile examples/pxScene2d/external/zlib-1.2.11/configure.log examples/pxScene2d/src/jsbindings/build/* +examples/pxScene2d/src/Release/* +examples/pxScene2d/src/Debug/* + examples/pxScene2d/external/libnode-v6.9.0/cctest.vcxproj examples/pxScene2d/external/libnode-v6.9.0/cctest.vcxproj.filters @@ -168,8 +176,8 @@ Makefile cmake_install.cmake examples/pxScene2d/external/dukluv/Makefile -examples/pxScene2d/external/dukluv/dukluv -examples/pxScene2d/external/dukluv/build/dukluv +examples/pxScene2d/external/dukluv/build/* + examples/pxScene2d/external/libpng-1.6.28/libtool examples/pxScene2d/external/libpng-1.6.28/timepng diff --git a/examples/pxBenchmark/src/CMakeLists.txt b/examples/pxBenchmark/src/CMakeLists.txt index 4ea7c0dadd..531277b2e9 100644 --- a/examples/pxBenchmark/src/CMakeLists.txt +++ b/examples/pxBenchmark/src/CMakeLists.txt @@ -84,7 +84,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -fpermissive -g -Wall -Wno-attributes set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -fpermissive -g -Wall -Wno-attributes -Wall -Wextra") set(PXSCENE_LINK_DIRECTORIES ${PXSCENE_LINK_DIRECTORIES} ${PXCORE_LIB_LOCATION}) set(PXSCENE_DEFINITIONS ${PXSCENE_DEFINITIONS} -DENABLE_NODE_V_6_9 -D_DARWIN_USE_64_BIT_INODE=1 -DNODE_ARCH="x64" -DNODE_WANT_INTERNALS=1 -DV8_DEPRECATION_WARNINGS= -DNODE_SHARED_MODE -DNODE_USE_V8_PLATFORM=1 -DNODE_HAVE_I18N_SUPPORT=1 -DNODE_HAVE_SMALL_ICU=1 -DHAVE_INSPECTOR=1 -DV8_INSPECTOR_USE_STL=1 -DV8_INSPECTOR_USE_OLD_STL=1 -DHAVE_OPENSSL=1 -DHAVE_DTRACE=1 -D__POSIX__ -DNODE_PLATFORM=darwin -DDUCONFIG_NO_TRANSLITERATION=1 -DUCONFIG_NO_SERVICE=1 -DUCONFIG_NO_REGULAR_EXPRESSIONS=1 -DU_ENABLE_DYLOAD=0 -DU_STATIC_IMPLEMENTATION=1 -DU_HAVE_STD_STRING=0 -DUCONFIG_NO_BREAK_ITERATION=0 -DUCONFIG_NO_LEGACY_CONVERSION=1 -DUCONFIG_NO_CONVERSION=1 -DHTTP_PARSER_STRICT=0 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64) -set(PLATFORM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../../pxScene2d/src/mac/pxContextUtils.mm) +set(PLATFORM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../../pxScene2d/src/mac/pxSharedContextNative.mm) set(PXSCENE_LINKER_OPTIONS "-framework OpenGL -framework Cocoa -framework Foundation") if (ENABLE_THREAD_SANITIZER) set(PXSCENE_LINKER_OPTIONS "${PXSCENE_LINKER_OPTIONS} -fsanitize=thread") @@ -246,7 +246,7 @@ ${NODEDIR}/src/udp_wrap.cc ${NODEDIR}/src/util.cc ${NODEDIR}/src/uv.cc) endif (SUPPORT_NODE) set(PLATFORM_SOURCES ${PLATFORM_SOURCES} ${PXCOREDIR}/src/utf8.c) set_source_files_properties(utf8.c PROPERTIES LANGUAGE CXX) -set(PXSCENE_DEFINITIONS ${PXSCENE_DEFINITIONS} -DHAS_WINDOWS_BREAKPAD) +#set(PXSCENE_DEFINITIONS ${PXSCENE_DEFINITIONS} -DHAS_WINDOWS_BREAKPAD) add_definitions(-DPX_PLATFORM_WIN -DRT_PLATFORM_WINDOWS -DWIN32 -DWIN32_LEAN_AND_MEAN -DGLEW_STATIC -D_TIMESPEC_DEFINED -D_CONSOLE -DCURL_STATICLIB -DRUNINMAIN -DENABLE_RT_NODE -DDISABLE_WAYLAND -DNODE_WANT_INTERNALS=1 -DENABLE_NODE_V_6_9 -DENABLE_V8_HEAP_PARAMS=1 -DV8_DEPRECATION_WARNINGS=1 -DNODE_SHARED_MODE -DHAVE_INSPECTOR=1 diff --git a/examples/pxScene2d/external/build.sh b/examples/pxScene2d/external/build.sh index f42994c7a0..afc15137a5 100755 --- a/examples/pxScene2d/external/build.sh +++ b/examples/pxScene2d/external/build.sh @@ -181,16 +181,7 @@ fi #-------- -#-------- GLIB -if [ ! -e $EXT_INSTALL_PATH/lib/libglib-2.0.la ] -then - banner "GLIB" - - ./glib/build.sh -fi - -#-------- #--------- GIF @@ -309,13 +300,13 @@ fi #--------- CURL -if [ ! -e $EXT_INSTALL_PATH/lib/libcurl.la ]; then +if [ ! -e curl/lib/libcurl.la ]; then banner "CURL" cd curl - CPPFLAGS="-I${OPENSSL_DIR} -I${OPENSSL_DIR}/include" LDFLAGS="-L${OPENSSL_DIR}/lib -Wl,-rpath,${OPENSSL_DIR}/lib " LIBS="-ldl -lpthread" PKG_CONFIG_PATH=$EXT_INSTALL_PATH/lib/pkgconfig:$PKG_CONFIG_PATH ./configure --with-ssl="${OPENSSL_DIR}" --prefix=$EXT_INSTALL_PATH + CPPFLAGS="-I${OPENSSL_DIR} -I${OPENSSL_DIR}/include" LDFLAGS="-L${OPENSSL_DIR}/lib -Wl,-rpath,${OPENSSL_DIR}/lib " LIBS="-ldl -lpthread" PKG_CONFIG_PATH=$EXT_INSTALL_PATH/lib/pkgconfig:$PKG_CONFIG_PATH ./configure --without-nghttp2 --with-ssl="${OPENSSL_DIR}" --prefix=$EXT_INSTALL_PATH if [ "$(uname)" = "Darwin" ]; then #Removing api definition for Yosemite compatibility. @@ -395,7 +386,8 @@ then if [ -e "node-v${NODE_VER}_mods.patch" ] then git apply --ignore-space-change --whitespace=nowarn "node-v${NODE_VER}_mods.patch" - git apply --ignore-space-change --whitespace=nowarn "openssl_1.0.2_compatibility.patch" + git apply --ignore-space-change --whitespace=nowarn "openssl_1.0.2_compatibility.patch" + git apply --ignore-space-change --whitespace=nowarn "node-v${NODE_VER}_fixclang.patch" fi cd "libnode-v${NODE_VER}" @@ -461,7 +453,7 @@ then cp Makefile.build Makefile fi - CPPFLAGS="${IDE_SEARCH_PATH} -I${OPENSSL_DIR} -I${OPENSSL_DIR}/include" LDFLAGS="-L${OPENSSL_DIR}/lib -Wl,-rpath,${OPENSSL_DIR}/lib " make + CPPFLAGS="${IDE_SEARCH_PATH} -I../libnode-v${NODE_VER}/deps/uv/include/ -I${OPENSSL_DIR} -I${OPENSSL_DIR}/include" LDFLAGS="-L${OPENSSL_DIR}/lib -Wl,-rpath,${OPENSSL_DIR}/lib " make git ls-files -z . | xargs -0 git update-index --assume-unchanged # ... help GIT out @@ -520,7 +512,8 @@ fi #-------- SPARK-WEBGL -if [ ! -d "spark-webgl/build" ]; then +#TODO I don't think this is used anymore... +if false && [ ! -d "spark-webgl/build" ]; then export NODE_PATH=$NODE_PATH:`pwd`/../src/node_modules export PATH=`pwd`/node/deps/npm/bin/node-gyp-bin/:`pwd`/node/out/Release:$PATH @@ -568,6 +561,17 @@ fi if [[ $# -eq 1 ]] && [[ $1 == "SPARK_ENABLE_VIDEO" ]] then + #-------- GLIB + + if [ ! -e $EXT_INSTALL_PATH/lib/libglib-2.0.la ] + then + banner "GLIB" + + ./glib/build.sh + fi + + #-------- + #-------- cJSON if [ ! -e $EXT_INSTALL_PATH/lib/libcjson.$LIBEXTN ] diff --git a/examples/pxScene2d/external/buildWindows.bat b/examples/pxScene2d/external/buildWindows.bat index b3973741b5..7d63e30a91 100644 --- a/examples/pxScene2d/external/buildWindows.bat +++ b/examples/pxScene2d/external/buildWindows.bat @@ -23,7 +23,8 @@ cd .. REM --------- GIF cd giflib-5.1.9 -patch -p1 < ../giflib-5.1.9-windows.diff +REM patch -p1 < ../giflib-5.1.9-windows.diff +git apply --ignore-space-change --ignore-whitespace --whitespace=nowarn ../giflib-5.1.9-windows.diff cl /c /EHsc dgif_lib.c egif_lib.c getarg.c gif2rgb.c gif_err.c gif_font.c gif_hash.c gifalloc.c gifbg.c gifbuild.c gifclrmp.c gifcolor.c gifecho.c giffilter.c giffix.c gifhisto.c gifinto.c gifsponge.c giftext.c giftool.c gifwedge.c openbsd-reallocarray.c qprintf.c quantize.c @@ -50,18 +51,7 @@ cd openssl-1.0.2o cd .. @rem freetype latest version needs to be updated here. Because the lib is named based on version, so to avoid a build failure and to build the external when there is a difference in version. -cat vc.build\config.props | grep "freetype-2.8.1" -if !errorlevel! == 0 ( - if exist vc.build\builds\freetype281MT_D.lib ( - echo "freetpye cache available" - ) ELSE ( - set buildExternal=1 - echo "Exact cache is not present, Externals will be built" - ) - ) ELSE ( - set buildExternal=1 - echo "Exact library version is not present, Externals will be built" -) +set buildExternal=1 if [%APPVEYOR_REPO_COMMIT%] == [] ( @@ -100,7 +90,8 @@ cd ..\..\..\..\ REM --------- NANOSVG cd nanosvg -patch -p1 < patches/add_ScaleXY.diff +REM patch -p1 < patches/add_ScaleXY.diff +git apply --ignore-space-change --ignore-whitespace --whitespace=nowarn patches/add_ScaleXY.diff cd .. REM --------- LIBNODE @@ -118,7 +109,8 @@ cd .. REM --------- DUKLUV cd dukluv -patch -p1 < patches/dukluv.git.patch +REM patch -p1 < patches/dukluv.git.patch +git apply --ignore-space-change --ignore-whitespace --whitespace=nowarn patches/dukluv.git.patch mkdir build cd build cmake .. diff --git a/examples/pxScene2d/external/clean.sh b/examples/pxScene2d/external/clean.sh index c557465ed4..8842d1d715 100755 --- a/examples/pxScene2d/external/clean.sh +++ b/examples/pxScene2d/external/clean.sh @@ -58,9 +58,9 @@ make clean -j3 cd .. #--------- spark-webgl -cd spark-webgl -node-gyp clean -cd .. +#cd spark-webgl +#node-gyp clean +#cd .. #--------- GIF diff --git a/examples/pxScene2d/external/giflib-5.1.9-windows.diff b/examples/pxScene2d/external/giflib-5.1.9-windows.diff index 72741e5c4d..8f4c61418c 100644 --- a/examples/pxScene2d/external/giflib-5.1.9-windows.diff +++ b/examples/pxScene2d/external/giflib-5.1.9-windows.diff @@ -1,7 +1,20 @@ -diff --git giflib-5.1.9/gif_hash.h giflib-5.1.9/gif_hash.h +diff --git a/examples/pxScene2d/external/giflib-5.1.9/dgif_lib.c b/examples/pxScene2d/external/giflib-5.1.9/dgif_lib.c +index c6291e7c4..c0c4e9942 100644 +--- a/examples/pxScene2d/external/giflib-5.1.9/dgif_lib.c ++++ b/examples/pxScene2d/external/giflib-5.1.9/dgif_lib.c +@@ -941,7 +941,7 @@ DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen) + while (StackPtr != 0 && i < LineLen) + Line[i++] = Stack[--StackPtr]; + } +- if (LastCode != NO_SUCH_CODE && Private->RunningCode - 2 < LZ_MAX_CODE && Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) { ++ if (LastCode != NO_SUCH_CODE && Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) { + Prefix[Private->RunningCode - 2] = LastCode; + + if (CrntCode == Private->RunningCode - 2) { +diff --git a/examples/pxScene2d/external/giflib-5.1.9/gif_hash.h b/examples/pxScene2d/external/giflib-5.1.9/gif_hash.h index ac20a43cb..a236bb56d 100644 ---- giflib-5.1.9/gif_hash.h -+++ giflib-5.1.9/gif_hash.h +--- a/examples/pxScene2d/external/giflib-5.1.9/gif_hash.h ++++ b/examples/pxScene2d/external/giflib-5.1.9/gif_hash.h @@ -7,7 +7,7 @@ gif_hash.h - magfic constants and declarations for GIF LZW #ifndef _GIF_HASH_H_ #define _GIF_HASH_H_ @@ -11,10 +24,10 @@ index ac20a43cb..a236bb56d 100644 #include #define HT_SIZE 8192 /* 12bits = 4096 or twice as big! */ -diff --git giflib-5.1.9/giftool.c giflib-5.1.9/giftool.c +diff --git a/examples/pxScene2d/external/giflib-5.1.9/giftool.c b/examples/pxScene2d/external/giflib-5.1.9/giftool.c index 21b9c486b..afdce4567 100644 ---- giflib-5.1.9/giftool.c -+++ giflib-5.1.9/giftool.c +--- a/examples/pxScene2d/external/giflib-5.1.9/giftool.c ++++ b/examples/pxScene2d/external/giflib-5.1.9/giftool.c @@ -10,7 +10,7 @@ giftool.c - GIF transformation tool. #include #include @@ -24,20 +37,3 @@ index 21b9c486b..afdce4567 100644 #include "getarg.h" #include "gif_lib.h" - - - diff --git giflib-5.1.9/dgif_lib.c giflib-5.1.9/dgif_lib.c -index 21b9c486b..afdce4567 100644 ---- giflib-5.1.9/dgif_lib.c -+++ giflib-5.1.9/dgif_lib.c - -@@ -941,7 +941,7 @@ DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen) - while (StackPtr != 0 && i < LineLen) - Line[i++] = Stack[--StackPtr]; - } -- if (LastCode != NO_SUCH_CODE && Private->RunningCode - 2 < LZ_MAX_CODE && Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) { -+ if (LastCode != NO_SUCH_CODE && Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) { - Prefix[Private->RunningCode - 2] = LastCode; - - if (CrntCode == Private->RunningCode - 2) { - diff --git a/examples/pxScene2d/external/node-v10.15.3_fixclang.patch b/examples/pxScene2d/external/node-v10.15.3_fixclang.patch new file mode 100644 index 0000000000..5e82241e67 --- /dev/null +++ b/examples/pxScene2d/external/node-v10.15.3_fixclang.patch @@ -0,0 +1,22 @@ +diff --git a/examples/pxScene2d/external/libnode-v10.15.3/deps/v8/src/torque/ast-generator.cc b/examples/pxScene2d/external/libnode-v10.15.3/deps/v8/src/torque/ast-generator.cc +index 617afd148..65e465dda 100755 +--- a/examples/pxScene2d/external/libnode-v10.15.3/deps/v8/src/torque/ast-generator.cc ++++ b/examples/pxScene2d/external/libnode-v10.15.3/deps/v8/src/torque/ast-generator.cc +@@ -120,7 +120,7 @@ Statement* AstGenerator::GetOptionalHelperBody( + + antlrcpp::Any AstGenerator::visitParameterList( + TorqueParser::ParameterListContext* context) { +- ParameterList result{{}, {}, context->VARARGS(), {}}; ++ ParameterList result{{}, {}, context->VARARGS() != nullptr, {}}; + if (context->VARARGS()) { + result.arguments_variable = context->IDENTIFIER()->getSymbol()->getText(); + } +@@ -141,7 +141,7 @@ antlrcpp::Any AstGenerator::visitTypeList( + + antlrcpp::Any AstGenerator::visitTypeListMaybeVarArgs( + TorqueParser::TypeListMaybeVarArgsContext* context) { +- ParameterList result{{}, {}, context->VARARGS(), {}}; ++ ParameterList result{{}, {}, context->VARARGS() != nullptr, {}}; + result.types.reserve(context->type().size()); + for (auto* type : context->type()) { + result.types.push_back(GetType(type)); diff --git a/examples/pxScene2d/external/node-v10.15.3_mods.patch b/examples/pxScene2d/external/node-v10.15.3_mods.patch index f1112bee49..026d216935 100644 --- a/examples/pxScene2d/external/node-v10.15.3_mods.patch +++ b/examples/pxScene2d/external/node-v10.15.3_mods.patch @@ -1651,10 +1651,26 @@ index a6cc01f12..ceee5e7ef 100755 TCPWrap* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, diff --git a/examples/pxScene2d/external/libnode-v10.15.3/deps/uv/src/win/handle.c b/examples/pxScene2d/external/libnode-v10.15.3/deps/uv/src/win/handle.c -index 9d76c3f..8e9a6df 100755 +index 9d76c3f54..c31c2f4f6 100755 --- a/examples/pxScene2d/external/libnode-v10.15.3/deps/uv/src/win/handle.c +++ b/examples/pxScene2d/external/libnode-v10.15.3/deps/uv/src/win/handle.c -@@ -148,6 +148,26 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) { +@@ -52,8 +52,13 @@ uv_handle_type uv_guess_handle(uv_file file) { + case FILE_TYPE_DISK: + return UV_FILE; + +- default: +- return UV_UNKNOWN_HANDLE; ++ default: { ++ if (file == 0 || file == 1 || file == 2) { // JRJR Hack to prevent the node stdio from dying when using /subsystem:windows ++ return UV_FILE; ++ } ++ else ++ return UV_UNKNOWN_HANDLE; ++ } + } + } + +@@ -148,6 +153,26 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) { } } diff --git a/examples/pxScene2d/src/CMakeLists.txt b/examples/pxScene2d/src/CMakeLists.txt index 7a0f429a22..9a3f0b2a88 100644 --- a/examples/pxScene2d/src/CMakeLists.txt +++ b/examples/pxScene2d/src/CMakeLists.txt @@ -24,8 +24,6 @@ set(WESTEROSSTUBINC ${EXTDIR}/westeros-stub) set(BREAKPADINC ${EXTDIR}/breakpad/src) -set(WINSPARKLEINC ${EXTDIR}/WinSparkle/include) - set(UWS ${EXTDIR}/uWebSockets) set(PX_LIBRARY_SUPPORT 1) set(PXWAYLAND_LIBRARY_SUPPORT 0) @@ -91,7 +89,7 @@ add_definitions(-DANIMATION_ROTATE_XYZ ) if(WIN32) set(OPENSSLLIB ${EXTDIR}/openssl-1.0.2o/) set(PXSCENE_LINK_DIRECTORIES ${PXSCENE_LINK_DIRECTORIES} ${OPENSSLLIB}/lib) - + include_directories(AFTER ${OPENSSLLIB}/bin) endif(WIN32) @@ -126,7 +124,7 @@ if (APPLE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -fpermissive -g -Wall -Wno-attributes -Wall -Wextra") set(PXSCENE_LINK_DIRECTORIES ${PXSCENE_LINK_DIRECTORIES} ${PXCORE_LIB_LOCATION}) set(PXSCENE_DEFINITIONS ${PXSCENE_DEFINITIONS} -DENABLE_NODE_V_6_9 -D_DARWIN_USE_64_BIT_INODE=1 -DNODE_ARCH="x64" -DNODE_WANT_INTERNALS=1 -DV8_DEPRECATION_WARNINGS= -DNODE_SHARED_MODE -DNODE_USE_V8_PLATFORM=1 -DNODE_HAVE_I18N_SUPPORT=1 -DNODE_HAVE_SMALL_ICU=1 -DHAVE_OPENSSL=1 -DHAVE_DTRACE=1 -D__POSIX__ -DNODE_PLATFORM=darwin -DDUCONFIG_NO_TRANSLITERATION=1 -DUCONFIG_NO_SERVICE=1 -DUCONFIG_NO_REGULAR_EXPRESSIONS=1 -DU_ENABLE_DYLOAD=0 -DU_STATIC_IMPLEMENTATION=1 -DU_HAVE_STD_STRING=0 -DUCONFIG_NO_BREAK_ITERATION=0 -DUCONFIG_NO_LEGACY_CONVERSION=1 -DUCONFIG_NO_CONVERSION=1 -DHTTP_PARSER_STRICT=0 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64) - set(PLATFORM_SOURCES mac/pxContextUtils.mm) + #set(PLATFORM_SOURCES mac/pxSharedContextNative.mm) set(PXSCENE_LINKER_OPTIONS "-framework OpenGL -framework Cocoa -framework Foundation") if (ENABLE_THREAD_SANITIZER) set(PXSCENE_LINKER_OPTIONS "${PXSCENE_LINKER_OPTIONS} -fsanitize=thread") @@ -197,7 +195,7 @@ elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") set(PX_PLATFORM PX_PLATFORM_GENERIC_EGL) set(PXCORE_LIB_LOCATION ${PXCOREDIR}/build/egl) set(PXSCENE_LINK_DIRECTORIES ${PXSCENE_LINK_DIRECTORIES} ${PXCORE_LIB_LOCATION}) - set(PLATFORM_SOURCES egl/pxContextUtils.cpp) + #set(PLATFORM_SOURCES egl/pxContextUtils.cpp) set(PXSCENE_DEFINITIONS ${PXSCENE_DEFINITIONS} -DPXSCENE_DISABLE_PXCONTEXT_EXT) include_directories(AFTER /opt/vc/include /opt/vc/include/interface/vcos/pthreads /opt/vc/include/interface/vmcs_host/linux /opt/vc/include) @@ -222,7 +220,7 @@ elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") set(PXCORE_LIB_LOCATION ${PXCOREDIR}/build/egl) set(PXSCENE_LINK_DIRECTORIES ${PXSCENE_LINK_DIRECTORIES} ${PXCORE_LIB_LOCATION} ${PXCOREDIR}/remote ${CMAKE_CURRENT_SOURCE_DIR}) - set(PLATFORM_SOURCES egl/pxContextUtils.cpp) + #set(PLATFORM_SOURCES egl/pxContextUtils.cpp) if (BUILD_PXSCENE_WITH_NEXUS_SUPPORT) set(PXSCENE_APP_LIBRARIES ${PXSCENE_APP_LIBRARIES} nxpl) @@ -272,7 +270,7 @@ elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") set(PX_PLATFORM PX_PLATFORM_GLUT) set(PXCORE_LIB_LOCATION ${PXCOREDIR}/build/glut) set(PXSCENE_LINK_DIRECTORIES ${PXSCENE_LINK_DIRECTORIES} ${PXCORE_LIB_LOCATION}) - set(PLATFORM_SOURCES glut/pxContextUtils.cpp) + #set(PLATFORM_SOURCES glut/pxContextUtils.cpp) set(PXSCENE_DEFINITIONS ${PXSCENE_DEFINITIONS} -DHAS_LINUX_BREAKPAD) include_directories(AFTER ${GLUTINC}) set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} glut breakpad_client ) @@ -302,11 +300,12 @@ elseif (WIN32) set(CMAKE_BUILD_TYPE Release) set(CMAKE_CONFIGURATION_TYPES ${CMAKE_BUILD_TYPE} CACHE STRING "" FORCE) add_definitions(-DWIN32 -D_LIB -DPX_PLATFORM_WIN -DRT_PLATFORM_WINDOWS) - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT ") + # /Zi /DEBUG to enable debugging + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT /Zi /DEBUG ") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /EHs-c-") set(PXCORE_LIB_LOCATION ${PXCORE_LIB_LOCATION} ${PXCOREDIR}/build/win/Release) set(PXSCENE_LINK_DIRECTORIES ${PXSCENE_LINK_DIRECTORIES} ${PXCORE_LIB_LOCATION}) - set(PLATFORM_SOURCES win/pxContextUtils.cpp) + #set(PLATFORM_SOURCES win/pxContextUtils.cpp) set(PLATFORM_SOURCES ${PLATFORM_SOURCES} ${PXCOREDIR}/src/utf8.c) set_source_files_properties(utf8.c PROPERTIES LANGUAGE CXX) set(PXSCENE_DEFINITIONS ${PXSCENE_DEFINITIONS} -DHAS_WINDOWS_BREAKPAD) @@ -322,7 +321,7 @@ elseif (WIN32) -DHTTP_PARSER_STRICT=0 -DUSE_RENDER_STATS -D_HAS_EXCEPTIONS=0) add_definitions(${COMM_DEPS_DEFINITIONS}) include_directories(AFTER ${COMM_DEPS_INCLUDE_DIRS} ${NODE_INCLUDE_DIRS} ${V8_INCLUDE_DIRS} ${DUKE_INCLUDE_DIRS}) - include_directories(AFTER "${EXTDIR}/pthread-2.9" ${WINSPARKLEINC} ${EXTDIR}/breakpad-chrome_55/src/) + include_directories(AFTER "${EXTDIR}/pthread-2.9") set(PXSCENE_LINK_DIRECTORIES ${PXSCENE_LINK_DIRECTORIES} ${COMM_DEPS_LIBRARY_DIRS} ${NODE_LIBRARY_DIRS} ${V8_LIBRARY_DIRS} ${DUKE_LIBRARY_DIRS}) @@ -387,18 +386,18 @@ set(PXSCENE_COMMON_FILES pxResource.cpp pxConstants.cpp pxRectangle.cpp pxFont.c pxTextBox.cpp pxTextCanvas.cpp pxImage.cpp pxImage9.cpp pxImageA.cpp pxImage9Border.cpp pxArchive.cpp pxAnimate.cpp) set(PXSCENE_COMMON_FILES ${PXSCENE_COMMON_FILES} pxObject.cpp) -set(PXSCENE_COMMON_FILES ${PXSCENE_COMMON_FILES} pxShaderUtils.cpp) +#set(PXSCENE_COMMON_FILES ${PXSCENE_COMMON_FILES} pxShaderUtils.cpp) set(PXSCENE_COMMON_FILES ${PXSCENE_COMMON_FILES} pxShaderResource.cpp) set(PXSCENE_COMMON_FILES ${PXSCENE_COMMON_FILES} pxScene2d.cpp) -set(PXWAYLAND_LIB_FILES pxContextGL.cpp egl/pxContextUtils.cpp) +#set(PXWAYLAND_LIB_FILES pxContextGL.cpp egl/pxContextUtils.cpp) if (BUILD_WITH_GL) message("Building with GL support") - set(PXSCENE_COMMON_FILES ${PXSCENE_COMMON_FILES} pxContextGL.cpp) + #set(PXSCENE_COMMON_FILES ${PXSCENE_COMMON_FILES} pxContextGL.cpp) else () message("Building with DirectFB support") - set(PXSCENE_COMMON_FILES ${PXSCENE_COMMON_FILES} pxContextDFB.cpp) + #set(PXSCENE_COMMON_FILES ${PXSCENE_COMMON_FILES} pxContextDFB.cpp) endif (BUILD_WITH_GL) if (BUILD_WITH_WAYLAND) @@ -543,7 +542,8 @@ if (BUILD_WITH_PXOBJECT_TRACKING) set(PXSCENE_DEFINITIONS ${PXSCENE_DEFINITIONS} -DENABLE_PXOBJECT_TRACKING) endif (BUILD_WITH_PXOBJECT_TRACKING) -set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} ${PXSCENE_LINKER_OPTIONS}) +# JRJR A space between ${CMAKE_EXE_LINKER_FLAGS} and ${PXSCENE_LINKER_OPTIONS} injects a spurious semicolon into the vc build files +set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS}${PXSCENE_LINKER_OPTIONS}) link_directories(${PXSCENE_LINK_DIRECTORIES}) ## @@ -552,6 +552,7 @@ link_directories(${PXSCENE_LINK_DIRECTORIES}) if (BUILD_PXSCENE_APP) message("Enabling build support for pxscene app") + # WIN32 to switch to /subsystem:windows add_executable(pxscene_app ${PXSCENE_APP_FILES} ${PXSCENE_ADDITIONAL_RESOURCES}) set_target_properties(pxscene_app PROPERTIES OUTPUT_NAME ${EXE}) target_link_libraries(pxscene_app ${PXSCENE_APP_LIBRARIES} ${PXSCENE_LINK_LIBRARIES}) diff --git a/examples/pxScene2d/src/Spark.cpp b/examples/pxScene2d/src/Spark.cpp index 123b8a3659..a6c3da9b6d 100644 --- a/examples/pxScene2d/src/Spark.cpp +++ b/examples/pxScene2d/src/Spark.cpp @@ -1,6 +1,6 @@ /* - pxCore Copyright 2005-2018 John Robinson + pxCore Copyright 2005-2021 John Robinson Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,469 +16,52 @@ */ -// main.cpp +// Spark.cpp +#include "rtSettings.h" +#include "rtUrlUtils.h" #include "rtPathUtils.h" +#include "rtPhoneHome.h" +#include "rtSoftwareUpdate.h" + +#include "rtScript.h" #include "pxCore.h" -#include "pxTimer.h" #include "pxEventLoop.h" -#include "pxWindow.h" - +//#include "pxViewWindow.h" +#include "pxWindowUtil.h" +#include "pxTimer.h" #include "pxContext.h" -#include "pxScene2d.h" -#include "rtUrlUtils.h" -#include "rtScript.h" +#include "sparkWindow.h" +#include "pxScene2d.h" #include "pxUtil.h" -#include "rtSettings.h" - -#ifdef RUNINMAIN -extern rtScript script; -#else -using namespace std; -#include "rtNodeThread.h" -#endif - -//#include "jsbindings/rtWrapperUtils.h" -#include -#ifndef WIN32 -#include -#endif - -#ifdef WIN32 -#include -//todo: is this resource file needed? if so, uncomment -//#include "../../../pxCore.vsbuild/pxScene2d/resource.h" -#endif -#include // for PRId64 #include // for PRId64 - -#ifndef RUNINMAIN -#define ENTERSCENELOCK() rtWrapperSceneUpdateEnter(); -#define EXITSCENELOCK() rtWrapperSceneUpdateExit(); -#else -#define ENTERSCENELOCK() -#define EXITSCENELOCK() -#endif +#include // for PRId64 +//#include #ifndef PX_SCENE_VERSION #define PX_SCENE_VERSION dev #endif -#ifdef HAS_LINUX_BREAKPAD -#include "client/linux/handler/exception_handler.h" -#elif HAS_WINDOWS_BREAKPAD -#include -#include -#include -#endif - -#ifdef PX_SERVICE_MANAGER_LINKED -#include "rtservicemanager.h" -#endif //PX_SERVICE_MANAGER_LINKED - -#ifndef RUNINMAIN -class AsyncScriptInfo; -vector scriptsInfo; -static uv_work_t nodeLoopReq; -#endif - -#include "rtThreadPool.h" - -#include -#include -#include "pxWindowUtil.h" - -pxEventLoop eventLoop; -pxEventLoop* gLoop = &eventLoop; - -pxContext context; -#ifdef ENABLE_DEBUG_MODE -extern int g_argc; -extern char** g_argv; -char *nodeInput = NULL; -char** g_origArgv = NULL; -#endif -bool gDumpMemUsage = false; -extern bool gApplicationIsClosing; -extern int pxObjectCount; - -#include "pxFont.h" - -#ifdef PXSCENE_FONT_ATLAS -extern pxFontAtlas gFontAtlas; -#endif +rtScript script; +pxEventLoop eventLoop; +pxContext context; // JRJR try to make this go away and be a parameter to onDraw double gCollectionTime = 30.0; - -#ifdef HAS_LINUX_BREAKPAD -static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, -void* context, bool succeeded) { - UNUSED_PARAM(descriptor); - UNUSED_PARAM(context); - return succeeded; -} -#elif HAS_WINDOWS_BREAKPAD -bool dumpCallback(const wchar_t* dump_path, - const wchar_t* minidump_id, - void* context, - EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion, - bool succeeded) { - return succeeded; -} -#endif +bool gDumpMemUsage = false; #ifdef ENABLE_CODE_COVERAGE extern "C" void __gcov_flush(); #endif -#ifdef ENABLE_OPTIMUS_SUPPORT -#include "optimus_client.h" -#endif //ENABLE_OPTIMUS_SUPPORT - -class sceneWindow : public pxWindow, public pxIViewContainer -{ -public: - sceneWindow(): mWidth(-1),mHeight(-1),mClosed(false) {} - virtual ~sceneWindow() - { - mView = NULL; - } - - void init(int x, int y, int w, int h, const char* url = NULL) - { - pxWindow::init(x,y,w,h); - - setUrl(url); - } - - void* getInterface(const char* /*name*/) - { - return NULL; - } - - rtError setView(pxIView* v) - { - mView = v; - - if (v) - { - ENTERSCENELOCK() - v->setViewContainer(this); - v->onSize(mWidth, mHeight); - EXITSCENELOCK() - } - - return RT_OK; - } - - rtError setUrl(const char* url) - { - // escape url begin - std::string escapedUrl; - std::string origUrl = url; - for (std::string::iterator it=origUrl.begin(); it!=origUrl.end(); ++it) - { - char currChar = *it; - if ((currChar == '"') || (currChar == '\\')) - { - escapedUrl.append(1, '\\'); - } - escapedUrl.append(1, currChar); - } - if (escapedUrl.length() > MAX_URL_SIZE) - { - rtLogWarn("url size greater than MAX_URL_SIZE, reset to empty url to get default behavior"); - escapedUrl = ""; - } - // escape url end - char buffer[MAX_URL_SIZE + 50]; - memset (buffer, 0, sizeof(buffer)); - - if (std::string::npos != escapedUrl.find("http")) { - snprintf(buffer,sizeof(buffer),"shell.js?url=%s",rtUrlEncodeParameters(escapedUrl.c_str()).cString()); - } - else { - snprintf(buffer,sizeof(buffer),"shell.js?url=%s",escapedUrl.c_str()); - } - -#ifdef RUNINMAIN - setView( new pxScriptView(buffer,"javascript/node/v8")); -#else - pxScriptView * scriptView = new pxScriptView(buffer, "javascript/node/v8"); - rtLogInfo("new scriptView is %x\n",scriptView); - AsyncScriptInfo * info = new AsyncScriptInfo(); - info->m_pView = scriptView; - uv_mutex_lock(&moreScriptsMutex); - scriptsInfo.push_back(info); - uv_mutex_unlock(&moreScriptsMutex); - rtLogDebug("sceneWindow::script is pushed on vector\n"); - uv_async_send(&asyncNewScript); - setView(scriptView); -#endif - return RT_OK; - } - - virtual void invalidateRect(pxRect* r) - { - pxWindow::invalidateRect(r); - } - - void close() - { - onCloseRequest(); - } -protected: - - virtual void onSize(int32_t w, int32_t h) - { - if (mWidth != w || mHeight != h) - { - mWidth = w; - mHeight = h; - ENTERSCENELOCK() - if (mView) - mView->onSize(w, h); - EXITSCENELOCK() - } - } - - virtual void onMouseDown(int32_t x, int32_t y, uint32_t flags) - { - ENTERSCENELOCK() - if (mView) - mView->onMouseDown(x, y, flags); - EXITSCENELOCK() - } - - virtual void onCloseRequest() - { - if (mClosed) - return; - mClosed = true; - if(gDumpMemUsage) - gApplicationIsClosing = true; - - rtLogInfo(__FUNCTION__); - fflush(stdout); - ENTERSCENELOCK(); - if (mView) - { - rtLogInfo("onClose request started"); - fflush(stdout); - mView->onCloseRequest(); - rtLogInfo("onClose request completed"); - fflush(stdout); - } - EXITSCENELOCK() - // delete mView; - -#ifndef RUNINMAIN - uv_close((uv_handle_t*) &asyncNewScript, NULL); - uv_close((uv_handle_t*) &gcTrigger, NULL); -#endif - // pxScene.cpp:104:12: warning: deleting object of abstract class type ‘pxIView’ which has non-virtual destructor will cause undefined behaviour [-Wdelete-non-virtual-dtor] - - - ENTERSCENELOCK() - mView = NULL; - EXITSCENELOCK() - #ifndef RUNINMAIN - script.setNeedsToEnd(true); - #endif - #ifdef ENABLE_DEBUG_MODE - free(g_origArgv); - #endif - - rtLogInfo("about to clear all the fonts during close"); - fflush(stdout); - pxFontManager::clearAllFonts(); - rtLogInfo("cleared all the fonts during close"); - fflush(stdout); - context.term(); -#ifdef RUNINMAIN - script.pump(); -#endif - rtLogInfo("about to call garbage collect during close"); - fflush(stdout); - script.collectGarbage(); - rtLogInfo("called garbage collect during close"); - fflush(stdout); - - if (gDumpMemUsage) - { - #ifdef RUNINMAIN - script.pump(); - #endif - script.collectGarbage(); - rtLogInfo("pxobjectcount is [%d]",pxObjectCount); -#ifndef PX_PLATFORM_DFB_NON_X11 - rtLogInfo("texture memory usage is [%" PRId64 "]",context.currentTextureMemoryUsageInBytes()); -#endif - fflush(stdout); -// #ifdef PX_PLATFORM_MAC -// rtLogInfo("texture memory usage is [%lld]",context.currentTextureMemoryUsageInBytes()); -// #else -// rtLogInfo("texture memory usage is [%ld]",context.currentTextureMemoryUsageInBytes()); -// #endif - } - #ifdef ENABLE_CODE_COVERAGE - __gcov_flush(); - #endif - ENTERSCENELOCK() - eventLoop.exit(); - EXITSCENELOCK() - } - - virtual void onMouseUp(int32_t x, int32_t y, uint32_t flags) - { - ENTERSCENELOCK() - if (mView) - mView->onMouseUp(x, y, flags); - EXITSCENELOCK() - } - - virtual void onMouseLeave() - { - ENTERSCENELOCK() - if (mView) - mView->onMouseLeave(); - EXITSCENELOCK() - } - - virtual void onMouseMove(int32_t x, int32_t y) - { - ENTERSCENELOCK() - if (mView) - mView->onMouseMove(x, y); - EXITSCENELOCK() - } - - virtual void onDragMove(int32_t x, int32_t y, int32_t type) - { - ENTERSCENELOCK() - if (mView) - mView->onDragMove(x, y, type); - EXITSCENELOCK() - } - - virtual void onDragEnter(int32_t x, int32_t y, int32_t type) - { - ENTERSCENELOCK() - if (mView) - mView->onDragEnter(x, y, type); - EXITSCENELOCK() - } - - virtual void onDragLeave(int32_t x, int32_t y, int32_t type) - { - ENTERSCENELOCK() - if (mView) - mView->onDragLeave(x, y, type); - EXITSCENELOCK() - } - - virtual void onDragDrop(int32_t x, int32_t y, int32_t type, const char* dropped) - { - ENTERSCENELOCK() - if (mView) - mView->onDragDrop(x, y, type, dropped); - EXITSCENELOCK() - } - - virtual void onScrollWheel(float dx, float dy) - { - ENTERSCENELOCK() - if (mView) - mView->onScrollWheel(dx, dy); - EXITSCENELOCK() - } - - virtual void onFocus() - { - ENTERSCENELOCK() - if (mView) - mView->onFocus(); - EXITSCENELOCK() - } - virtual void onBlur() - { - ENTERSCENELOCK() - if (mView) - mView->onBlur(); - EXITSCENELOCK() - } - - virtual void onKeyDown(uint32_t keycode, uint32_t flags) - { - ENTERSCENELOCK() - if (mView) - { - mView->onKeyDown(keycode, flags); - } - EXITSCENELOCK() - } - - virtual void onKeyUp(uint32_t keycode, uint32_t flags) - { - ENTERSCENELOCK() - if (mView) - mView->onKeyUp(keycode, flags); - EXITSCENELOCK() - } - - virtual void onChar(uint32_t c) - { - ENTERSCENELOCK() - if (mView) - mView->onChar(c); - EXITSCENELOCK() - } - - virtual void onDraw(pxSurfaceNative ) - { - context.updateRenderTick(); - ENTERSCENELOCK() - if (mView) - mView->onDraw(); - EXITSCENELOCK() - } - - virtual void onAnimationTimer() - { - static double lastCollectionTime = pxSeconds(); - ENTERSCENELOCK() - if (mView && !mClosed) - mView->onUpdate(pxSeconds()); - EXITSCENELOCK() -#ifdef ENABLE_OPTIMUS_SUPPORT - OptimusClient::pumpRemoteObjectQueue(); -#endif //ENABLE_OPTIMUS_SUPPORT -#ifdef RUNINMAIN - script.pump(); -#endif - double currentTime = pxSeconds(); - if ((gCollectionTime > 0) && (currentTime - lastCollectionTime > gCollectionTime)) - { - script.collectGarbage(); - lastCollectionTime = currentTime; - } - } - - int mWidth; - int mHeight; - rtRef mView; - bool mClosed; -}; -sceneWindow win; +sparkWindow win; #define xstr(s) str(s) #define str(s) #s -void handleTerm(int) -{ +#if 0 +void handleTerm(int) { rtLogInfo("Signal TERM received. closing the window"); win.close(); #ifndef PX_PLATFORM_MAC @@ -490,391 +73,76 @@ void handleTerm(int) raise(SIGTERM); #endif } - -void handleSegv(int) -{ - signal(SIGSEGV, SIG_DFL); - FILE* fp = fopen("/tmp/pxscenecrash","w"); - fclose(fp); - rtLogInfo("Signal SEGV received. sleeping to collect data"); -#ifndef WIN32 - sleep(1800); -#endif //WIN32 -} - -void handleAbrt(int) -{ - FILE* fp = fopen("/tmp/pxscenecrash","w"); - fclose(fp); - rtLogInfo("Signal ABRT received. sleeping to collect data"); -#ifndef WIN32 - sleep(1800); -#endif //WIN32 -} - -#ifdef ENABLE_OPTIMUS_SUPPORT -namespace OptimusClient -{ - class rtOptimusSpark : public rtOptimus - { - public: - - static rtError onSceneReadyCallback(int numArgs, const rtValue* args, rtValue* /*result*/, void* context) - { - rtError rc = RT_FAIL; - if (context == NULL) - { - return rc; - } - rtOptimusSpark* optimusSpark = (rtOptimusSpark*)context; - if (numArgs >= 3) - { - rtObjectRef scene = args[0].toObject(); - rtString url = args[1].toString(); - bool success = args[2].toBool(); - rtString optimusUrl; - optimusSpark->url(optimusUrl); - if (url.compare(optimusUrl) == 0) - { - optimusSpark->sceneReady(success); - } - rc = RT_OK; - } - return rc; - } - - rtDeclareObject(rtOptimusSpark, rtOptimus); - - rtOptimusSpark(rtString url) : mUrl(url), mSceneReadyCallback() - { - mSceneReadyCallback = new rtFunctionCallback(onSceneReadyCallback, this); - pxScriptView::addListener("onSceneReady", mSceneReadyCallback); - } - - ~rtOptimusSpark() - { - if (mSceneReadyCallback.getPtr() != NULL) - { - pxScriptView::delListener("onSceneReady", mSceneReadyCallback); - mSceneReadyCallback = NULL; - } - } - - rtProperty(url, url, setUrl, rtString); - - rtError url(rtString& v) const - { - v = mUrl; - return RT_OK; - } - rtError setUrl(rtString v) - { - mUrl = v; - const char* url = v.cString(); - if (mSceneReadyCallback.getPtr() != NULL) - { - pxScriptView::delListener("onSceneReady", mSceneReadyCallback); - mSceneReadyCallback = NULL; - } - mSceneReadyCallback = new rtFunctionCallback(onSceneReadyCallback, this); - pxScriptView::addListener("onSceneReady", mSceneReadyCallback); - return win.setUrl(url); - } - - rtError sceneReady(bool success) - { - pxScriptView::delListener("onSceneReady", mSceneReadyCallback); - mSceneReadyCallback = NULL; - rtObjectRef e = new rtMapObject; - e.set("success", success); - mEmit.send("onApplicationLoaded", e); - return RT_OK; - } - - protected: - rtString mUrl; - rtFunctionRef mSceneReadyCallback; - }; - rtDefineObject(rtOptimusSpark, rtOptimus); - rtDefineProperty(rtOptimusSpark, url); -} -#endif //ENABLE_OPTIMUS_SUPPORT - -int pxMain(int argc, char* argv[]) -{ - mapNativeKeyCodes(); -#ifdef HAS_LINUX_BREAKPAD - google_breakpad::MinidumpDescriptor descriptor("/tmp"); - google_breakpad::ExceptionHandler eh(descriptor, NULL, dumpCallback, NULL, true, -1); -#elif HAS_WINDOWS_BREAKPAD - //register exception handler for breakpad - google_breakpad::ExceptionHandler* handler = NULL; - handler = new google_breakpad::ExceptionHandler(L"C:\\dumps\\", - NULL, - dumpCallback, - NULL, - google_breakpad::ExceptionHandler::HANDLER_ALL, - MiniDumpNormal, - L"", - NULL); #endif - signal(SIGTERM, handleTerm); - char const* handle_signals = getenv("HANDLE_SIGNALS"); - if (handle_signals && (strcmp(handle_signals,"1") == 0)) - { - signal(SIGSEGV, handleSegv); - signal(SIGABRT, handleAbrt); - } -#ifndef RUNINMAIN - rtLogWarn("Setting __rt_main_thread__ to be %x\n",pthread_self()); - __rt_main_thread__ = pthread_self(); // NB - rtLogWarn("Now __rt_main_thread__ is %x\n",__rt_main_thread__); - //rtLogWarn("rtIsMainThread() returns %d\n",rtIsMainThread()); - - #if PX_PLATFORM_X11 - XInitThreads(); - #endif - - uv_mutex_init(&moreScriptsMutex); - uv_mutex_init(&threadMutex); - - // Start script thread - uv_queue_work(nodeLoop, &nodeLoopReq, nodeThread, nodeIsEndingCallback); - // init asynch that will get notifications about new scripts - uv_async_init(nodeLoop, &asyncNewScript, processNewScript); - uv_async_init(nodeLoop, &gcTrigger,collectGarbage); - -#endif - - -#ifdef PX_PLATFORM_MAC_XCODE - - // #warning "PX_PLATFORM_MAC_XCODE build... Xcode DEBUG only !" - - // NOTE: PX_PLATFORM_MAC_XCODE is only defined for DEBUG + XCODE IDE builds - // via the .xcconfig file ... - -#else - rtModuleDirs::instance(); -#endif - - rtSettings::instance()->loadFromFile(); - // overwrite file settings with settings from the command line - rtSettings::instance()->loadFromArgs(argc, argv); - -char const* s = getenv("PX_DUMP_MEMUSAGE"); -if (s && (strcmp(s,"1") == 0)) -{ - gDumpMemUsage = true; -} +int pxMain(int argc, char *argv[]) { + rtPhoneHome crash; + crash.init(); - const char* url = ""; - for (int i=1;iloadFromFile(); + // overwrite settings from the command line + rtSettings::instance()->loadFromArgs(argc, argv); - rtValue screenWidth, screenHeight; - if (RT_OK == rtSettings::instance()->value("screenWidth", screenWidth)) - windowWidth = screenWidth.toInt32(); - if (RT_OK == rtSettings::instance()->value("screenHeight", screenHeight)) - windowHeight = screenHeight.toInt32(); + script.init(); + gDumpMemUsage = rtEnv("PX_DUMP_MEMUSAGE",false); + gCollectionTime = rtEnv("SPARK_COLLECTION_TIME", 30); + int32_t windowWidth = rtEnv("SPARK_WINDOW_WIDTH", 1280); + int32_t windowHeight = rtEnv("SPARK_WINDOW_HEIGHT", 720); + windowWidth = rtSettings::get("screenWidth", windowWidth); + windowHeight = rtSettings::get("screenHeight", windowHeight); extern bool gDirtyRectsEnabled; - rtValue dirtyRectsSetting; - if (RT_OK == rtSettings::instance()->value("enableDirtyRects", dirtyRectsSetting)) - gDirtyRectsEnabled = dirtyRectsSetting.toString().compare("true") == 0; + gDirtyRectsEnabled = rtSettings::get("enableDirtyRects"); + rtLogInfo("dirty rectangles enabled: %s", gDirtyRectsEnabled ? "true" : "false"); - rtLogInfo("dirty rectangles enabled: %s", gDirtyRectsEnabled ? "true":"false"); + pxScene2d::enableOptimizedUpdate(rtSettings::get("enabledOptimiedUpdate")); - rtValue optimizedUpdateSetting; - if (RT_OK == rtSettings::instance()->value("enableOptimizedUpdate", optimizedUpdateSetting)) - { - bool enable = optimizedUpdateSetting.toString().compare("true") == 0; - pxScene2d::enableOptimizedUpdate(enable); - } - - // OSX likes to pass us some weird parameter on first launch after internet install - rtLogInfo("window width = %d height = %d", windowWidth, windowHeight); win.init(10, 10, windowWidth, windowHeight, url); + + char buffer[256]; + sprintf(buffer, "Spark: %s", xstr(PX_SCENE_VERSION)); + win.setTitle(buffer); // JRJR TODO Why aren't these necessary for glut... pxCore bug win.setVisibility(true); - uint32_t animationFPS = 60; - rtString f; - if (RT_OK == rtGetHomeDirectory(f)) - { - f.append(".sparkFps"); - if (rtFileExists(f)) - { - std::fstream fs(f.cString(), std::fstream::in); - uint32_t val = 0; - fs >> val; - if (val > 0) - animationFPS = val; - } - } - rtLogInfo("Animation FPS: %lu", (unsigned long) animationFPS); + uint32_t animationFPS = rtSettings::get("animationFPS", 60); + rtLogInfo("Animation FPS: %lu", (unsigned long)animationFPS); win.setAnimationFPS(animationFPS); -#ifdef WIN32 - - HDC hdc = ::GetDC(win.mWindow); - HGLRC hrc; - - static PIXELFORMATDESCRIPTOR pfd = - { - sizeof(PIXELFORMATDESCRIPTOR), - 1, - PFD_DRAW_TO_WINDOW | - PFD_SUPPORT_OPENGL | - PFD_DOUBLEBUFFER | - PFD_SWAP_EXCHANGE, - PFD_TYPE_RGBA, - 24, - 0, 0, 0, 0, 0, 0, - 8, - 0, - 0, - 0, 0, 0, 0, - 24, - 8, - 0, - PFD_MAIN_PLANE, - 0, - 0, 0, 0 - }; - - int pixelFormat = ChoosePixelFormat(hdc, &pfd); - if (::SetPixelFormat(hdc, pixelFormat, &pfd)) { - hrc = wglCreateContext(hdc); - if (::wglMakeCurrent(hdc, hrc)) { - glewExperimental = GL_TRUE; - if (glewInit() != GLEW_OK) - throw std::runtime_error("glewInit failed"); - - char *GL_version = (char *)glGetString(GL_VERSION); - char *GL_vendor = (char *)glGetString(GL_VENDOR); - char *GL_renderer = (char *)glGetString(GL_RENDERER); - - - rtLogInfo("GL_version = %s", GL_version); - rtLogInfo("GL_vendor = %s", GL_vendor); - rtLogInfo("GL_renderer = %s", GL_renderer); - } - } - - -#endif - #if 0 - sceneWindow win2; - win2.init(50, 50, 1280, 720); - #endif - -// JRJR TODO this needs happen after GL initialization which right now only happens after a pxWindow has been created. -// Likely will move this to pxWindow... as an option... a "context" type -// would like to decouple it from pxScene2d specifically - context.init(); - -#ifdef WIN32 - - // Initialize WinSparkle as soon as the app itself is initialized, right - // before entering the event loop: - win_sparkle_set_appcast_url("https://github.com/pxscene/pxscene/tree/gh-pages/dist/windows/appcast.xml"); - win_sparkle_init(); - +#if 0 // JRJR multiple windows broken on windows... likely opengl context is not correct. + sparkWindow win2; + //win2.init(50, 50, 1280, 720); + win2.init(10, 10, windowWidth, windowHeight, url); #endif -#ifdef ENABLE_OPTIMUS_SUPPORT - rtObjectRef optimusObject = new OptimusClient::rtOptimusSpark(url); - OptimusClient::registerApi(optimusObject); -#endif //ENABLE_OPTIMUS_SUPPORT - -#ifdef PX_SERVICE_MANAGER_LINKED - RtServiceManager::start(); + // JRJR TODO this needs happen after GL initialization which right now only + // happens after a pxWindow has been created. Likely will move this to + // pxWindow... as an option... a "context" type would like to decouple it + // from pxScene2d specifically + context.init(); -#endif //PX_SERVICE_MANAGER_LINKED + rtSoftwareUpdate update; + update.init(); eventLoop.run(); -#ifdef WIN32 - win_sparkle_cleanup(); -#endif - base64_cleanup(); return 0; diff --git a/examples/pxScene2d/src/browser.js b/examples/pxScene2d/src/browser.js index f0a0587f2a..db7e4df77c 100644 --- a/examples/pxScene2d/src/browser.js +++ b/examples/pxScene2d/src/browser.js @@ -278,7 +278,7 @@ px.import({ scene: 'px:scene.1.js', if (keepHistory) { - currUrl = u; + currUrl = originalUrl } if (true) @@ -308,7 +308,7 @@ px.import({ scene: 'px:scene.1.js', backUrls.push(currUrl) foreUrls = [] } - currUrl = u + currUrl = originalUrl } } diff --git a/examples/pxScene2d/src/mkapp.sh b/examples/pxScene2d/src/mkapp.sh index 10446726dd..a8dcf6f70d 100755 --- a/examples/pxScene2d/src/mkapp.sh +++ b/examples/pxScene2d/src/mkapp.sh @@ -1,7 +1,7 @@ #!/bin/bash -#minJS=cp #don't minify -minJS=./jsMin.sh #minify +minJS=cp #don't minify +#minJS=./jsMin.sh #minify externalDir=../external EXT_INSTALL_PATH=$externalDir/extlibs diff --git a/examples/pxScene2d/src/pxConstants.h b/examples/pxScene2d/src/pxConstants.h index 85ae380b53..9bc8fc758c 100644 --- a/examples/pxScene2d/src/pxConstants.h +++ b/examples/pxScene2d/src/pxConstants.h @@ -27,6 +27,7 @@ #include "rtObject.h" #include "rtObjectMacros.h" #include "pxInterpolators.h" +#include "pxContext.h" @@ -123,14 +124,16 @@ class pxConstantsAnimation : public rtObject class pxConstantsMaskOperation : public rtObject { public: +#if 0 enum constants { NORMAL = 0, INVERT, }; +#endif rtDeclareObject(pxConstantsMaskOperation, rtObject); - rtConstantProperty(NORMAL, NORMAL, uint32_t); - rtConstantProperty(INVERT, INVERT, uint32_t); + rtConstantProperty(NORMAL, pxContextMaskOperation::NORMAL, uint32_t); + rtConstantProperty(INVERT, pxContextMaskOperation::INVERT, uint32_t); }; class pxConstantsDragType : public rtObject @@ -152,11 +155,13 @@ class pxConstantsDragType : public rtObject class pxConstantsStretch : public rtObject { public: +#if 0 enum constants { NONE = 0, STRETCH, REPEAT, }; +#endif rtDeclareObject(pxConstantsStretch, rtObject); rtConstantProperty(NONE, NONE, uint32_t); diff --git a/examples/pxScene2d/src/pxContextUtils.h b/examples/pxScene2d/src/pxContextUtils.h deleted file mode 100644 index 5780e322fb..0000000000 --- a/examples/pxScene2d/src/pxContextUtils.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - -pxCore Copyright 2005-2018 John Robinson - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*/ - -#ifndef PX_CONTEXT_UTILS_H -#define PX_CONTEXT_UTILS_H - -#include "pxCore.h" -#include "rtRef.h" -#include "rtAtomic.h" - -pxError deleteInternalGLContext(int id); -pxError createInternalContext(int &id); -pxError makeInternalGLContextCurrent(bool current, int id = 0); -pxError createInternalContext(int &id, bool depthBuffer = false); - - -class pxSharedContext -{ -public: - pxSharedContext(bool depthBuffer) : mRef(0), mContextId(0), mIsCurrent(false), mDepthBuffer(depthBuffer) - { } - virtual ~pxSharedContext() - { - if (mContextId != 0) - { - if (mIsCurrent) - { - makeInternalGLContextCurrent(false, mContextId); - } - deleteInternalGLContext(mContextId); - } - mContextId = 0; - } - - virtual unsigned long AddRef() - { - return rtAtomicInc(&mRef); - } - - virtual unsigned long Release() - { - unsigned long l = rtAtomicDec(&mRef); - if (l == 0) - delete this; - return l; - } - - pxError makeCurrent(bool current) - { - if (mContextId == 0) - { - createInternalContext(mContextId, mDepthBuffer); - } - mIsCurrent = current; - return makeInternalGLContextCurrent(current, mContextId); - } - -protected: - rtAtomic mRef; - int32_t mContextId; - bool mIsCurrent; - bool mDepthBuffer; -}; - -typedef rtRef pxSharedContextRef; - -#endif //PX_CONTEXT_UTILS_H diff --git a/examples/pxScene2d/src/pxFont.cpp b/examples/pxScene2d/src/pxFont.cpp index 10fa191b94..1d2c0857a4 100644 --- a/examples/pxScene2d/src/pxFont.cpp +++ b/examples/pxScene2d/src/pxFont.cpp @@ -98,9 +98,9 @@ uint32_t npot(uint32_t i) return power; } -#ifdef PXSCENE_FONT_ATLAS +//#ifdef PXSCENE_FONT_ATLAS pxFontAtlas gFontAtlas; -#endif +//#endif pxFont::pxFont(rtString fontUrl, uint32_t id, rtString proxyUrl, rtString fontStyle):pxResource(),mFace(NULL),mPixelSize(0), mFontData(0), mFontDataSize(0), mFontMutex(), mFontDataMutex(), mFontDownloadedData(NULL), mFontDownloadedDataSize(0), diff --git a/examples/pxScene2d/src/pxImage.cpp b/examples/pxScene2d/src/pxImage.cpp index 0751c8c503..19d8a7712b 100644 --- a/examples/pxScene2d/src/pxImage.cpp +++ b/examples/pxScene2d/src/pxImage.cpp @@ -226,7 +226,7 @@ bool pxImage::needsUpdate() float pxImage::getOnscreenWidth() { - if(mw == -1 || mStretchX == pxConstantsStretch::NONE) + if(mw == -1 || mStretchX == pxContextStretch::NONE) { return mResource.get("w"); } @@ -236,7 +236,7 @@ float pxImage::getOnscreenWidth() } float pxImage::getOnscreenHeight() { - if(mh == -1 || mStretchY == pxConstantsStretch::NONE) + if(mh == -1 || mStretchY == pxContextStretch::NONE) { return mResource.get("h"); } @@ -324,7 +324,7 @@ void pxImage::dispose(bool pumpJavascript) void pxImage::checkStretchX() { rtImageResource* imageResource = getImageResource(); - if (mStretchX == pxConstantsStretch::REPEAT && imageResource != NULL && imageResource->isInitialized()) + if (mStretchX == pxContextStretch::REPEAT && imageResource != NULL && imageResource->isInitialized()) { pxTextureRef texture = imageResource->getTexture(); if (texture.getPtr() != NULL && (!isPowerOfTwo(texture->width()) || !isPowerOfTwo(texture->height()))) @@ -337,7 +337,7 @@ void pxImage::checkStretchX() void pxImage::checkStretchY() { rtImageResource* imageResource = getImageResource(); - if (mStretchY == pxConstantsStretch::REPEAT && imageResource != NULL && imageResource->isInitialized()) + if (mStretchY == pxContextStretch::REPEAT && imageResource != NULL && imageResource->isInitialized()) { pxTextureRef texture = imageResource->getTexture(); if (texture.getPtr() != NULL && (!isPowerOfTwo(texture->width()) || !isPowerOfTwo(texture->height()))) @@ -349,14 +349,14 @@ void pxImage::checkStretchY() rtError pxImage::setStretchX(int32_t v) { - mStretchX = (pxConstantsStretch::constants)v; + mStretchX = (pxContextStretch)v; checkStretchX(); return RT_OK; } rtError pxImage::setStretchY(int32_t v) { - mStretchY = (pxConstantsStretch::constants)v; + mStretchY = (pxContextStretch)v; checkStretchY(); return RT_OK; } @@ -392,7 +392,7 @@ rtError pxImage::setResolveWithoutParent(bool v) rtError pxImage::setMaskOp(int32_t v) { - mMaskOp = (pxConstantsMaskOperation::constants)v; + mMaskOp = (pxContextMaskOperation)v; return RT_OK; } diff --git a/examples/pxScene2d/src/pxImage.h b/examples/pxScene2d/src/pxImage.h index a15a2cf8e3..cf47f846a3 100644 --- a/examples/pxScene2d/src/pxImage.h +++ b/examples/pxScene2d/src/pxImage.h @@ -42,8 +42,8 @@ class pxImage: public pxObject, pxResourceListener rtProperty(downscaleSmooth, downscaleSmooth, setDownscaleSmooth, bool); rtMethodNoArgAndReturn("texture", texture, uint32_t); - pxImage(pxScene2d* scene) : pxObject(scene),mStretchX(pxConstantsStretch::NONE),mStretchY(pxConstantsStretch::NONE), - mMaskOp(pxConstantsMaskOperation::NORMAL), imageLoaded(false), mListenerAdded(false), mDownscaleSmooth(false), mFlip(false), mResolveWithoutParent(false), mReceivedReadyBeforeInit(false) + pxImage(pxScene2d* scene) : pxObject(scene),mStretchX(pxContextStretch::NONE),mStretchY(pxContextStretch::NONE), + mMaskOp(pxContextMaskOperation::NORMAL), imageLoaded(false), mListenerAdded(false), mDownscaleSmooth(false), mFlip(false), mResolveWithoutParent(false), mReceivedReadyBeforeInit(false) { mw = -1; mh = -1; @@ -120,10 +120,10 @@ class pxImage: public pxObject, pxResourceListener void loadImage(rtString Url); inline rtImageResource* getImageResource() const { return (rtImageResource*)mResource.getPtr(); } - pxConstantsStretch::constants mStretchX; - pxConstantsStretch::constants mStretchY; + pxContextStretch mStretchX; + pxContextStretch mStretchY; - pxConstantsMaskOperation::constants mMaskOp; + pxContextMaskOperation mMaskOp; rtObjectRef mResource; diff --git a/examples/pxScene2d/src/pxImageA.cpp b/examples/pxScene2d/src/pxImageA.cpp index b7456b5dbb..62f0272d5e 100644 --- a/examples/pxScene2d/src/pxImageA.cpp +++ b/examples/pxScene2d/src/pxImageA.cpp @@ -30,7 +30,7 @@ static pxTextureRef nullMaskRef; pxImageA::pxImageA(pxScene2d *scene) : pxObject(scene), mImageWidth(0), mImageHeight(0), - mStretchX(pxConstantsStretch::NONE), mStretchY(pxConstantsStretch::NONE), + mStretchX(pxContextStretch::NONE), mStretchY(pxContextStretch::NONE), mResource(), mImageLoaded(false), mListenerAdded(false), mResolveWithoutParent(false), mReceivedReadyBeforeInit(false) { mCurFrame = 0; @@ -213,14 +213,14 @@ void pxImageA::checkStretchY() rtError pxImageA::setStretchX(int32_t v) { - mStretchX = (pxConstantsStretch::constants)v; + mStretchX = (pxContextStretch)v; //checkStretchX(); return RT_OK; } rtError pxImageA::setStretchY(int32_t v) { - mStretchY = (pxConstantsStretch::constants)v; + mStretchY = (pxContextStretch)v; //checkStretchY(); return RT_OK; } @@ -382,7 +382,7 @@ uint64_t pxImageA::textureMemoryUsage(std::vector &objectsCounted) float pxImageA::getOnscreenWidth() { - if(mw == -1 || mStretchX == pxConstantsStretch::NONE) + if(mw == -1 || mStretchX == pxContextStretch::NONE) { return static_cast(mImageWidth); } @@ -392,7 +392,7 @@ float pxImageA::getOnscreenWidth() } float pxImageA::getOnscreenHeight() { - if(mh == -1 || mStretchY == pxConstantsStretch::NONE) + if(mh == -1 || mStretchY == pxContextStretch::NONE) { return static_cast(mImageHeight); } diff --git a/examples/pxScene2d/src/pxImageA.h b/examples/pxScene2d/src/pxImageA.h index 6ac172198a..d6b568f1af 100644 --- a/examples/pxScene2d/src/pxImageA.h +++ b/examples/pxScene2d/src/pxImageA.h @@ -89,8 +89,8 @@ class pxImageA: public pxObject, pxResourceListener pxTextureRef mTexture; double mFrameTime; - pxConstantsStretch::constants mStretchX; - pxConstantsStretch::constants mStretchY; + pxContextStretch mStretchX; + pxContextStretch mStretchY; rtObjectRef mResource; bool mImageLoaded; diff --git a/examples/pxScene2d/src/pxObject.cpp b/examples/pxScene2d/src/pxObject.cpp index f85b568841..9c10f6b709 100644 --- a/examples/pxScene2d/src/pxObject.cpp +++ b/examples/pxScene2d/src/pxObject.cpp @@ -1292,7 +1292,7 @@ void pxObject::drawInternal(bool maskPass /* = false */) else if (mPainting) { - pxConstantsMaskOperation::constants maskOp = pxConstantsMaskOperation::NORMAL; // default + pxContextMaskOperation maskOp = pxContextMaskOperation::NORMAL; // default // MASKING ? --------------------------------------------------------------------------------------------------- bool maskFound = false; @@ -1309,7 +1309,7 @@ void pxObject::drawInternal(bool maskPass /* = false */) int32_t val; img->maskOp(val); // get mask operation - maskOp = (pxConstantsMaskOperation::constants) val; + maskOp = (pxContextMaskOperation) val; } break; diff --git a/examples/pxScene2d/src/pxScene2d.cpp b/examples/pxScene2d/src/pxScene2d.cpp index cfa922b8dc..afa5058e38 100755 --- a/examples/pxScene2d/src/pxScene2d.cpp +++ b/examples/pxScene2d/src/pxScene2d.cpp @@ -146,26 +146,17 @@ uint32_t gFboBindCalls; #endif //USE_RENDER_STATS -// TODO move to rt* -// Taken from -// http://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c - #include #include #ifdef ENABLE_RT_NODE extern void rtWrapperSceneUpdateEnter(); extern void rtWrapperSceneUpdateExit(); -#ifdef RUNINMAIN -rtScript script; -#else -class AsyncScriptInfo; -extern vector scriptsInfo; -extern uv_mutex_t moreScriptsMutex; -extern uv_async_t asyncNewScript; -extern uv_async_t gcTrigger; -#endif // RUNINMAIN + +extern rtScript script; + #endif //ENABLE_RT_NODE + #ifdef ENABLE_VALGRIND #include void startProfiling() @@ -568,7 +559,7 @@ pxScene2d::pxScene2d(bool top, pxScriptView* scriptView) // capabilities.network.http2 = 2 // // capabilities.metrics.textureMemory = 1 - // + // // capabilities.animations.durations = 2 // // capabilities.events.drag_n_drop = 2 // additional Drag'n'Drop events @@ -586,22 +577,22 @@ pxScene2d::pxScene2d(bool top, pxScriptView* scriptView) graphicsCapabilities.set("svg", 2); graphicsCapabilities.set("colors", 1); - + #ifdef SUPPORT_GIF graphicsCapabilities.set("gif", 2); #endif //SUPPORT_GIF graphicsCapabilities.set("imageAResource", 2); - + graphicsCapabilities.set("screenshots", 2); graphicsCapabilities.set("shaders", 1); graphicsCapabilities.set("text", 3); - - + + rtObjectRef fontCapabilities = new rtMapObject; fontCapabilities.set("fallback", 1); mCapabilityVersions.set("font", fontCapabilities); - + #ifdef SPARK_CURSOR_SUPPORT graphicsCapabilities.set("cursor", 1); @@ -742,6 +733,7 @@ rtError pxScene2d::dispose() return RT_OK; } +// JRJR TODO... Try to get rid of this... but watch for leaks mentioned by Madan void pxScene2d::onCloseRequest() { rtLogInfo(__FUNCTION__); @@ -1012,7 +1004,7 @@ rtError pxScene2d::createShaderResource(rtObjectRef p, rtObjectRef& o) { rtString fragmentUrl = p.get("fragment"); rtString vertexUrl = p.get("vertex"); - + if(fragmentUrl.isEmpty() && vertexUrl.isEmpty()) { rtLogError("Failed to create [shaderResource] ... no Fragment/Vertex shader found."); @@ -1573,6 +1565,7 @@ void pxScene2d::onDraw() if (mTop) { + context.updateRenderTick(); #ifdef ENABLE_RT_NODE rtWrapperSceneUpdateEnter(); #endif //ENABLE_RT_NODE @@ -1701,7 +1694,7 @@ bool pxScene2d::onMouseDown(int32_t x, int32_t y, uint32_t flags) rtObjectRef e = new rtMapObject; e.set("name", "onMouseDown"); - e.set("target", (rtObject*)hit.getPtr()); + e.set("target", hit.getPtr()); e.set("x", hitPt.x); e.set("y", hitPt.y); e.set("flags", flags); @@ -1710,11 +1703,16 @@ bool pxScene2d::onMouseDown(int32_t x, int32_t y, uint32_t flags) #else bubbleEvent(e,hit,"onPreMouseDown","onMouseDown"); #endif + + setMouseEntered(hit); } + else + setMouseEntered(NULL); } return false; } + bool pxScene2d::onMouseUp(int32_t x, int32_t y, uint32_t flags) { #if 1 @@ -1724,7 +1722,70 @@ bool pxScene2d::onMouseUp(int32_t x, int32_t y, uint32_t flags) e.set("name", "onMouseUp"); e.set("x", x); e.set("y", y); - e.set("flags", static_cast(flags)); + e.set("flags", (uint32_t)flags); + mEmit.send("onMouseUp", e); + } +#endif + { + //Looking for an object + pxMatrix4f m; + pxPoint2f pt(static_cast(x),static_cast(y)), hitPt; + rtRef hit; + //rtRef tMouseDown = mMouseDown; + + if (mMouseDown) + { + // Since onClick is a proper subset of onMouseUp fire first so + // that appropriate action can be taken in this case. + + // TODO optimization... we really only need to check mMouseDown + if (mRoot && mRoot->hitTestInternal(m, pt, hit, hitPt)) + { + // Send onClick if this object got an onMouseDown + if (mMouseDown == hit) + { + rtObjectRef e = new rtMapObject; + e.set("name", "onClick"); + e.set("target",hit.getPtr()); + e.set("x", hitPt.x); // In object local coordinates + e.set("y", hitPt.y); + e.set("flags", flags); + bubbleEvent(e,hit,"onPreClick","onClick"); + } + setMouseEntered(hit); + } + + pxVector4f from(static_cast(x),static_cast(y),0,1); + pxVector4f to; + pxObject::transformPointFromSceneToObject(mMouseDown, from, to); + + rtObjectRef e = new rtMapObject; + e.set("name", "onMouseUp"); + e.set("target",mMouseDown.getPtr()); + e.set("x", to.x()); // In object local coordinates + e.set("y", to.y()); + e.set("flags", flags); + bubbleEvent(e,mMouseDown,"onPreMouseUp","onMouseUp"); + + mMouseDown = NULL; + } + else + setMouseEntered(NULL); + } + return false; +} + +#if 0 +bool pxScene2d::onMouseUp(int32_t x, int32_t y, uint32_t flags) +{ +#if 1 + { + // Send to root scene in global window coordinates + rtObjectRef e = new rtMapObject; + e.set("name", "onMouseUp"); + e.set("x", x); + e.set("y", y); + e.set("flags", (uint32_t)flags); mEmit.send("onMouseUp", e); } #endif @@ -1763,8 +1824,10 @@ bool pxScene2d::onMouseUp(int32_t x, int32_t y, uint32_t flags) } return false; } +#endif // TODO rtRef doesn't like non-const != +// JRJR what are the x and y for? void pxScene2d::setMouseEntered(rtRef o, int32_t x /* = 0*/, int32_t y /* = 0*/) { if (mMouseEntered != o) @@ -1787,11 +1850,8 @@ void pxScene2d::setMouseEntered(rtRef o, int32_t x /* = 0*/, int32_t y { rtObjectRef e = new rtMapObject; e.set("name", "onMouseEnter"); - e.set("target", o.getPtr()); - e.set("x", x); - e.set("y", y); - - bubbleEvent(e,o, "onPreMouseEnter", "onMouseEnter"); + e.set("target", mMouseEntered.getPtr()); + bubbleEvent(e,mMouseEntered, "onPreMouseEnter", "onMouseEnter"); } } } @@ -1851,12 +1911,19 @@ bool pxScene2d::onMouseEnter() bool pxScene2d::onMouseLeave() { // top level scene event + #if 0 rtObjectRef e = new rtMapObject; e.set("name", "onMouseLeave"); mEmit.send("onMouseLeave", e); + #endif - mMouseDown = NULL; + // Don't change here if dragging + if (!mMouseDown.getPtr()) + { + mMouseDown = NULL; + } setMouseEntered(NULL); + return false; } @@ -2036,9 +2103,11 @@ bool pxScene2d::onMouseMove(int32_t x, int32_t y) #if 1 { // Send to root scene in global window coordinates + // Used to send to child scenes for event propogation + // Always non translated events rtObjectRef e = new rtMapObject; e.set("name", "onMouseMove"); - e.set("x", x); + e.set("x", x); // Sent in global scene e.set("y", y); mEmit.send("onMouseMove", e); } @@ -2058,6 +2127,7 @@ bool pxScene2d::onMouseMove(int32_t x, int32_t y) pxObject::transformPointFromSceneToObject(mMouseDown, from, to); // to.dump(); + #if 0 { pxVector4f validate; pxObject::transformPointFromObjectToScene(mMouseDown, to, validate); @@ -2079,6 +2149,7 @@ bool pxScene2d::onMouseMove(int32_t x, int32_t y) to.x(),to.y(),validate.x(),validate.y()); } } + #endif #if 0 rtObjectRef e = new rtMapObject; @@ -2365,7 +2436,6 @@ rtError pxScene2d::showDirtyRect(bool& v) const v=mShowDirtyRectangle; return RT_OK; } - rtError pxScene2d::setShowDirtyRect(bool v) { mShowDirtyRectangle = v; @@ -2390,14 +2460,14 @@ rtError pxScene2d::dirtyRectanglesEnabled(bool& v) const { } rtError pxScene2d::dirtyRectangle(rtObjectRef& v) const { - v = new rtMapObject(); -if (gDirtyRectsEnabled) { + v = new rtMapObject(); + if (gDirtyRectsEnabled) { v.set("x1", mDirtyRect.left()); v.set("y1", mDirtyRect.top()); v.set("x2", mDirtyRect.right()); v.set("y2", mDirtyRect.bottom()); -} - return RT_OK; + } + return RT_OK; } rtError pxScene2d::enableDirtyRect(bool& v) const @@ -3387,7 +3457,7 @@ void pxScriptView::runScript() { mSparkHttp = new rtFunctionCallback(sparkHttp, NULL); } - //mCtx->add("view", this); + //mCtx->add("view", this); // JRJR TODO initially with zero mWidth/mHeight until onSize event // defer to onSize once events have been ironed out @@ -3405,7 +3475,7 @@ void pxScriptView::runScript() beginDrawing(); glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT); // compile initGL.js if (mSparkGlInitApp.isEmpty()) { @@ -3425,11 +3495,11 @@ void pxScriptView::runScript() bool b = true; // JRJR Adding an AddRef to this... causes bad things to happen when reloading gl scenes - // investigate... + // investigate... // JRJR WARNING! must use sendReturns since wrappers will invoke asyncronously otherwise. f.sendReturns(mUrl,mBeginDrawing.getPtr(),mEndDrawing.getPtr(), shadow.getPtr(), mBootstrap, mSparkHttp.getPtr(), b); endDrawing(); - + } else { @@ -3440,10 +3510,10 @@ void pxScriptView::runScript() s.append("init.js"); rtData initData; rtError e = rtLoadFile(s.cString(), initData); - + if (e != RT_OK) rtLogError("Failed to load file: %s", s.cString()); - + mSparkInitApp = rtString((char*)initData.data(), (uint32_t)initData.length()); } mCtx->runScript(mSparkInitApp.cString()); @@ -3513,7 +3583,7 @@ pxScriptView::~pxScriptView() mSharedContext->makeCurrent(false); } mDrawing = false; - + if (NULL != mBeginDrawing.getPtr()) mBeginDrawing->clearContext(); if (NULL != mEndDrawing.getPtr()) @@ -3530,7 +3600,7 @@ pxScriptView::~pxScriptView() shadow->emit()->clearListeners(); - // JRJR TODO Not Releasing GL Context + // JRJR TODO Not Releasing GL Context if(mScene) mEmit.send("onSceneRemoved", mScene); @@ -3698,7 +3768,7 @@ bool pxScriptView::onBlur() } bool pxScriptView::onKeyDown(uint32_t keycode, uint32_t flags) -{ +{ { rtObjectRef e = new rtMapObject; e.set("keyCode", keycode); @@ -3753,7 +3823,7 @@ void pxScriptView::onDraw(/*pxBuffer& b, pxRect* r*/) if (mView) mView->onDraw(); } - + } rtError pxScriptView::suspend(const rtValue& v, bool& b) @@ -3898,7 +3968,7 @@ rtError pxScriptView::beginDrawing2(int /*numArgs*/, const rtValue* /*args*/, rt if (ctx) { pxScriptView* v = (pxScriptView*)ctx; - v->beginDrawing(); + v->beginDrawing(); } return RT_OK; } @@ -3913,7 +3983,7 @@ rtError pxScriptView::endDrawing2(int /*numArgs*/, const rtValue* /*args*/, rtVa return RT_OK; } -// JRJR could be made much simpler... +// JRJR could be made much simpler... rtError pxScriptView::getSetting(int numArgs, const rtValue* args, rtValue* result, void* /*ctx*/) { if (numArgs >= 1) diff --git a/examples/pxScene2d/src/pxScene2d.h b/examples/pxScene2d/src/pxScene2d.h index 645adf3e86..a18593be80 100755 --- a/examples/pxScene2d/src/pxScene2d.h +++ b/examples/pxScene2d/src/pxScene2d.h @@ -81,10 +81,10 @@ class pxConstantsDragType; #ifdef RUNINMAIN #define ENTERSCENELOCK() -#define EXITSCENELOCK() +#define EXITSCENELOCK() #else #define ENTERSCENELOCK() rtWrapperSceneUpdateEnter(); -#define EXITSCENELOCK() rtWrapperSceneUpdateExit(); +#define EXITSCENELOCK() rtWrapperSceneUpdateExit(); class pxScriptView; class AsyncScriptInfo { public: @@ -104,7 +104,7 @@ extern rtThreadQueue* gUIThreadQueue; // TODO Finish //#include "pxTransform.h" #include "pxConstants.h" -#include "pxContextUtils.h" +#include "pxSharedContext.h" // Constants static pxConstants CONSTANTS; @@ -117,7 +117,7 @@ rtError createObject2(const char* t, rtObjectRef& o); typedef void (*pxAnimationEnded)(void* ctx); -struct pxAnimationTarget +struct pxAnimationTarget { char* prop; float to; @@ -138,7 +138,7 @@ struct animation double duration; pxConstantsAnimation::animationOptions options; - + pxInterp interpFunc; int32_t count; @@ -149,10 +149,10 @@ struct animation rtObjectRef animateObj; }; -struct pxPoint2f +struct pxPoint2f { pxPoint2f():x(0),y(0) {} - pxPoint2f(float _x, float _y) { x = _x; y = _y; } + pxPoint2f(float _x, float _y) { x = _x; y = _y; } float x, y; }; @@ -241,7 +241,7 @@ class pxViewContainer: public pxObject, public pxIViewContainer virtual void* getInterface(const char* /*name*/) { return NULL; - } + } #if 0 rtError url(rtString& v) const { v = mUri; return RT_OK; } @@ -249,21 +249,21 @@ class pxViewContainer: public pxObject, public pxIViewContainer #endif rtError w(float& v) const { v = mw; return RT_OK; } - rtError setW(float v) - { - mw = v; + rtError setW(float v) + { + mw = v; if (mView) - mView->onSize(static_cast(mw),static_cast(mh)); - return RT_OK; + mView->onSize(static_cast(mw),static_cast(mh)); + return RT_OK; } - + rtError h(float& v) const { v = mh; return RT_OK; } - rtError setH(float v) - { - mh = v; + rtError setH(float v) + { + mh = v; if (mView) - mView->onSize(static_cast(mw),static_cast(mh)); - return RT_OK; + mView->onSize(static_cast(mw),static_cast(mh)); + return RT_OK; } rtError onMouseDown(rtObjectRef o) @@ -473,13 +473,13 @@ class pxViewContainer: public pxObject, public pxIViewContainer pxObject::update(t,updateChildren); } - virtual void draw() + virtual void draw() { if (mView) mView->onDraw(); } - + protected: pxViewRef mView; @@ -505,7 +505,7 @@ class pxSceneContainer: public pxViewContainer rtMethod1ArgAndReturn("screenshot", screenshot, rtString, rtValue); // rtMethod1ArgAndNoReturn("makeReady", makeReady, bool); // DEPRECATED ? - + pxSceneContainer(pxScene2d* scene):pxViewContainer(scene){ pxSceneContainerCount++;} virtual ~pxSceneContainer() {rtLogDebug("###############~pxSceneContainer\n");pxSceneContainerCount--;} @@ -524,7 +524,7 @@ class pxSceneContainer: public pxViewContainer rtError api(rtValue& v) const; rtError ready(rtObjectRef& o) const; - + rtError serviceContext(rtObjectRef& o) const { o = mServiceContext; return RT_OK;} rtError setServiceContext(rtObjectRef o); @@ -540,16 +540,16 @@ class pxSceneContainer: public pxViewContainer // rtError makeReady(bool ready); // DEPRECATED ? - // in the case of pxSceneContainer, the makeReady should be the - // catalyst for ready to fire, so override sendPromise - // to prevent firing from update() + // in the case of pxSceneContainer, the makeReady should be the + // catalyst for ready to fire, so override sendPromise + // to prevent firing from update() virtual void sendPromise() { /*rtLogDebug("pxSceneContainer ignoring sendPromise\n");*/ } virtual void* getInterface(const char* name); virtual void releaseData(bool sceneSuspended); virtual void reloadData(bool sceneSuspended); virtual uint64_t textureMemoryUsage(std::vector &objectsCounted); - + private: rtRef mScriptView; rtString mUrl; @@ -602,13 +602,13 @@ class pxScriptView: public rtObject, public pxIView void runScript(); // Run the script - virtual unsigned long AddRef() + virtual unsigned long AddRef() { //rtLogInfo(__FUNCTION__); return rtAtomicInc(&mRefCount); } - - virtual unsigned long Release() + + virtual unsigned long Release() { //rtLogInfo(__FUNCTION__); long l = rtAtomicDec(&mRefCount); @@ -631,7 +631,7 @@ class pxScriptView: public rtObject, public pxIView { if (!mReady) return RT_FAIL; - + o = mReady; return RT_OK; } @@ -659,7 +659,7 @@ class pxScriptView: public rtObject, public pxIView rtError textureMemoryUsage(rtValue& v); rtError screenshot(rtString type, rtValue& returnValue); - + protected: @@ -691,7 +691,7 @@ class pxScriptView: public rtObject, public pxIView virtual bool onMouseDown(int32_t x, int32_t y, uint32_t flags); virtual bool onMouseUp(int32_t x, int32_t y, uint32_t flags); virtual bool onMouseMove(int32_t x, int32_t y); - + virtual bool onDragMove( int32_t x, int32_t y, int32_t type); virtual bool onDragEnter(int32_t x, int32_t y, int32_t type); virtual bool onDragLeave(int32_t x, int32_t y, int32_t type); @@ -787,7 +787,7 @@ class pxScene2d: public rtObject, public pxIView, public rtIServiceProvider rtReadOnlyProperty(dirtyRectanglesEnabled, dirtyRectanglesEnabled, bool); rtProperty(enableDirtyRect, enableDirtyRect, setEnableDirtyRect, bool); rtProperty(customAnimator, customAnimator, setCustomAnimator, rtFunctionRef); - rtMethod1ArgAndReturn("loadArchive",loadArchive,rtString,rtObjectRef); + rtMethod1ArgAndReturn("loadArchive",loadArchive,rtString,rtObjectRef); rtMethod1ArgAndReturn("create", create, rtObjectRef, rtObjectRef); rtMethodNoArgAndReturn("clock", clock, double); rtMethodNoArgAndNoReturn("logDebugMetrics", logDebugMetrics); @@ -812,10 +812,10 @@ class pxScene2d: public rtObject, public pxIView, public rtIServiceProvider // focus is now a bool property on pxObject //rtMethod1ArgAndNoReturn("setFocus", setFocus, rtObjectRef); rtMethodNoArgAndReturn("getFocus", getFocus, rtObjectRef); - - + + // rtMethodNoArgAndNoReturn("stopPropagation",stopPropagation); - + rtMethod1ArgAndReturn("screenshot", screenshot, rtString, rtValue); rtMethod1ArgAndReturn("clipboardGet", clipboardGet, rtString, rtString); @@ -824,8 +824,8 @@ class pxScene2d: public rtObject, public pxIView, public rtIServiceProvider rtMethod1ArgAndReturn("getService", getService, rtString, rtObjectRef); rtMethodNoArgAndReturn("getAvailableApplications", getAvailableApplications, rtString); - - + + rtProperty(ctx, ctx, setCtx, rtValue); rtProperty(api, api, setAPI, rtValue); // rtReadOnlyProperty(emit, emit, rtFunctionRef); @@ -1157,9 +1157,9 @@ class pxScene2d: public rtObject, public pxIView, public rtIServiceProvider private: static void updateObjects(double t); - bool bubbleEvent(rtObjectRef e, rtRef t, + bool bubbleEvent(rtObjectRef e, rtRef t, const char* preEvent, const char* event) ; - + bool bubbleEventOnBlur(rtObjectRef e, rtRef t, rtRef o); void draw(); @@ -1250,7 +1250,7 @@ class pxScene2dRef: public rtRef, public rtObjectBase // operator= is not inherited pxScene2dRef& operator=(pxScene2d* s) { asn(s); return *this; } - + private: virtual rtError Get(const char* name, rtValue* value) const override; virtual rtError Get(uint32_t i, rtValue* value) const override; diff --git a/examples/pxScene2d/src/pxWebGL.cpp b/examples/pxScene2d/src/pxWebGL.cpp index 9971b06a4c..1fe77ed94d 100644 --- a/examples/pxScene2d/src/pxWebGL.cpp +++ b/examples/pxScene2d/src/pxWebGL.cpp @@ -17,7 +17,7 @@ */ #include "pxWebGL.h" -#include "pxContextUtils.h" +#include "pxSharedContext.h" #include "pxContext.h" #include @@ -104,12 +104,12 @@ void pxWebgl::onInit() { mReady.send("resolve",this); pxObject::onInit(); - + rtLogDebug("[%s]", __FUNCTION__); - + pixelStorei_UNPACK_FLIP_Y_WEBGL = 0; pixelStorei_UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0; - pixelStorei_UNPACK_FLIP_BLUE_RED = 0; + pixelStorei_UNPACK_FLIP_BLUE_RED = 0; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mInitialFrameBuffer); CheckGLError(); @@ -232,7 +232,7 @@ rtError pxWebgl::pixelStorei(uint32_t pname, bool param) if (pname == 0x9240 /* UNPACK_FLIP_Y_WEBGL */) { pixelStorei_UNPACK_FLIP_Y_WEBGL = param; - } else if (pname == 0x9241 /* UNPACK_PREMULTIPLY_ALPHA_WEBGL */) { + } else if (pname == 0x9241 /* UNPACK_PREMULTIPLY_ALPHA_WEBGL */) { pixelStorei_UNPACK_PREMULTIPLY_ALPHA_WEBGL = param; } else if (pname == 0x9245 /* UNPACK_FLIP_BLUE_RED */) { pixelStorei_UNPACK_FLIP_BLUE_RED = param; @@ -277,7 +277,7 @@ rtError pxWebgl::clearColor(float_t red, float_t green, float_t blue, float_t al rtError pxWebgl::Clear(uint32_t mask) { rtLogDebug("[%s] mask: %u", __FUNCTION__, mask); - + glClear(mask); CheckGLError(); @@ -299,7 +299,7 @@ rtError pxWebgl::texImage2D(uint32_t target, uint32_t level, uint32_t internalfo rtLogDebug("[%s] target: %d level: %d internalformat: %d width: %d height %d format %d", __FUNCTION__, target, level, internalformat, width, height, format); rtArrayObject* pixelArray = (rtArrayObject*) data.toObject().getPtr(); - + void *pixels = NULL; if(pixelArray) { @@ -719,7 +719,7 @@ rtError pxWebgl::DisableVertexAttribArray(uint32_t index) rtError pxWebgl::CreateFramebuffer(uint32_t& buffer) { rtLogDebug("[%s]", __FUNCTION__); - + glGenFramebuffers(1, &buffer); CheckGLError(); @@ -732,17 +732,17 @@ rtError pxWebgl::CreateFramebuffer(uint32_t& buffer) } rtLogDebug("[%s] returning buffer: %u",__FUNCTION__, buffer); - + return RT_OK; } rtError pxWebgl::FramebufferTexture2D(uint32_t target, uint32_t attachment, uint32_t textarget, uint32_t texture, uint32_t level) { rtLogDebug("[%s] target: %u, attachment: %u, textarget: %u, texture: %u, level: %u", __FUNCTION__, target, attachment, textarget, texture, level); - + glFramebufferTexture2D(target, attachment, textarget, texture, level); CheckGLError(); - + return RT_OK; } diff --git a/examples/pxScene2d/src/sparkWindow.h b/examples/pxScene2d/src/sparkWindow.h new file mode 100644 index 0000000000..6e5d0a60af --- /dev/null +++ b/examples/pxScene2d/src/sparkWindow.h @@ -0,0 +1,156 @@ +/* + + pxCore Copyright 2005-2021 John Robinson + Spark Copyright 2016-2021 John Robinson + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +// sparkWindow.h + +#include "pxViewWindow.h" +#include "pxScene2d.h" + +#include + +#define MAX_URL_SIZE 8000 + +extern pxEventLoop eventLoop; +extern pxContext context; +extern rtScript script; +extern bool gDumpMemUsage; +extern bool gApplicationIsClosing; +extern int pxObjectCount; +extern double gCollectionTime; + +class sparkWindow: public pxViewWindow { + public: + sparkWindow(): mClosed(false) {} + virtual ~sparkWindow() { mView = NULL; } + + void init(int x, int y, int w, int h, const char *url = NULL) { + pxWindow::init(x, y, w, h); + setUrl(url); + } + + void *getInterface(const char * /*name*/) { return NULL; } + + rtError setUrl(const char *url) { + // escape url begin + std::string escapedUrl; + std::string origUrl = url; + for (std::string::iterator it = origUrl.begin(); it != origUrl.end(); ++it) { + char currChar = *it; + if ((currChar == '"') || (currChar == '\\')) { + escapedUrl.append(1, '\\'); + } + escapedUrl.append(1, currChar); + } + if (escapedUrl.length() > MAX_URL_SIZE) { + rtLogWarn( + "url size greater than MAX_URL_SIZE, reset to empty url to get " + "default behavior"); + escapedUrl = ""; + } + // escape url end + char buffer[MAX_URL_SIZE + 50]; + memset(buffer, 0, sizeof(buffer)); + + if (std::string::npos != escapedUrl.find("http")) { + snprintf(buffer, sizeof(buffer), "shell.js?url=%s", + rtUrlEncodeParameters(escapedUrl.c_str()).cString()); + } else { + snprintf(buffer, sizeof(buffer), "shell.js?url=%s", escapedUrl.c_str()); + } + + setView(new pxScriptView(buffer, "javascript/node/v8")); + + return RT_OK; + } + + protected: + + virtual void onCloseRequest() { + if (mClosed) + return; + + mClosed = true; + + if (gDumpMemUsage) + gApplicationIsClosing = true; + + rtLogInfo(__FUNCTION__); + fflush(stdout); + if (mView) { + rtLogInfo("onClose request started"); + fflush(stdout); + mView->onCloseRequest(); + rtLogInfo("onClose request completed"); + fflush(stdout); + } + + // pxScene.cpp:104:12: warning: deleting object of abstract class type + // ‘pxIView’ which has non-virtual destructor will cause undefined behaviour + // [-Wdelete-non-virtual-dtor] + + mView = NULL; + + context.term(); + + script.pump(); + + rtLogInfo("about to call garbage collect during close"); + fflush(stdout); + script.collectGarbage(); + rtLogInfo("called garbage collect during close"); + fflush(stdout); + + if (gDumpMemUsage) { + script.pump(); + script.collectGarbage(); + + rtLogInfo("pxobjectcount is [%d]", pxObjectCount); + + rtLogInfo("texture memory usage is [%" PRId64 "]", + context.currentTextureMemoryUsageInBytes()); + + fflush(stdout); + } +#ifdef ENABLE_CODE_COVERAGE + __gcov_flush(); +#endif + + close(); + eventLoop.exit(); + } + + virtual void onAnimationTimer() { + static double lastCollectionTime = pxSeconds(); + + if (mView && !mClosed) + mView->onUpdate(pxSeconds()); + + script.pump(); + + double currentTime = pxSeconds(); + if ((gCollectionTime > 0) && + (currentTime - lastCollectionTime > gCollectionTime)) { + script.collectGarbage(); + lastCollectionTime = currentTime; + } + } + + protected: + bool mClosed; +}; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9ec759cfb1..6e0346be06 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,6 +44,7 @@ add_definitions(-DSUPPORT_GIF) endif (BUILD_WITH_GIF) +add_definitions(-DPXSCENE_FONT_ATLAS) if (APPLE) message("Building pxcore for mac") @@ -61,7 +62,7 @@ if (APPLE) -DU_STATIC_IMPLEMENTATION=1 -DU_HAVE_STD_STRING=0 -DUCONFIG_NO_BREAK_ITERATION=0 -DUCONFIG_NO_LEGACY_CONVERSION=1 -DUCONFIG_NO_CONVERSION=1 -DHTTP_PARSER_STRICT=0 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DRT_PLATFORM_LINUX -DENABLE_NODE_V_6_9) - set(PXCORE_FILES mac/pxBufferNative.mm mac/pxOffscreenNative.mm mac/pxWindowNative.mm + set(PXCORE_FILES mac/pxBufferNative.mm mac/pxOffscreenNative.mm mac/pxSharedContextNative.mm mac/pxWindowNative.mm mac/pxEventLoopNative.mm mac/pxTimerNative.mm mac/pxTimerNative.mm mac/pxClipboardNative.mm mac/window.mm unix/rtMutexNative.cpp unix/rtThreadPoolNative.cpp @@ -160,7 +161,7 @@ elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} glut) set(PXCORE_FILES glut/pxBufferNative.cpp glut/pxOffscreenNative.cpp glut/pxWindowNative.cpp glut/pxEventLoopNative.cpp glut/pxTimerNative.cpp glut/pxClipboardNative.cpp pxViewWindow.cpp - unix/rtMutexNative.cpp unix/rtThreadPoolNative.cpp + unix/rtMutexNative.cpp unix/rtThreadPoolNative.cpp glut/pxSharedContextNative.cpp rtFileCache.cpp rtHttpCache.cpp) set(PLATFORM_LINKER_FLAGS) if (DEFINED ENV{CODE_COVERAGE}) @@ -180,7 +181,7 @@ elseif(WIN32) add_definitions(-DENABLE_RT_NODE -DRUNINMAIN) add_definitions(-DPX_PLATFORM_WIN -DRT_PLATFORM_WINDOWS -DWIN32 -DWIN32_LEAN_AND_MEAN -DGLEW_STATIC -D_TIMESPEC_DEFINED -D_CONSOLE -DCURL_STATICLIB -DRUNINMAIN -DENABLE_RT_NODE -DDISABLE_WAYLAND -DNODE_WANT_INTERNALS=1 - -DENABLE_NODE_V_6_9 -DENABLE_V8_HEAP_PARAMS=1 -DV8_DEPRECATION_WARNINGS=1 -DNODE_SHARED_MODE + -DENABLE_NODE_V_6_9 -DENABLE_V8_HEAP_PARAMS=1 -DV8_DEPRECATION_WARNINGS=1 -DNODE_SHARED_MODE -DENABLE_MAX_TEXTURE_SIZE -DHAVE_OPENSSL -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -D_HAS_EXCEPTIONS=0 -DBUILDING_V8_SHARED=1 -DBUILDING_UV_SHARED=1 -DNODE_ARCH="ia32" -DNODE_USE_V8_PLATFORM=1 -DNODE_HAVE_I18N_SUPPORT=1 -DNODE_HAVE_SMALL_ICU=1 @@ -191,8 +192,9 @@ elseif(WIN32) add_definitions(-DWIN32 -D_LIB -DNDEBUG -DPX_PLATFORM_WIN -DRT_PLATFORM_WINDOWS) add_definitions(${COMM_DEPS_DEFINITIONS}) include_directories(AFTER ${COMM_DEPS_INCLUDE_DIRS}) - include_directories(AFTER "${EXTDIR}/pthread-2.9") - set(PXCORE_FILES win/pxBufferNative.cpp win/pxOffscreenNative.cpp win/pxWindowNative.cpp + set(WINSPARKLEINC ${EXTDIR}/WinSparkle/include) + include_directories(AFTER "${EXTDIR}/pthread-2.9" ${WINSPARKLEINC} ${EXTDIR}/breakpad-chrome_55/src/) + set(PXCORE_FILES win/pxBufferNative.cpp win/pxOffscreenNative.cpp win/pxSharedContextNative.cpp win/pxWindowNative.cpp win/pxEventLoopNative.cpp win/pxTimerNative.cpp win/pxClipboardNative.cpp pxViewWindow.cpp win/rtMutexNative.cpp win/rtThreadPoolNative.cpp) set_source_files_properties(utf8.c PROPERTIES LANGUAGE CXX) @@ -214,7 +216,7 @@ include_directories(AFTER ${V8_INCLUDE_DIRS}) include_directories(AFTER ${NODE_INCLUDE_DIRS}) include_directories(AFTER ${CMAKE_CURRENT_SOURCE_DIR}) -set(PXCORE_FILES ${PXCORE_FILES} pxOffscreen.cpp pxWindowUtil.cpp pxColorNames.cpp +set(PXCORE_FILES ${PXCORE_FILES} pxOffscreen.cpp pxContextGL.cpp pxShaderUtils.cpp pxWindowUtil.cpp pxColorNames.cpp pxViewWindow.cpp rtFile.cpp rtLibrary.cpp rtPathUtils.cpp rtTest.cpp rtThreadPool.cpp rtThreadQueue.cpp rtThreadTask.cpp rtUrlUtils.cpp @@ -222,7 +224,7 @@ set(PXCORE_FILES ${PXCORE_FILES} pxOffscreen.cpp pxWindowUtil.cpp pxColorNames.c rtFileDownloader.cpp unzip.c ioapi.c rtScript.cpp rtSettings.cpp rtCORS.cpp rtHttpRequest.cpp rtHttpResponse.cpp - rtJsonUtils.cpp + rtJsonUtils.cpp rtPhoneHome.cpp rtSoftwareUpdate.cpp ) if (SUPPORT_STORAGE) @@ -240,7 +242,7 @@ endif() if (SUPPORT_NODE) message("Adding Node scripting support") add_definitions(-DRTSCRIPT_SUPPORT_NODE) - set(PXCORE_FILES ${PXCORE_FILES} rtScriptV8/rtScriptNode.cpp rtScriptV8/jsCallback.cpp rtScriptV8/rtFunctionWrapper.cpp + set(PXCORE_FILES ${PXCORE_FILES} rtScriptV8/rtScriptNode.cpp rtScriptV8/jsCallback.cpp rtScriptV8/rtFunctionWrapper.cpp rtScriptV8/rtObjectWrapper.cpp rtScriptV8/rtWrapperUtils.cpp) if (USE_NODE_10) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y") @@ -253,7 +255,7 @@ if (SUPPORT_V8) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=deprecated-declarations") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=deprecated-declarations") include_directories(AFTER ${EXTDIR}/uWebSockets/src) - set(PXCORE_FILES ${PXCORE_FILES} rtScriptV8/rtScriptV8.cpp rtScriptV8/jsCallback.cpp rtScriptV8/rtFunctionWrapper.cpp + set(PXCORE_FILES ${PXCORE_FILES} rtScriptV8/rtScriptV8.cpp rtScriptV8/jsCallback.cpp rtScriptV8/rtFunctionWrapper.cpp rtScriptV8/rtObjectWrapper.cpp rtScriptV8/rtWrapperUtils.cpp rtScriptV8/rtWebSocket.cpp ${V8_SOURCES}) endif() diff --git a/src/glut/pxConfigNative.h b/src/glut/pxConfigNative.h index f033273e5e..ff80c670e5 100644 --- a/src/glut/pxConfigNative.h +++ b/src/glut/pxConfigNative.h @@ -41,6 +41,7 @@ limitations under the License. #include "pxOffscreenNative.h" #include "pxWindowNative.h" #include "pxClipboardNative.h" +#include "pxSharedContextNative.h" #endif // PX_NATIVE diff --git a/src/glut/pxSharedContextNative.cpp b/src/glut/pxSharedContextNative.cpp new file mode 100644 index 0000000000..4587b250b4 --- /dev/null +++ b/src/glut/pxSharedContextNative.cpp @@ -0,0 +1,17 @@ +#include "pxSharedContext.h" + +#include +#include +#include +#include +#include "rtLog.h" +#include "rtMutex.h" + + +// TODO webgl won't work until this is wired up + +pxSharedContextNative::pxSharedContextNative(bool depthBuffer):context(NULL) {} + +pxSharedContextNative::~pxSharedContextNative() {} + +void pxSharedContext::makeCurrent(bool f) {} \ No newline at end of file diff --git a/examples/pxScene2d/src/win/pxContextUtils.cpp b/src/glut/pxSharedContextNative.h similarity index 60% rename from examples/pxScene2d/src/win/pxContextUtils.cpp rename to src/glut/pxSharedContextNative.h index 282ae8a74f..a3968cef89 100644 --- a/examples/pxScene2d/src/win/pxContextUtils.cpp +++ b/src/glut/pxSharedContextNative.h @@ -16,25 +16,25 @@ limitations under the License. */ -#include "pxContextUtils.h" - -int nextInternalContextId = 0; - -pxError createInternalContext(int &id, bool /*depthBuffer*/) -{ - id = nextInternalContextId++; - //TODO - return PX_OK; -} - -pxError deleteInternalGLContext(int id) -{ - //TODO - return PX_OK; -} - -pxError makeInternalGLContextCurrent(bool, int) -{ - //TODO - return PX_OK; -} +#ifndef PX_SHAREDCONTEXTNATIVE_H +#define PX_SHAREDCONTEXTNATIVE_H + +#include +#include +#include + +#include "rtAtomic.h" +#include "rtRef.h" + +#include "pxCore.h" + +class pxSharedContextNative { +public: + pxSharedContextNative(bool depthBuffer); + virtual ~pxSharedContextNative(); + +private: + void* context; +}; + +#endif //PX_SHARED_CONTEXT_NATIVE_H diff --git a/src/mac/pxConfigNative.h b/src/mac/pxConfigNative.h index 82768f4195..fb1731b5eb 100644 --- a/src/mac/pxConfigNative.h +++ b/src/mac/pxConfigNative.h @@ -26,10 +26,12 @@ limitations under the License. #define PX_LITTLEENDIAN_PIXELS #define PX_LITTLEENDIAN_RGBA_PIXELS + #include "pxBufferNative.h" #include "pxOffscreenNative.h" #include "pxWindowNative.h" #include "pxClipboardNative.h" +#include "pxSharedContextNative.h" #endif diff --git a/src/mac/pxSharedContextNative.h b/src/mac/pxSharedContextNative.h new file mode 100644 index 0000000000..d282adb945 --- /dev/null +++ b/src/mac/pxSharedContextNative.h @@ -0,0 +1,42 @@ +/* + +pxCore Copyright 2005-2018 John Robinson + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +#ifndef PX_SHAREDCONTEXTNATIVE_H +#define PX_SHAREDCONTEXTNATIVE_H + +#include +#include +//#import + +#include "rtAtomic.h" +#include "rtRef.h" + +#include "pxCore.h" + +class pxSharedContextNative { +public: + pxSharedContextNative(bool depthBuffer); + virtual ~pxSharedContextNative(); + + //void makeCurrent(bool f); + +protected: + void *context; // NSOpenGLContext* +}; + +#endif //PX_SHARED_CONTEXT_NATIVE_H diff --git a/examples/pxScene2d/src/mac/pxContextUtils.mm b/src/mac/pxSharedContextNative.mm similarity index 57% rename from examples/pxScene2d/src/mac/pxContextUtils.mm rename to src/mac/pxSharedContextNative.mm index e6401bd7b3..4fc77d5d3e 100644 --- a/examples/pxScene2d/src/mac/pxContextUtils.mm +++ b/src/mac/pxSharedContextNative.mm @@ -1,4 +1,4 @@ -#include "pxContextUtils.h" +#include "pxSharedContext.h" #include #include @@ -7,43 +7,44 @@ #include "rtLog.h" #include "rtMutex.h" +#if 0 bool glContextIsCurrent = false; rtMutex eglContextMutex; int nextInternalContextId = 1; -extern NSOpenGLContext *openGLContext; +#endif -NSOpenGLPixelFormatAttribute attribs[] = - { - /*NSOpenGLPFADoubleBuffer,*/ - NSOpenGLPFAAllowOfflineRenderers, // lets OpenGL know this context is offline renderer aware - NSOpenGLPFAMultisample, 1, - NSOpenGLPFASampleBuffers, 1, - NSOpenGLPFASamples, 4, - NSOpenGLPFAColorSize, 32, - NSOpenGLPFAOpenGLProfile,NSOpenGLProfileVersionLegacy/*, NSOpenGLProfileVersion3_2Core*/, // Core Profile is the future - 0 - }; - -NSOpenGLPixelFormatAttribute attribsWithDepth[] = - { - /*NSOpenGLPFADoubleBuffer,*/ - NSOpenGLPFADepthSize,32, - NSOpenGLPFAAllowOfflineRenderers, // lets OpenGL know this context is offline renderer aware - NSOpenGLPFAMultisample, 1, - NSOpenGLPFASampleBuffers, 1, - NSOpenGLPFASamples, 4, - NSOpenGLPFADepthSize, 32, - NSOpenGLPFAOpenGLProfile,NSOpenGLProfileVersionLegacy/*, NSOpenGLProfileVersion3_2Core*/, // Core Profile is the future - 0 - }; +extern NSOpenGLContext *openGLContext; // TODO try to get rid of thsi... + +NSOpenGLPixelFormatAttribute attribs[] = { + /*NSOpenGLPFADoubleBuffer,*/ + NSOpenGLPFAAllowOfflineRenderers, // lets OpenGL know this context is offline renderer aware + NSOpenGLPFAMultisample, 1, + NSOpenGLPFASampleBuffers, 1, + NSOpenGLPFASamples, 4, + NSOpenGLPFAColorSize, 32, + NSOpenGLPFAOpenGLProfile,NSOpenGLProfileVersionLegacy/*, NSOpenGLProfileVersion3_2Core*/, // Core Profile is the future + 0 +}; + +NSOpenGLPixelFormatAttribute attribsWithDepth[] = { + /*NSOpenGLPFADoubleBuffer,*/ + NSOpenGLPFADepthSize,32, + NSOpenGLPFAAllowOfflineRenderers, // lets OpenGL know this context is offline renderer aware + NSOpenGLPFAMultisample, 1, + NSOpenGLPFASampleBuffers, 1, + NSOpenGLPFASamples, 4, + NSOpenGLPFADepthSize, 32, + NSOpenGLPFAOpenGLProfile,NSOpenGLProfileVersionLegacy/*, NSOpenGLProfileVersion3_2Core*/, // Core Profile is the future + 0 +}; NSOpenGLPixelFormat *internalPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; NSOpenGLPixelFormat *internalPixelWithDepthFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribsWithDepth]; -std::map internalContexts; - +//std::map internalContexts; +#if 0 pxError createGLContext(int id, bool depthBuffer) { NSOpenGLContext *context = nil; @@ -122,3 +123,32 @@ pxError makeInternalGLContextCurrent(bool current, int id) } return PX_OK; } +#endif + +pxSharedContextNative::pxSharedContextNative(bool depthBuffer):context(NULL) { + if (depthBuffer) + context = (void*)[[NSOpenGLContext alloc] initWithFormat:internalPixelFormat shareContext:openGLContext]; + else + context = (void*)[[NSOpenGLContext alloc] initWithFormat:internalPixelWithDepthFormat shareContext:openGLContext]; +} + +pxSharedContextNative::~pxSharedContextNative() { + if (context) { + NSOpenGLContext* c = (NSOpenGLContext*)context; + [c release]; + context = NULL; + } +} + +void pxSharedContext::makeCurrent(bool f) { + if (f) { + NSOpenGLContext* c = (NSOpenGLContext*)context; + [c makeCurrentContext]; + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + } + else { + glFlush(); + [openGLContext makeCurrentContext]; + } +} \ No newline at end of file diff --git a/src/mac/pxWindowNative.mm b/src/mac/pxWindowNative.mm index c0dc3d50e4..d932689ce9 100644 --- a/src/mac/pxWindowNative.mm +++ b/src/mac/pxWindowNative.mm @@ -417,17 +417,21 @@ - (void)drawView { //GLGL #ifdef GLGL + [[self openGLContext] makeCurrentContext]; // We draw on a secondary thread through the display link // Add a mutex around to avoid the threads from accessing the context simultaneously CGLLockContext([[self openGLContext] CGLContextObj]); +// TODO not sure what drawView is doing ... doesn't seem to actually draw anything... +#if 1 glViewport(0,0,[self bounds].size.width,[self bounds].size.height); glClearColor(0.675f,0.675f,0.675f,1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); #endif +#endif #if 0 @@ -1179,6 +1183,7 @@ -(void)drawRect:(NSRect)dirtyRect { [view setNeedsDisplay:YES]; } +#if 0 // needed to "forcibly allow" a drawRect call to occur whilst resizing a window if ([view inLiveResize]) { @@ -1186,6 +1191,7 @@ -(void)drawRect:(NSRect)dirtyRect { [view displayIfNeeded]; }]; } +#endif } bool pxWindow::visibility() diff --git a/examples/pxScene2d/src/pxContext.h b/src/pxContext.h similarity index 91% rename from examples/pxScene2d/src/pxContext.h rename to src/pxContext.h index 3daadee886..79b853cf17 100644 --- a/examples/pxScene2d/src/pxContext.h +++ b/src/pxContext.h @@ -27,10 +27,10 @@ #include "pxCore.h" #include "pxOffscreen.h" #include "pxMatrix4T.h" -#include "pxConstants.h" +//#include "pxConstants.h" #include "pxTexture.h" #include "pxContextFramebuffer.h" -#include "pxContextUtils.h" +#include "pxSharedContext.h" #include "pxEffects.h" #ifdef ENABLE_DFB @@ -54,6 +54,17 @@ class shaderProgram; //fwd #define PXSCENE_DEFAULT_TEXTURE_MEMORY_LIMIT_THRESHOLD_PADDING_IN_BYTES (5 * 1024 * 1024) #endif +typedef enum pxContextMaskOperation { + NORMAL = 0, + INVERT, +} pxContextMask; + +typedef enum pxContextStretch { + NONE = 0, + STRETCH, + REPEAT, + } pxContextStretch; + class pxContext { public: @@ -76,7 +87,7 @@ class pxContext { void init(); void term(); - // debugging outlines + // debugging outlines bool showOutlines() { return mShowOutlines; } void setShowOutlines(bool v) { mShowOutlines = v; } @@ -116,15 +127,15 @@ class pxContext { // convenience method void drawImageMasked(float x, float y, float w, float h, - pxConstantsMaskOperation::constants maskOp, + pxContextMaskOperation maskOp, pxTextureRef t, pxTextureRef mask); - + void drawImage(float x, float y, float w, float h, pxTextureRef t, pxTextureRef mask, bool useTextureDimsAlways = true, float* color = NULL, - pxConstantsStretch::constants xStretch = pxConstantsStretch::STRETCH, - pxConstantsStretch::constants yStretch = pxConstantsStretch::STRETCH, + pxContextStretch xStretch = pxContextStretch::STRETCH, + pxContextStretch yStretch = pxContextStretch::STRETCH, bool downscaleSmooth = false, - pxConstantsMaskOperation::constants maskOp= pxConstantsMaskOperation::NORMAL); + pxContextMaskOperation maskOp = NORMAL); void drawEffect(float x, float y, float w, float h, pxTextureRef t, shaderProgram *shader, void *options = nullptr); @@ -144,7 +155,7 @@ class pxContext { void drawImage9(float w, float h, float x1, float y1, float x2, float y2, pxTextureRef texture); - void drawImage9Border(float w, float h, + void drawImage9Border(float w, float h, float bx1, float by1, float bx2, float by2, float ix1, float iy1, float ix2, float iy2, bool drawCenter, float* color, @@ -154,7 +165,7 @@ class pxContext { float dst_x, float dst_y, float w, float h, pxOffscreen &offscreen); - + // Only use for debug/diag purposes not for normal rendering void drawDiagRect(float x, float y, float w, float h, float* color); void drawDiagLine(float x1, float y1, float x2, float y2, float* color); @@ -165,7 +176,7 @@ class pxContext { int64_t currentTextureMemoryUsageInBytes(); int64_t textureMemoryOverflow(pxTextureRef texture); int64_t ejectTextureMemory(int64_t bytesRequested, bool forceEject=false); - + pxError setEjectTextureAge(uint32_t age); void updateRenderTick(); diff --git a/examples/pxScene2d/src/pxContextDescGL.h b/src/pxContextDescGL.h similarity index 100% rename from examples/pxScene2d/src/pxContextDescGL.h rename to src/pxContextDescGL.h diff --git a/examples/pxScene2d/src/pxContextFramebuffer.h b/src/pxContextFramebuffer.h similarity index 100% rename from examples/pxScene2d/src/pxContextFramebuffer.h rename to src/pxContextFramebuffer.h diff --git a/examples/pxScene2d/src/pxContextGL.cpp b/src/pxContextGL.cpp similarity index 97% rename from examples/pxScene2d/src/pxContextGL.cpp rename to src/pxContextGL.cpp index 01af9a6621..8f76e6a071 100644 --- a/examples/pxScene2d/src/pxContextGL.cpp +++ b/src/pxContextGL.cpp @@ -58,7 +58,7 @@ #endif //PX_PLATFORM_WAYLAND_EGL #endif -#include "pxContextUtils.h" +#include "pxSharedContext.h" #include "pxTimer.h" #define PX_TEXTURE_MIN_FILTER GL_LINEAR @@ -1686,9 +1686,9 @@ class textureShaderProgram: public shaderProgram } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, - (stretchX==pxConstantsStretch::REPEAT)?GL_REPEAT:GL_CLAMP_TO_EDGE); + (stretchX==pxContextStretch::REPEAT)?GL_REPEAT:GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, - (stretchY==pxConstantsStretch::REPEAT)?GL_REPEAT:GL_CLAMP_TO_EDGE); + (stretchY==pxContextStretch::REPEAT)?GL_REPEAT:GL_CLAMP_TO_EDGE); glVertexAttribPointer(mPosLoc, 2, GL_FLOAT, GL_FALSE, 0, pos); glVertexAttribPointer(mUVLoc, 2, GL_FLOAT, GL_FALSE, 0, uv); @@ -1767,9 +1767,9 @@ class textureBorderShaderProgram: public shaderProgram } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, - (stretchX==pxConstantsStretch::REPEAT)?GL_REPEAT:GL_CLAMP_TO_EDGE); + (stretchX==pxContextStretch::REPEAT)?GL_REPEAT:GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, - (stretchY==pxConstantsStretch::REPEAT)?GL_REPEAT:GL_CLAMP_TO_EDGE); + (stretchY==pxContextStretch::REPEAT)?GL_REPEAT:GL_CLAMP_TO_EDGE); glVertexAttribPointer(mPosLoc, 2, GL_FLOAT, GL_FALSE, 0, pos); glVertexAttribPointer(mUVLoc, 2, GL_FLOAT, GL_FALSE, 0, uv); @@ -1830,7 +1830,7 @@ class textureMaskedShaderProgram: public shaderProgram const void* uv, pxTextureRef texture, pxTextureRef mask, - pxConstantsMaskOperation::constants maskOp = pxConstantsMaskOperation::NORMAL) + pxContextMaskOperation maskOp = pxContextMaskOperation::NORMAL) { use(); // change program... if needed @@ -1838,7 +1838,7 @@ class textureMaskedShaderProgram: public shaderProgram glUniformMatrix4fv(mMatrixLoc, 1, GL_FALSE, matrix); glUniform1i(mFlipYLoc, gFlipRendering); glUniform1f(mAlphaLoc, alpha); - glUniform1f(mInvertedLoc, static_cast((maskOp == pxConstantsMaskOperation::NORMAL) ? 0.0 : 1.0)); + glUniform1f(mInvertedLoc, static_cast((maskOp == pxContextMaskOperation::NORMAL) ? 0.0 : 1.0)); if (texture->bindGLTexture(mTextureLoc) != PX_OK) @@ -2129,9 +2129,9 @@ static void drawRectOutline(GLfloat x, GLfloat y, GLfloat w, GLfloat h, GLfloat static void drawImageTexture(float x, float y, float w, float h, pxTextureRef texture, pxTextureRef mask, bool useTextureDimsAlways, float* color, // default: "color = BLACK" - pxConstantsStretch::constants xStretch, - pxConstantsStretch::constants yStretch, - pxConstantsMaskOperation::constants maskOp = pxConstantsMaskOperation::constants::NORMAL) + pxContextStretch xStretch, + pxContextStretch yStretch, + pxContextMaskOperation maskOp = pxContextMaskOperation::NORMAL) { // args are tested at call site... @@ -2161,26 +2161,26 @@ static void drawImageTexture(float x, float y, float w, float h, pxTextureRef te float tw; switch(xStretch) { - case pxConstantsStretch::NONE: + case pxContextStretch::NONE: tw = w/iw; break; - case pxConstantsStretch::STRETCH: + case pxContextStretch::STRETCH: tw = 1.0; break; - case pxConstantsStretch::REPEAT: + case pxContextStretch::REPEAT: tw = w/iw; break; } float th; switch(yStretch) { - case pxConstantsStretch::NONE: + case pxContextStretch::NONE: th = h/ih; break; - case pxConstantsStretch::STRETCH: + case pxContextStretch::STRETCH: th = 1.0; break; - case pxConstantsStretch::REPEAT: + case pxContextStretch::REPEAT: #if 1 // PX_TEXTURE_ANCHOR_BOTTOM th = h/ih; #else @@ -2333,7 +2333,7 @@ static void drawImage92(GLfloat x, GLfloat y, GLfloat w, GLfloat h, GLfloat x1, { ou2,ov2 } }; - gTextureShader->draw(gResW,gResH,gMatrix.data(),gAlpha,22,verts,uv,texture,pxConstantsStretch::NONE,pxConstantsStretch::NONE); + gTextureShader->draw(gResW,gResH,gMatrix.data(),gAlpha,22,verts,uv,texture,pxContextStretch::NONE,pxContextStretch::NONE); } static void drawImage9Border2(GLfloat x, GLfloat y, GLfloat w, GLfloat h, @@ -2460,7 +2460,7 @@ static void drawImage9Border2(GLfloat x, GLfloat y, GLfloat w, GLfloat h, float colorPM[4]; premultiply(colorPM,color); - gTextureBorderShader->draw(gResW,gResH,gMatrix.data(),gAlpha,drawCenter? 28 : 24,verts,uv,texture,pxConstantsStretch::NONE,pxConstantsStretch::NONE, colorPM); + gTextureBorderShader->draw(gResW,gResH,gMatrix.data(),gAlpha,drawCenter? 28 : 24,verts,uv,texture,pxContextStretch::NONE,pxContextStretch::NONE, colorPM); } bool gContextInit = false; @@ -2981,13 +2981,13 @@ void pxContext::drawImage9Border(float w, float h, // convenience method void pxContext::drawImageMasked(float x, float y, float w, float h, - pxConstantsMaskOperation::constants maskOp, + pxContextMaskOperation maskOp, pxTextureRef t, pxTextureRef mask) { this->drawImage(x, y, w, h, t , mask, /* useTextureDimsAlways = */ true, /*color = */ NULL, // DEFAULT - /* stretchX = */ pxConstantsStretch::STRETCH, // DEFAULT - /* stretchY = */ pxConstantsStretch::STRETCH, // DEFAULT + /* stretchX = */ pxContextStretch::STRETCH, // DEFAULT + /* stretchY = */ pxContextStretch::STRETCH, // DEFAULT /* downscaleSmooth = */ false, // DEFAULT maskOp // PARAMETER ); @@ -2997,10 +2997,10 @@ void pxContext::drawImage(float x, float y, float w, float h, pxTextureRef t, pxTextureRef mask, bool useTextureDimsAlways /* = true */, float* color, /* = NULL */ - pxConstantsStretch::constants stretchX, /* = pxConstantsStretch::STRETCH, */ - pxConstantsStretch::constants stretchY, /* = pxConstantsStretch::STRETCH, */ + pxContextStretch stretchX, /* = pxContextStretch::STRETCH, */ + pxContextStretch stretchY, /* = pxContextStretch::STRETCH, */ bool downscaleSmooth /* = false */, - pxConstantsMaskOperation::constants maskOp /* = pxConstantsMaskOperation::NORMAL */ ) + pxContextMaskOperation maskOp /* = pxContextMaskOperation::NORMAL */ ) { #ifdef DEBUG_SKIP_IMAGE #warning "DEBUG_SKIP_IMAGE enabled ... Skipping " @@ -3027,14 +3027,14 @@ void pxContext::drawImage(float x, float y, float w, float h, mask->setLastRenderTick(gRenderTick); } - if (stretchX < pxConstantsStretch::NONE || stretchX > pxConstantsStretch::REPEAT) + if (stretchX < pxContextStretch::NONE || stretchX > pxContextStretch::REPEAT) { - stretchX = pxConstantsStretch::NONE; + stretchX = pxContextStretch::NONE; } - if (stretchY < pxConstantsStretch::NONE || stretchY > pxConstantsStretch::REPEAT) + if (stretchY < pxContextStretch::NONE || stretchY > pxContextStretch::REPEAT) { - stretchY = pxConstantsStretch::NONE; + stretchY = pxContextStretch::NONE; } float black[4] = {0,0,0,1}; diff --git a/examples/pxScene2d/src/pxEffects.h b/src/pxEffects.h similarity index 100% rename from examples/pxScene2d/src/pxEffects.h rename to src/pxEffects.h diff --git a/src/pxIView.h b/src/pxIView.h index 62a406f76a..fee24d4864 100644 --- a/src/pxIView.h +++ b/src/pxIView.h @@ -31,7 +31,7 @@ // upon being destroyed class pxIViewContainer { -public: +public: // In view coordinates on pixel boundaries // NULL means invalidate everything virtual void RT_STDCALL invalidateRect(pxRect* r) = 0; @@ -56,14 +56,14 @@ class pxIView virtual bool RT_STDCALL onMouseDown(int32_t x, int32_t y, uint32_t flags) = 0; virtual bool RT_STDCALL onMouseUp( int32_t x, int32_t y, uint32_t flags) = 0; virtual bool RT_STDCALL onMouseMove(int32_t x, int32_t y) = 0; - - virtual bool RT_STDCALL onScrollWheel(float dx, float dy) { UNUSED_PARAM(dx); UNUSED_PARAM(dy); return false; }; + + virtual bool RT_STDCALL onScrollWheel(float dx, float dy) = 0; // { UNUSED_PARAM(dx); UNUSED_PARAM(dy); return false; }; virtual bool RT_STDCALL onDragDrop( int32_t x, int32_t y, int32_t type, - const char *dropped) { UNUSED_PARAM(x); UNUSED_PARAM(y); UNUSED_PARAM(type); UNUSED_PARAM(dropped); return false; }; - virtual bool RT_STDCALL onDragMove( int32_t x, int32_t y, int32_t type) { UNUSED_PARAM(x); UNUSED_PARAM(y); UNUSED_PARAM(type); return false; }; - virtual bool RT_STDCALL onDragEnter(int32_t x, int32_t y, int32_t type) { UNUSED_PARAM(x); UNUSED_PARAM(y); UNUSED_PARAM(type); return false; }; - virtual bool RT_STDCALL onDragLeave(int32_t x, int32_t y, int32_t type) { UNUSED_PARAM(x); UNUSED_PARAM(y); UNUSED_PARAM(type); return false; }; + const char *dropped) = 0; //{ UNUSED_PARAM(x); UNUSED_PARAM(y); UNUSED_PARAM(type); UNUSED_PARAM(dropped); return false; }; + virtual bool RT_STDCALL onDragMove( int32_t x, int32_t y, int32_t type) = 0; //{ UNUSED_PARAM(x); UNUSED_PARAM(y); UNUSED_PARAM(type); return false; }; + virtual bool RT_STDCALL onDragEnter(int32_t x, int32_t y, int32_t type) = 0;// { UNUSED_PARAM(x); UNUSED_PARAM(y); UNUSED_PARAM(type); return false; }; + virtual bool RT_STDCALL onDragLeave(int32_t x, int32_t y, int32_t type) = 0; // { UNUSED_PARAM(x); UNUSED_PARAM(y); UNUSED_PARAM(type); return false; }; virtual bool RT_STDCALL onMouseEnter() = 0; virtual bool RT_STDCALL onMouseLeave() = 0; @@ -79,7 +79,9 @@ class pxIView virtual void RT_STDCALL onDraw(/*pxBuffer& b, pxRect* r*/) = 0; virtual void RT_STDCALL setViewContainer(pxIViewContainer* l) = 0; - virtual void RT_STDCALL onCloseRequest() {}; + + // JRJR TODO Get rid of this... + virtual void RT_STDCALL onCloseRequest() = 0; // {}; #if 0 virtual rtError RT_STDCALL setURI(const char* s) = 0; #endif diff --git a/examples/pxScene2d/src/pxShaderUtils.cpp b/src/pxShaderUtils.cpp similarity index 100% rename from examples/pxScene2d/src/pxShaderUtils.cpp rename to src/pxShaderUtils.cpp diff --git a/examples/pxScene2d/src/pxShaderUtils.h b/src/pxShaderUtils.h similarity index 100% rename from examples/pxScene2d/src/pxShaderUtils.h rename to src/pxShaderUtils.h diff --git a/src/pxSharedContext.h b/src/pxSharedContext.h new file mode 100644 index 0000000000..f8e012b486 --- /dev/null +++ b/src/pxSharedContext.h @@ -0,0 +1,51 @@ +/* + +pxCore Copyright 2005-2018 John Robinson + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +#ifndef PX_SHAREDCONTEXT_H +#define PX_SHAREDCONTEXT_H + +#include "rtAtomic.h" +#include "rtRef.h" + +#include "pxCore.h" + +class pxSharedContext: public pxSharedContextNative { +public: + pxSharedContext(bool depthBuffer): pxSharedContextNative(depthBuffer) {} + virtual ~pxSharedContext() {} + + virtual unsigned long AddRef() { + return rtAtomicInc(&mRef); + } + + virtual unsigned long Release() { + unsigned long l = rtAtomicDec(&mRef); + if (l == 0) + delete this; + return l; + } + + void makeCurrent(bool f); + +protected: + rtAtomic mRef; +}; + +typedef rtRef pxSharedContextRef; + +#endif //PX_CONTEXT_UTILS_H diff --git a/examples/pxScene2d/src/pxTexture.h b/src/pxTexture.h similarity index 100% rename from examples/pxScene2d/src/pxTexture.h rename to src/pxTexture.h diff --git a/src/pxViewWindow.cpp b/src/pxViewWindow.cpp index f49d833244..71eeddfb56 100644 --- a/src/pxViewWindow.cpp +++ b/src/pxViewWindow.cpp @@ -19,148 +19,120 @@ limitations under the License. // pxViewWindow.cpp #include "pxViewWindow.h" -#include "pxTimer.h" -//#include "rtLog.h" +#include "pxTimer.h" -pxError pxViewWindow::view(pxViewRef& v) -{ +pxError pxViewWindow::view(pxViewRef& v) { v = mView; return PX_OK; } -pxError pxViewWindow::setView(pxIView* v) -{ -#if 1 - if (mView) - { +pxError pxViewWindow::setView(pxIView* v) { + if (mView) { mView->setViewContainer(NULL); mView = NULL; } -#endif mView = v; - if (v) - { + if (v) { v->setViewContainer(this); - v->onSize(mWidth,mHeight); + v->onSize(mWidth, mHeight); } - + return PX_OK; } -void pxViewWindow::onClose() -{ - setView(NULL); -} +void pxViewWindow::onClose() { setView(NULL); } -void pxViewWindow::onSize(int32_t w, int32_t h) -{ - mWidth = w; - mHeight = h; - - if (mView) - mView->onSize(w, h); +void pxViewWindow::onSize(int32_t w, int32_t h) { + if (mWidth != w || mHeight != h) { + mWidth = w; + mHeight = h; + + if (mView) + mView->onSize(w, h); + } } -void pxViewWindow::onDragMove(int32_t x, int32_t y, int32_t type) -{ +void pxViewWindow::onDragMove(int32_t x, int32_t y, int32_t type) { if (mView) - mView->onDragMove(x, y, type); + mView->onDragMove(x, y, type); } -void pxViewWindow::onDragEnter(int32_t x, int32_t y, int32_t type) -{ +void pxViewWindow::onDragEnter(int32_t x, int32_t y, int32_t type) { if (mView) - mView->onDragEnter(x, y, type); + mView->onDragEnter(x, y, type); } -void pxViewWindow::onDragLeave(int32_t x, int32_t y, int32_t type) -{ +void pxViewWindow::onDragLeave(int32_t x, int32_t y, int32_t type) { if (mView) - mView->onDragLeave(x, y, type); + mView->onDragLeave(x, y, type); } -void pxViewWindow::onDragDrop(int32_t x, int32_t y, int32_t type, const char *dropped) -{ +void pxViewWindow::onDragDrop(int32_t x, int32_t y, int32_t type, + const char* dropped) { if (mView) mView->onDragDrop(x, y, type, dropped); } -void pxViewWindow::onScrollWheel(float dx, float dy) -{ +void pxViewWindow::onScrollWheel(float dx, float dy) { if (mView) mView->onScrollWheel(dx, dy); } -void pxViewWindow::onMouseDown(int32_t x, int32_t y, uint32_t flags) -{ +void pxViewWindow::onMouseDown(int32_t x, int32_t y, uint32_t flags) { if (mView) mView->onMouseDown(x, y, flags); } -void pxViewWindow::onMouseUp(int32_t x, int32_t y, uint32_t flags) -{ +void pxViewWindow::onMouseUp(int32_t x, int32_t y, uint32_t flags) { if (mView) mView->onMouseUp(x, y, flags); } -void pxViewWindow::onMouseLeave() -{ +void pxViewWindow::onMouseLeave() { if (mView) mView->onMouseLeave(); } -void pxViewWindow::onFocus() -{ +void pxViewWindow::onFocus() { if (mView) { mView->onFocus(); } } -void pxViewWindow::onBlur() -{ +void pxViewWindow::onBlur() { if (mView) { mView->onBlur(); } } -void pxViewWindow::onMouseMove(int32_t x, int32_t y) -{ +void pxViewWindow::onMouseMove(int32_t x, int32_t y) { if (mView) mView->onMouseMove(x, y); } -void pxViewWindow::onKeyDown(uint32_t keycode, uint32_t flags) -{ +void pxViewWindow::onKeyDown(uint32_t keycode, uint32_t flags) { if (mView) mView->onKeyDown(keycode, flags); } -void pxViewWindow::onKeyUp(uint32_t keycode, uint32_t flags) -{ +void pxViewWindow::onKeyUp(uint32_t keycode, uint32_t flags) { if (mView) mView->onKeyUp(keycode, flags); } -void pxViewWindow::onChar(uint32_t codepoint) -{ +void pxViewWindow::onChar(uint32_t codepoint) { if (mView) mView->onChar(codepoint); } - -void pxViewWindow::onAnimationTimer() -{ +void pxViewWindow::onAnimationTimer() { if (mView) - { mView->onUpdate(pxSeconds()); - } } -void pxViewWindow::onDraw(pxSurfaceNative /*s*/) -{ +void pxViewWindow::onDraw(pxSurfaceNative /*s*/) { if (mView) mView->onDraw(/*s*/); } - diff --git a/src/pxViewWindow.h b/src/pxViewWindow.h index c8fccb55c7..c33a05cead 100644 --- a/src/pxViewWindow.h +++ b/src/pxViewWindow.h @@ -21,12 +21,12 @@ #ifndef PX_VIEWWINDOW_H #define PX_VIEWWINDOW_H -#include "pxWindow.h" #include "pxIView.h" +#include "pxWindow.h" -class pxViewWindow: public pxWindow, public pxIViewContainer -{ -public: +class pxViewWindow : public pxWindow, public pxIViewContainer { + public: + pxViewWindow(): mWidth(-1), mHeight(-1) {} // pxViewRef is a smart ptr // that manages the refcount on a pxIView instance @@ -34,12 +34,10 @@ class pxViewWindow: public pxWindow, public pxIViewContainer // Specifying NULL will release the view pxError setView(pxIView* v); -protected: - + protected: virtual void onClose(); - virtual void RT_STDCALL invalidateRect(pxRect* r) - { + virtual void RT_STDCALL invalidateRect(pxRect* r) { pxWindow::invalidateRect(r); } @@ -53,10 +51,11 @@ class pxViewWindow: public pxWindow, public pxIViewContainer virtual void onMouseLeave(); virtual void onMouseMove(int32_t x, int32_t y); - virtual void onDragMove( int32_t x, int32_t y, int32_t type); + virtual void onDragMove(int32_t x, int32_t y, int32_t type); virtual void onDragEnter(int32_t x, int32_t y, int32_t type); virtual void onDragLeave(int32_t x, int32_t y, int32_t type); - virtual void onDragDrop( int32_t x, int32_t y, int32_t type, const char *dropped); + virtual void onDragDrop(int32_t x, int32_t y, int32_t type, + const char* dropped); virtual void onScrollWheel(float dx, float dy); @@ -69,11 +68,9 @@ class pxViewWindow: public pxWindow, public pxIViewContainer virtual void onDraw(pxSurfaceNative s); -private: + protected: pxViewRef mView; -// pxOffscreen mViewOffscreen; uint32_t mWidth, mHeight; }; -#endif // PX_VIEWWINDOW_H - +#endif // PX_VIEWWINDOW_H diff --git a/src/pxWindowUtil.cpp b/src/pxWindowUtil.cpp index 9f3be05d5d..2c8544375c 100644 --- a/src/pxWindowUtil.cpp +++ b/src/pxWindowUtil.cpp @@ -151,6 +151,7 @@ uint32_t keycodeFromNative(uint32_t nativeKeycode) commonKeycode = PX_KEY_NATIVE_CLEAR; //TODO break; +#if 0 // Don't support key codes for modifier keys case PX_KEY_NATIVE_SHIFT: commonKeycode = PX_KEY_SHIFT; break; @@ -160,6 +161,7 @@ uint32_t keycodeFromNative(uint32_t nativeKeycode) case PX_KEY_NATIVE_ALT: commonKeycode = PX_KEY_ALT; break; +#endif case PX_KEY_NATIVE_PAUSE: commonKeycode = PX_KEY_PAUSE; break; diff --git a/src/rtPathUtils.h b/src/rtPathUtils.h index 9fd71bd9fe..6eb991d687 100644 --- a/src/rtPathUtils.h +++ b/src/rtPathUtils.h @@ -21,13 +21,13 @@ #ifndef _RT_PATH_UTILS #define _RT_PATH_UTILS -#include -#include - #include "rtCore.h" #include "rtString.h" #include "rtValue.h" +#include +#include + rtError rtEnsureTrailingPathSeparator(rtString& d); rtError rtGetCurrentDirectory(rtString& d); rtError rtGetHomeDirectory(rtString& d); @@ -36,6 +36,21 @@ rtError rtGetEnv(const char* e, rtString& v); rtString rtGetEnvAsString(const char* name, const char* defaultValue = ""); rtValue rtGetEnvAsValue(const char* name, const char* defaultValue = ""); +template +T rtEnv(const char* name) { + char* v = getenv(name); // JRJR TODO secure_getenv?? + return rtValue(v).convert(); +} + +template +T rtEnv(const char* name, T defaultValue) { + char* v = getenv(name); // JRJR TODO secure_getenv?? and can I move these impls out of header + return v != NULL?rtValue(v).convert():defaultValue; +} + +template +T rtEnv(const char* name, T defaultValue); + bool rtFileExists(const char* f); bool rtFileRemove(const char* f); diff --git a/src/rtPhoneHome.cpp b/src/rtPhoneHome.cpp new file mode 100644 index 0000000000..3831d6b4b6 --- /dev/null +++ b/src/rtPhoneHome.cpp @@ -0,0 +1,101 @@ +/* + + pxCore Copyright 2005-2018 John Robinson + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +// rtPhoneHome.cpp + + +#include "rtPhoneHome.h" + +#include "rtLog.h" +#include "rtPathUtils.h" +#include "pxTimer.h" + +#include +#include +#include + +#ifdef HAS_LINUX_BREAKPAD +#include "client/linux/handler/exception_handler.h" +#elif HAS_WINDOWS_BREAKPAD +#include "client/linux/handler/exception_handler.h" +#if 1 +#include +#include +#include +#endif + +#endif + +#ifdef HAS_LINUX_BREAKPAD +static bool dumpCallback(const google_breakpad::MinidumpDescriptor &descriptor, + void *context, bool succeeded) { + UNUSED_PARAM(descriptor); + UNUSED_PARAM(context); + return succeeded; +} +#elif HAS_WINDOWS_BREAKPAD +bool dumpCallback(const wchar_t *dump_path, const wchar_t *minidump_id, + void *context, EXCEPTION_POINTERS *exinfo, + MDRawAssertionInfo *assertion, bool succeeded) { + return succeeded; +} +#endif + +static void handleSegv(int) { + signal(SIGSEGV, SIG_DFL); + FILE *fp = fopen("/tmp/pxscenecrash", "w"); + fclose(fp); + rtLogInfo("Signal SEGV received. sleeping to collect data"); + pxSleepMS(30000); // TODO review length and necessity +} + +static void handleAbrt(int) { + FILE *fp = fopen("/tmp/pxscenecrash", "w"); + fclose(fp); + rtLogInfo("Signal ABRT received. sleeping to collect data"); + pxSleepMS(30000); // TODO review length and necessity +} + +void rtPhoneHome::init() { + //signal(SIGTERM, handleTerm); + if (rtEnv("HANDLE_SIGNALS",false)) { + + #ifdef HAS_LINUX_BREAKPAD + google_breakpad::MinidumpDescriptor descriptor("/tmp"); + google_breakpad::ExceptionHandler eh(descriptor, NULL, dumpCallback, NULL, + true, -1); + #elif HAS_WINDOWS_BREAKPAD + // register exception handler for breakpad + google_breakpad::ExceptionHandler *handler = NULL; + handler = new google_breakpad::ExceptionHandler( + L"C:\\dumps\\", NULL, dumpCallback, NULL, + google_breakpad::ExceptionHandler::HANDLER_ALL, MiniDumpNormal, L"", + NULL); + #endif + + signal(SIGSEGV, handleSegv); + signal(SIGABRT, handleAbrt); + mInitialized = true; + } +} + +void rtPhoneHome::term() { + if (mInitialized) { + + } +} diff --git a/src/rtPhoneHome.h b/src/rtPhoneHome.h new file mode 100644 index 0000000000..5e14765d03 --- /dev/null +++ b/src/rtPhoneHome.h @@ -0,0 +1,32 @@ +/* + + pxCore Copyright 2005-2018 John Robinson + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +// rtPhoneHome.h + +// Crash Reporting +class rtPhoneHome { +public: + rtPhoneHome(): mInitialized(false) {} + ~rtPhoneHome() { term(); } + + void init(); + void term(); + +protected: + bool mInitialized; +}; diff --git a/src/rtScriptDuk/rtScriptDuk.cpp b/src/rtScriptDuk/rtScriptDuk.cpp index 5341f9130b..561417fec6 100644 --- a/src/rtScriptDuk/rtScriptDuk.cpp +++ b/src/rtScriptDuk/rtScriptDuk.cpp @@ -344,14 +344,14 @@ rtDukContext::rtDukContext(rtDukContextRef clone_me) : void rtDukContext::createEnvironment() { - rtLogInfo(__FUNCTION__); + rtLogInfo("%s",__FUNCTION__); } #ifdef USE_CONTEXTIFY_CLONES void rtDukContext::clonedEnvironment(rtDukContextRef clone_me) { - rtLogInfo(__FUNCTION__); + rtLogInfo("%s",__FUNCTION__); duk_idx_t thr_idx = duk_push_thread(clone_me->dukCtx); duk_dup(clone_me->dukCtx, -1); @@ -379,7 +379,7 @@ void rtDukContext::clonedEnvironment(rtDukContextRef clone_me) rtDukContext::~rtDukContext() { - rtLogInfo(__FUNCTION__); + rtLogInfo("%s",__FUNCTION__); //Make sure node is not destroyed abnormally Release(); // NOTE: 'mIsolate' is owned by rtNode. Don't destroy here ! @@ -983,7 +983,7 @@ static duk_int_t myload_code(duk_context *ctx, const char *code) rtError rtDukContext::runScript(const char* szscript, rtValue* retVal /*= NULL*/, const char *args /*= NULL*/) { std::string script = szscript; - rtLogInfo(__FUNCTION__); + rtLogInfo("%s",__FUNCTION__); if(script.empty()) { rtLogError(" %s ... no script given.",__PRETTY_FUNCTION__); @@ -1045,7 +1045,7 @@ rtScriptDuk::rtScriptDuk(bool initialize): dukCtx(NULL), duk_is_initialized(fals #endif mRefCount(0) { - rtLogInfo(__FUNCTION__); + rtLogInfo("%s",__FUNCTION__); if (true == initialize) { init(); @@ -1054,7 +1054,7 @@ rtScriptDuk::rtScriptDuk(bool initialize): dukCtx(NULL), duk_is_initialized(fals rtError rtScriptDuk::init() { - rtLogInfo(__FUNCTION__); + rtLogInfo("%s",__FUNCTION__); char const* s = getenv("RT_TEST_GC"); if (s && strlen(s) > 0) mTestGc = true; @@ -1215,7 +1215,7 @@ void rtScriptDuk::init2(int argc, char** argv) argv = uv_setup_args(argc, argv); #endif - rtLogInfo(__FUNCTION__); + rtLogInfo("%s",__FUNCTION__); #if 0 #warning Using DEBUG AGENT... @@ -1252,7 +1252,7 @@ void rtScriptDuk::init2(int argc, char** argv) rtError rtScriptDuk::term() { - rtLogInfo(__FUNCTION__); + rtLogInfo("%s",__FUNCTION__); //nodeTerminated = true; //uv_loop_close(dukLoop); diff --git a/src/rtScriptV8/rtScriptNode.cpp b/src/rtScriptV8/rtScriptNode.cpp index 4700a4c8f8..61511ad778 100644 --- a/src/rtScriptV8/rtScriptNode.cpp +++ b/src/rtScriptV8/rtScriptNode.cpp @@ -376,7 +376,7 @@ rtNodeContext::rtNodeContext(Isolate *isolate, rtNodeContextRef clone_me) : void rtNodeContext::createEnvironment() { - rtLogDebug(__FUNCTION__); + rtLogDebug("%s",__FUNCTION__); Locker locker(mIsolate); Isolate::Scope isolate_scope(mIsolate); HandleScope handle_scope(mIsolate); @@ -460,7 +460,8 @@ void rtNodeContext::createEnvironment() #ifdef WIN32 node::InspectorStart(mEnv, currentPath.cString(), platform); #else - node::InspectorStart(mEnv, currentPath.cString(), "", 0); + //node::InspectorStart(mEnv, currentPath.cString(), "", 0); + node::InspectorStart(mEnv, currentPath.cString(), platform); #endif #endif //USE_NODE_PLATFORM #endif @@ -559,7 +560,7 @@ void rtNodeContext::createEnvironment() void rtNodeContext::clonedEnvironment(rtNodeContextRef clone_me) { - rtLogDebug(__FUNCTION__); + rtLogDebug("%s",__FUNCTION__); Locker locker(mIsolate); Isolate::Scope isolate_scope(mIsolate); HandleScope handle_scope(mIsolate); @@ -661,7 +662,7 @@ void rtNodeContext::clonedEnvironment(rtNodeContextRef clone_me) rtNodeContext::~rtNodeContext() { - rtLogDebug(__FUNCTION__); + rtLogDebug("%s",__FUNCTION__); //Make sure node is not destroyed abnormally if (true == node_is_initialized) { @@ -892,7 +893,7 @@ rtError rtNodeContext::runScript(const char* script, rtValue* retVal /*= NULL*/, //rtError rtNodeContext::runScript(const std::string &script, rtValue* retVal /*= NULL*/, const char* /* args = NULL*/) rtError rtNodeContext::runScript(const char* script, rtValue* retVal /*= NULL*/, const char *args /*= NULL*/) { - rtLogDebug(__FUNCTION__); + rtLogDebug("%s",__FUNCTION__); if(!script || strlen(script) == 0) { rtLogError(" %s ... no script given.",__PRETTY_FUNCTION__); @@ -1000,7 +1001,7 @@ rtError rtNodeContext::runFile(const char *file, rtValue* retVal /*= NULL*/, con // Read the script file js_file = file; js_script = readFile(file); - + if( js_script.empty() ) // load error { rtLogError(" %s ... [%s] load error / not found.",__PRETTY_FUNCTION__, file); @@ -1022,7 +1023,7 @@ rtScriptNode::rtScriptNode():mRefCount(0) #endif #endif { - rtLogDebug(__FUNCTION__); + rtLogDebug("%s",__FUNCTION__); mTestGc = false; mIsolate = NULL; mPlatform = NULL; @@ -1038,7 +1039,7 @@ rtScriptNode::rtScriptNode(bool initialize):mRefCount(0) #endif #endif { - rtLogDebug(__FUNCTION__); + rtLogDebug("%s",__FUNCTION__); mTestGc = false; mIsolate = NULL; mPlatform = NULL; @@ -1060,7 +1061,27 @@ unsigned long rtScriptNode::Release() rtError rtScriptNode::init() { - rtLogDebug(__FUNCTION__); + if (g_argc == 0) { + + g_argv = NULL; + + char* args = (char*)"spark --experimental-vm-modules"; + + char* argsBuffer = strdup(args); // JRJR leak leak + char* start = argsBuffer; + + int l = strlen(argsBuffer); + for (char* p = argsBuffer; p < argsBuffer+l+1; p++) { + if (*p == ' ' || *p == '\0') { + g_argv = (char**)realloc(g_argv, sizeof(char*) * (g_argc+1)); + g_argv[g_argc++] = start; + *p = '\0'; + start = p+1; + } + } + } + + rtLogDebug("%s",__FUNCTION__); char const* s = getenv("RT_TEST_GC"); if (s && strlen(s) > 0) mTestGc = true; @@ -1093,6 +1114,7 @@ rtError rtScriptNode::init() static const char *argv2[] = {&args2[0], &args2[7], &args2[33], &args2[45], &args2[48], NULL}; #endif // ENABLE_NODE_V_6_9 #endif //ENABLE_V8_HEAP_PARAMS + #ifndef ENABLE_DEBUG_MODE int argc = sizeof(argv2)/sizeof(char*) - 1; @@ -1100,7 +1122,6 @@ rtError rtScriptNode::init() s_gArgs = &aa; - char **argv = aa.argv; #endif @@ -1147,10 +1168,10 @@ rtError rtScriptNode::pump() //#else #ifdef RUNINMAIN // found a problem where if promise triggered by one event loop gets resolved by other event loop. - // It is causing the dependencies between data running between two event loops failed, if one one + // It is causing the dependencies between data running between two event loops failed, if one one // loop didn't complete before other. So, promise not registered by first event loop, before the second // event looop sends back the ready event - if (gIsPumpingJavaScript == false) + if (gIsPumpingJavaScript == false) { gIsPumpingJavaScript = true; #endif @@ -1264,7 +1285,7 @@ void rtScriptNode::init2(int argc, char** argv) argv = uv_setup_args(argc, argv); #endif - rtLogInfo(__FUNCTION__); + rtLogInfo("%s",__FUNCTION__); #if 0 #warning Using DEBUG AGENT... @@ -1327,7 +1348,7 @@ void rtScriptNode::init2(int argc, char** argv) rtError rtScriptNode::term() { - rtLogInfo(__FUNCTION__); + rtLogInfo("%s",__FUNCTION__); nodeTerminated = true; #if 0 #ifdef USE_CONTEXTIFY_CLONES diff --git a/src/rtSettings.cpp b/src/rtSettings.cpp index 3b756257b2..3f8e96ee43 100644 --- a/src/rtSettings.cpp +++ b/src/rtSettings.cpp @@ -38,7 +38,7 @@ rtSettingsRef rtSettings::instance() return instance; } -rtError rtSettings::value(const rtString& key, rtValue& value) const +rtError rtSettings::value(const char* key, rtValue& value) const { std::map::const_iterator it = mValues.find(key); if (it != mValues.end()) @@ -49,7 +49,7 @@ rtError rtSettings::value(const rtString& key, rtValue& value) const return RT_ERROR; } -rtError rtSettings::setValue(const rtString& key, const rtValue& value) +rtError rtSettings::setValue(const char* key, const rtValue& value) { mValues[key] = value; return RT_OK; @@ -63,7 +63,7 @@ rtError rtSettings::keys(std::vector& keys) const return RT_OK; } -rtError rtSettings::remove(const rtString& key) +rtError rtSettings::remove(const char* key) { std::map::iterator it = mValues.find(key); if (it != mValues.end()) @@ -80,7 +80,7 @@ rtError rtSettings::clear() return RT_OK; } -rtError rtSettings::loadFromFile(const rtString& filePath) +rtError rtSettings::loadFromFile(const char* filePath) { rtString settingsPath = filePath; @@ -158,7 +158,7 @@ rtError rtSettings::loadFromArgs(int argc, char* argv[]) return RT_OK; } -rtError rtSettings::save(const rtString& filePath) const +rtError rtSettings::save(const char* filePath) const { rtMapObject* o = new rtMapObject; for (std::map::const_iterator it = mValues.begin(); it != mValues.end(); ++it) @@ -168,7 +168,7 @@ rtError rtSettings::save(const rtString& filePath) const rtValue v = o; - return rtValue2jsonFile(v, filePath.cString()); + return rtValue2jsonFile(v, filePath); } rtDefineObject(rtSettings, rtObject); diff --git a/src/rtSettings.h b/src/rtSettings.h index f4a7f01a68..a401d3f353 100644 --- a/src/rtSettings.h +++ b/src/rtSettings.h @@ -34,21 +34,37 @@ class rtSettings : public rtObject rtDeclareObject(rtSettings, rtObject); - static rtSettingsRef instance(); + template + static T get(const char* name) { + rtValue v; + instance()->value(name, v); + return v.convert(); + } + + template + static T get(const char* name, T defaultValue) { + rtValue v; + rtError e = instance()->value(name, v); + return e==RT_OK?v.convert():defaultValue; + } // if key is found then value is set and RT_OK is returned. otherwise RT_ERROR is returned - rtError value(const rtString& key, rtValue& value) const; + //rtError value(const rtString& key, rtValue& value) const; + rtError value(const char* key, rtValue& value) const; - rtError setValue(const rtString& key, const rtValue& value); + //rtError setValue(const rtString& key, const rtValue& value); + rtError setValue(const char* key, const rtValue& value); rtError keys(std::vector& keys) const; // removes the key (if present) and its corresponding value. returns RT_OK on success and RT_ERROR if key is not found rtError remove(const rtString& key); + rtError remove(const char* key); rtError clear(); // loads the settings from a file and returns RT_OK on success or RT_ERROR on failure - rtError loadFromFile(const rtString& filePath = rtString()); + //rtError loadFromFile(const rtString& filePath = rtString()); + rtError loadFromFile(const char* filePath = NULL); // there are two ways settings can specified via the command line // Method 1: -settingName @@ -57,9 +73,13 @@ class rtSettings : public rtObject // saves the settings (in json format) to disk with the specified file name // returns RT_OK on success or RT_ERROR on failure - rtError save(const rtString& filePath) const; + //rtError save(const rtString& filePath) const; + rtError save(const char* filePath) const; + +public: + + static rtSettingsRef instance(); -private: rtSettings(); static const char* FILE_NAME; diff --git a/src/rtSoftwareUpdate.cpp b/src/rtSoftwareUpdate.cpp new file mode 100644 index 0000000000..fa5fb983e3 --- /dev/null +++ b/src/rtSoftwareUpdate.cpp @@ -0,0 +1,48 @@ +/* + + pxCore Copyright 2005-2021 John Robinson + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +// rtSoftwareUpdate.cpp + +#include "rtSoftwareUpdate.h" + +#ifdef WIN32 +#include +// todo: is this resource file needed? if so, uncomment +//#include "../../../pxCore.vsbuild/pxScene2d/resource.h" +#endif + +void rtSoftwareUpdate::init() { +#if 0 +#ifdef WIN32 + + // Initialize WinSparkle as soon as the app itself is initialized, right + // before entering the event loop: + win_sparkle_set_appcast_url( + "https://github.com/pxscene/pxscene/tree/gh-pages/dist/windows/" + "appcast.xml"); + win_sparkle_init(); + +#endif +#endif +} + +void rtSoftwareUpdate::term() { +#ifdef WIN32 + win_sparkle_cleanup(); +#endif +} diff --git a/src/rtSoftwareUpdate.h b/src/rtSoftwareUpdate.h new file mode 100644 index 0000000000..864d97abe3 --- /dev/null +++ b/src/rtSoftwareUpdate.h @@ -0,0 +1,30 @@ +/* + + pxCore Copyright 2005-2021 John Robinson + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +// rtSoftwareUpdate.h + +class rtSoftwareUpdate { +public: + rtSoftwareUpdate(): mInitialized(false) {} + ~rtSoftwareUpdate() {} + + void init(); + void term(); +protected: + bool mInitialized; +}; diff --git a/src/win/pxConfigNative.h b/src/win/pxConfigNative.h index 3b2af52a81..7abd3a8218 100755 --- a/src/win/pxConfigNative.h +++ b/src/win/pxConfigNative.h @@ -1,32 +1,34 @@ -/* - -pxCore Copyright 2005-2018 John Robinson - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*/ - -// pxConfigNative.h - -#ifndef PX_CONFIGNATIVE_H -#define PX_CONFIGNATIVE_H - -#define PXCALL __stdcall -#define PX_LITTLEENDIAN_PIXELS -#define PX_LITTLEENDIAN_RGBA_PIXELS - -#include "win/pxBufferNative.h" -#include "win/pxOffscreenNative.h" -#include "win/pxWindowNative.h" -#endif - +/* + +pxCore Copyright 2005-2018 John Robinson + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +// pxConfigNative.h + +#ifndef PX_CONFIGNATIVE_H +#define PX_CONFIGNATIVE_H + +#define PXCALL __stdcall +#define PX_LITTLEENDIAN_PIXELS +#define PX_LITTLEENDIAN_RGBA_PIXELS + +#include "win/pxBufferNative.h" +#include "win/pxOffscreenNative.h" +#include "win/pxWindowNative.h" + +#include "win/pxSharedContextNative.h" +#endif + diff --git a/src/win/pxSharedContextNative.cpp b/src/win/pxSharedContextNative.cpp new file mode 100644 index 0000000000..3cfe5d1806 --- /dev/null +++ b/src/win/pxSharedContextNative.cpp @@ -0,0 +1,47 @@ +/* + +pxCore Copyright 2005-2021 John Robinson + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +// pxSharedContextNative.cpp + +#include "rtLog.h" +#include "rtMutex.h" +#include "pxSharedContext.h" + +#include "windows.h" + +#include "pxSharedContextNative.h" + +void pxSharedContext::makeCurrent(bool f) { + pxSharedContextNative::makeCurrent(f); +} + +pxSharedContextNative::pxSharedContextNative() { + mHDC = wglGetCurrentDC(); + mOriginalGLContext = wglGetCurrentContext(); + mGLContext = wglCreateContext(mHDC); + wglShareLists(mOriginalGLContext, mGLContext); +} + +pxSharedContextNative::~pxSharedContextNative() { + if (mGLContext) + wglDeleteContext(mGLContext); +} + +void pxSharedContextNative::makeCurrent(bool f) { + wglMakeCurrent(mHDC, f?mGLContext:mOriginalGLContext); +} diff --git a/src/win/pxSharedContextNative.h b/src/win/pxSharedContextNative.h new file mode 100644 index 0000000000..385dcd83e2 --- /dev/null +++ b/src/win/pxSharedContextNative.h @@ -0,0 +1,39 @@ +/* + +pxCore Copyright 2005-2021 John Robinson + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +// pxSharedContextNative.h +#ifndef PX_SHAREDCONTEXTNATIVE_H +#define PX_SHAREDCONTEXTNATIVE_H + +#include "windows.h" + +class pxSharedContextNative { +public: + + pxSharedContextNative(); + virtual ~pxSharedContextNative(); + + void makeCurrent(bool f); + +protected: + HDC mHDC; + HGLRC mGLContext; + HGLRC mOriginalGLContext; +}; + +#endif diff --git a/src/win/pxWindowNative.cpp b/src/win/pxWindowNative.cpp index d85b7bbce0..c1dc94066c 100755 --- a/src/win/pxWindowNative.cpp +++ b/src/win/pxWindowNative.cpp @@ -1,504 +1,539 @@ -/* - -pxCore Copyright 2005-2018 John Robinson - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*/ - -// pxWindowNative.cpp - -#define PX_NATIVE -#include "pxOffscreenNative.h" -#include "pxWindowNative.h" -#include "../pxWindow.h" -#include "../pxWindowUtil.h" - -#include "../pxKeycodes.h" - -#ifndef WINCE -#include -#define _ATL_NO_HOSTING -//#include -#endif - -#include "windowsx.h" - -#pragma warning ( disable:4311) -#pragma warning ( disable:4312) - -#define WM_DEFERREDCREATE WM_USER+1000 -// With the addition of getting native events -// maybe this should be deprecated? -#define WM_SYNCHRONIZEDMESSAGE WM_USER+1001 - -#ifdef WINCE -#define MOBILE -#include "aygshell.h" -#endif - -using namespace std; - -void setWindowPtr(HWND w, void* p) -{ -#ifndef WINCE - SetWindowLongPtr(w, GWLP_USERDATA, (LONG)p); -#else - SetWindowLong(w, GWL_USERDATA, (LONG)p); -#endif -} - -void* getWindowPtr(HWND w) -{ -#ifndef WINCE - return (void*)GetWindowLongPtr(w, GWLP_USERDATA); -#else - return (void*)GetWindowLong(w, GWL_USERDATA); -#endif -} - - -// pxWindow - -pxError pxWindow::init(int left, int top, int width, int height) -{ -#ifndef MOBILE - return initNative(NULL, left, top, width, height, WS_OVERLAPPEDWINDOW, 0); -#else - return initNative(NULL, left, top, width, height, WS_VISIBLE, 0); -#endif -} - -#include - -pxError pxWindowNative::initNative(HWND parent, int left, int top, int width, int height, DWORD style, DWORD styleEx) -{ - HINSTANCE hInstance = ::GetModuleHandle(NULL); - - std::string className = "pxWindow"; - WNDCLASS wc; - if (!::GetClassInfo(hInstance, className.c_str(), &wc)) - { - - wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - wc.lpfnWndProc = (WNDPROC)windowProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = NULL; - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); - wc.lpszMenuName = 0; - wc.lpszClassName = className.c_str(); - - RegisterClass(&wc); - } - -#ifndef MOBILE - mWindow = ::CreateWindowEx(styleEx, "pxWindow", "", style, left, top, width, height, parent, NULL, - hInstance, (pxWindowNative*)this); -#else - mWindow = CreateWindow(className.c_str(), L"", style, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, (pxWindowNative*)this); - - if (mWindow) - { - SHDoneButton (mWindow, SHDB_SHOW); - SHFullScreen(mWindow, SHFS_HIDESIPBUTTON); - } -#endif - return mWindow?PX_OK:PX_FAIL; -} - - -void pxWindowNative::size(int& width, int& height) -{ - RECT r; - GetClientRect(mWindow, &r); - width = r.right-r.left; - height = r.bottom-r.top; -} - -pxError pxWindow::term() -{ -// ::DestroyWindow(mWindow); - return PX_OK; -} - -#if 1 -void pxWindow::invalidateRect(pxRect* r) -{ - RECT wr; - RECT* pwr = NULL; - if (r) - { - pwr = ≀ - SetRect(pwr, r->left(), r->top(), r->right(), r->bottom()); - } - InvalidateRect(mWindow, pwr, FALSE); -} -#endif - -bool pxWindow::visibility() -{ - return IsWindowVisible(mWindow)?true:false; -} - -void pxWindow::setVisibility(bool visible) -{ - ShowWindow(mWindow, visible?SW_SHOW:SW_HIDE); -} - -pxError pxWindow::setAnimationFPS(uint32_t fps) -{ -#if 0 - if (mTimerId) - { - KillTimer(mWindow, mTimerId); - mTimerId = NULL; - } - - if (fps > 0) - { - mTimerId = SetTimer(mWindow, 1, 1000/fps, NULL); - } - return PX_OK; -#else - pxWindowNative::setAnimationFPS(fps); - return PX_OK; -#endif -} - -pxError pxWindowNative::setAnimationFPS(long fps) -{ - if (mTimerId) - { - KillTimer(mWindow, mTimerId); - mTimerId = NULL; - } - - if (fps > 0) - { - mTimerId = SetTimer(mWindow, 1, 1000/fps, NULL); - } - return PX_OK; -} - -void pxWindow::setTitle(const char* title) -{ -#if 0 - USES_CONVERSION; - ::SetWindowText(mWindow, A2T(title)); -#else -#ifndef WINCE - ::SetWindowTextA(mWindow, title); -#endif -#endif -} - -pxError pxWindow::beginNativeDrawing(pxSurfaceNative& s) -{ - s = ::GetDC(mWindow); - return s?PX_OK:PX_FAIL; -} - -pxError pxWindow::endNativeDrawing(pxSurfaceNative& s) -{ - ::ReleaseDC(mWindow, s); - return PX_OK; -} - -// pxWindowNative - -pxWindowNative::~pxWindowNative() -{ - setWindowPtr(mWindow, NULL); -} - -void pxWindowNative::sendSynchronizedMessage(char* messageName, void *p1) -{ - synchronizedMessage m; - m.messageName = messageName; - m.p1 = p1; - ::SendMessage(mWindow, WM_SYNCHRONIZEDMESSAGE, 0, (LPARAM)&m); -} - -LRESULT __stdcall pxWindowNative::windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - int mouseButtonShift = 0; - - pxWindowNative* w; - - static HDC hDC; - static HGLRC hRC; - -#ifndef WINCE - if (msg == WM_NCCREATE) -#else - if (msg == WM_CREATE) -#endif - { - CREATESTRUCT *cs = (CREATESTRUCT*)lParam; - // ::SetProp(hWnd, _T("wnWindow"), (HANDLE)cs->lpCreateParams); - setWindowPtr(hWnd, cs->lpCreateParams); - w = (pxWindowNative*)cs->lpCreateParams; - w->mWindow = hWnd; - } - else - w = (pxWindowNative*)getWindowPtr(hWnd); - - - bool consumed = false; - - if (w) - { - pxEventNativeDesc e; - - e.wnd = hWnd; - e.msg = msg; - e.wParam = wParam; - e.lParam = lParam; - - w->onEvent(e, consumed); - - if (consumed) - { - // ick - if (e.msg == WM_SETCURSOR) - return 1; - else - return 0; - } - - // re resolve the window ptr since we have destroyed it - - w = (pxWindowNative*)getWindowPtr(hWnd); - if (w) - { - switch(msg) - { -// Special case code to handle the "fake" close button in the form -// of an OK button on win mobile -#ifdef MOBILE - case WM_COMMAND: - { - unsigned int wmId = LOWORD(wParam); - unsigned int wmEvent = HIWORD(wParam); - // Parse the menu selections: - switch (wmId) - { - case IDOK: - SendMessage (w->mWindow, WM_CLOSE, 0, 0); - break; - default: - return DefWindowProc(w->mWindow, msg, wParam, lParam); - } - } - break; -#endif -#if 1 - case WM_CREATE: - // We have to retry setting the animation timer if it happened to early - // after creation - w->onCreate(); - PostMessage(hWnd, WM_DEFERREDCREATE, 0, 0); - break; - case WM_DEFERREDCREATE: - //w->onCreate(); - if (w->mAnimationFPS) - w->setAnimationFPS(w->mAnimationFPS); - break; - - case WM_CLOSE: - w->onCloseRequest(); - return 0; - break; - - case WM_DESTROY: - w->onClose(); - //SetProp(hWnd, _T("wnWindow"), NULL); - - wglMakeCurrent(hDC, nullptr); - wglDeleteContext(hRC); -#ifdef WINCE - setWindowPtr(hWnd, NULL); -#endif - break; - -#ifndef WINCE - case WM_NCDESTROY: - setWindowPtr(hWnd, NULL); - break; -#endif - - case WM_RBUTTONDOWN: mouseButtonShift++; - case WM_MBUTTONDOWN: mouseButtonShift++; - case WM_LBUTTONDOWN: - { -#if 1 - SetCapture(w->mWindow); - unsigned long flags = 1 << mouseButtonShift; - if (wParam & MK_CONTROL) flags |= PX_MOD_CONTROL; - if (wParam & MK_SHIFT) flags |= PX_MOD_SHIFT; - if (GetKeyState(VK_MENU) < 0) flags |= PX_MOD_ALT; - - w->onMouseDown(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), flags); - -#endif - } - break; - case WM_RBUTTONUP: mouseButtonShift++; - case WM_MBUTTONUP: mouseButtonShift++; - case WM_LBUTTONUP: - { -#if 1 - ReleaseCapture(); - unsigned long flags = 1 << mouseButtonShift; - if (wParam & MK_CONTROL) flags |= PX_MOD_CONTROL; - if (wParam & MK_SHIFT) flags |= PX_MOD_SHIFT; - if (GetKeyState(VK_MENU) < 0) flags |= PX_MOD_ALT; - - w->onMouseUp(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), flags); -#endif - } - break; - - case WM_MOUSEWHEEL: - { - GET_WHEEL_DELTA_WPARAM(wParam); - int direction = (int(wParam) > 0) ? 1 : -1; - - w->onScrollWheel((float)(GET_X_LPARAM(lParam) * direction), (float)(GET_Y_LPARAM(lParam) * direction)); - } - break; - - case WM_MOUSEMOVE: -#if 1 -#ifndef WINCE - if (!w->mTrackMouse) - { - TRACKMOUSEEVENT tme; - tme.cbSize = sizeof(TRACKMOUSEEVENT); - tme.dwFlags = TME_LEAVE; - tme.hwndTrack = hWnd; - - if (TrackMouseEvent(&tme)) - { - w->mTrackMouse = true; - } - } -#endif - w->onMouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); -#endif - break; - -#ifndef WINCE - case WM_MOUSELEAVE: - w->mTrackMouse = false; - w->onMouseLeave(); - break; -#endif - - case WM_TIMER: - // Should filter this to a single id - w->onAnimationTimer(); - break; - - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - { - unsigned long flags = 0; - - if (GetKeyState(VK_SHIFT) & 0x8000) - { - flags |= PX_MOD_SHIFT; - } - if (GetKeyState(VK_CONTROL) & 0x8000) - { - flags |= PX_MOD_CONTROL; - } - if (GetKeyState(VK_MENU) & 0x8000) - { - flags |= PX_MOD_ALT; - } - - w->onKeyDown(keycodeFromNative((int)wParam), flags); - //w->onChar((char)wParam); - } - break; - case WM_CHAR: - w->onChar((char)wParam); - break; - - case WM_KEYUP: - case WM_SYSKEYUP: - { - unsigned long flags = 0; - - if (GetKeyState(VK_SHIFT) & 0x8000) - { - flags |= PX_MOD_SHIFT; - } - if (GetKeyState(VK_CONTROL) & 0x8000) - { - flags |= PX_MOD_CONTROL; - } - if (GetKeyState(VK_MENU) & 0x8000) - { - flags |= PX_MOD_ALT; - } - - w->onKeyUp(keycodeFromNative((int)wParam), flags); - } - break; - case WM_PAINT: -#if 1 - { - PAINTSTRUCT ps; - HDC dc = BeginPaint(w->mWindow, &ps); - w->onDraw(dc); - SwapBuffers(dc); - EndPaint(w->mWindow, &ps); - return 0; - } -#endif - break; - case WM_SIZE: - { - w->onSize(LOWORD(lParam), HIWORD(lParam)); - } - break; - case WM_ERASEBKGND: - { -#if 0 - PAINTSTRUCT ps; - HDC dc = BeginPaint(w->mWindow, &ps); - w->onDraw(dc); - EndPaint(w->mWindow, &ps); -#endif - } - return 0; - break; - case WM_SYNCHRONIZEDMESSAGE: - { - synchronizedMessage *m = (synchronizedMessage*)lParam; - w->onSynchronizedMessage(m->messageName, m->p1); - } - break; -#endif - } - } - } - - return DefWindowProc(hWnd, msg, wParam, lParam); -} +/* + +pxCore Copyright 2005-2021 John Robinson + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +// pxWindowNative.cpp + +#define PX_NATIVE + +#include "rtLog.h" +#include "pxOffscreenNative.h" +#include "pxWindowNative.h" + +#include "../pxKeycodes.h" +#include "../pxWindow.h" +#include "../pxWindowUtil.h" + + +#ifndef WINCE +#include +#define _ATL_NO_HOSTING +//#include +#endif + +#include "windowsx.h" + +#if 1 +#ifdef __APPLE__ +#include +#include +#include +#else +#if defined(PX_PLATFORM_WAYLAND_EGL) || defined(PX_PLATFORM_GENERIC_EGL) +#include +#ifndef GL_GLEXT_PROTOTYPES +#define GL_GLEXT_PROTOTYPES +#endif +#include +#else +#include +#ifdef WIN32 +#include +#endif // WIN32 +#ifdef PX_PLATFORM_GLUT +#include +#endif +#include +#endif //PX_PLATFORM_WAYLAND_EGL +#endif +#endif + +#pragma warning(disable : 4311) +#pragma warning(disable : 4312) + +#define WM_DEFERREDCREATE WM_USER + 1000 +// With the addition of getting native events +// maybe this should be deprecated? +#define WM_SYNCHRONIZEDMESSAGE WM_USER + 1001 + +#ifdef WINCE +#define MOBILE +#include "aygshell.h" +#endif + +using namespace std; + +void setWindowPtr(HWND w, void* p) { +#ifndef WINCE + SetWindowLongPtr(w, GWLP_USERDATA, (LONG)p); +#else + SetWindowLong(w, GWL_USERDATA, (LONG)p); +#endif +} + +void* getWindowPtr(HWND w) { +#ifndef WINCE + return (void*)GetWindowLongPtr(w, GWLP_USERDATA); +#else + return (void*)GetWindowLong(w, GWL_USERDATA); +#endif +} + +// pxWindow + +pxError pxWindow::init(int left, int top, int width, int height) { +#ifndef MOBILE + return initNative(NULL, left, top, width, height, WS_OVERLAPPEDWINDOW, 0); +#else + return initNative(NULL, left, top, width, height, WS_VISIBLE, 0); +#endif +} + +#include + +pxError pxWindowNative::initNative(HWND parent, int left, int top, int width, + int height, DWORD style, DWORD styleEx) { + HINSTANCE hInstance = ::GetModuleHandle(NULL); + + std::string className = "pxWindow"; + WNDCLASS wc; + if (!::GetClassInfo(hInstance, className.c_str(), &wc)) { + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = (WNDPROC)windowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = NULL; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); + wc.lpszMenuName = 0; + wc.lpszClassName = className.c_str(); + + RegisterClass(&wc); + } + +#ifndef MOBILE + mWindow = + ::CreateWindowEx(styleEx, "pxWindow", "", style, left, top, width, height, + parent, NULL, hInstance, (pxWindowNative*)this); +#else + mWindow = CreateWindow(className.c_str(), L"", style, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, + NULL, hInstance, (pxWindowNative*)this); + + if (mWindow) { + SHDoneButton(mWindow, SHDB_SHOW); + SHFullScreen(mWindow, SHFS_HIDESIPBUTTON); + } +#endif + +#if 1 + HDC hdc = ::GetDC(mWindow); + HGLRC hrc; + + static PIXELFORMATDESCRIPTOR pfd = {sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | + PFD_DOUBLEBUFFER | PFD_SWAP_EXCHANGE, + PFD_TYPE_RGBA, + 24, + 0, + 0, + 0, + 0, + 0, + 0, + 8, + 0, + 0, + 0, + 0, + 0, + 0, + 24, + 8, + 0, + PFD_MAIN_PLANE, + 0, + 0, + 0, + 0}; + + int pixelFormat = ChoosePixelFormat(hdc, &pfd); + if (::SetPixelFormat(hdc, pixelFormat, &pfd)) { + hrc = wglCreateContext(hdc); + if (::wglMakeCurrent(hdc, hrc)) { + glewExperimental = GL_TRUE; + if (glewInit() != GLEW_OK) throw std::runtime_error("glewInit failed"); + + char *GL_version = (char *)glGetString(GL_VERSION); + char *GL_vendor = (char *)glGetString(GL_VENDOR); + char *GL_renderer = (char *)glGetString(GL_RENDERER); + + rtLogInfo("GL_version = %s", GL_version); + rtLogInfo("GL_vendor = %s", GL_vendor); + rtLogInfo("GL_renderer = %s", GL_renderer); + } + } +#endif + + return mWindow ? PX_OK : PX_FAIL; +} + +void pxWindowNative::size(int& width, int& height) { + RECT r; + GetClientRect(mWindow, &r); + width = r.right - r.left; + height = r.bottom - r.top; +} + +pxError pxWindow::term() { + // ::DestroyWindow(mWindow); + return PX_OK; +} + +#if 1 +void pxWindow::invalidateRect(pxRect* r) { + RECT wr; + RECT* pwr = NULL; + if (r) { + pwr = ≀ + SetRect(pwr, r->left(), r->top(), r->right(), r->bottom()); + } + InvalidateRect(getHWND(), pwr, FALSE); +} +#endif + +bool pxWindow::visibility() { + return IsWindowVisible(getHWND()) ? true : false; +} + +void pxWindow::setVisibility(bool visible) { + ShowWindow(getHWND(), visible ? SW_SHOW : SW_HIDE); +} + +pxError pxWindow::setAnimationFPS(uint32_t fps) { +#if 0 + if (mTimerId) + { + KillTimer(mWindow, mTimerId); + mTimerId = NULL; + } + + if (fps > 0) + { + mTimerId = SetTimer(mWindow, 1, 1000/fps, NULL); + } + return PX_OK; +#else + pxWindowNative::setAnimationFPS(fps); + return PX_OK; +#endif +} + +pxError pxWindowNative::setAnimationFPS(long fps) { + if (mTimerId) { + KillTimer(getHWND(), mTimerId); + mTimerId = NULL; + } + + if (fps > 0) { + mTimerId = SetTimer(getHWND(), 1, 1000 / fps, NULL); + } + return PX_OK; +} + +void pxWindow::setTitle(const char* title) { +#if 0 + USES_CONVERSION; + ::SetWindowText(mWindow, A2T(title)); +#else +#ifndef WINCE + ::SetWindowTextA(getHWND(), title); +#endif +#endif +} + +pxError pxWindow::beginNativeDrawing(pxSurfaceNative& s) { + s = ::GetDC(getHWND()); + return s ? PX_OK : PX_FAIL; +} + +pxError pxWindow::endNativeDrawing(pxSurfaceNative& s) { + ::ReleaseDC(getHWND(), s); + return PX_OK; +} + +// pxWindowNative + +pxWindowNative::~pxWindowNative() { setWindowPtr(mWindow, NULL); } + +void pxWindowNative::sendSynchronizedMessage(char* messageName, void* p1) { + synchronizedMessage m; + m.messageName = messageName; + m.p1 = p1; + ::SendMessage(mWindow, WM_SYNCHRONIZEDMESSAGE, 0, (LPARAM)&m); +} + +LRESULT __stdcall pxWindowNative::windowProc(HWND hWnd, UINT msg, WPARAM wParam, + LPARAM lParam) { + int mouseButtonShift = 0; + + pxWindowNative* w; + + static HDC hDC; + static HGLRC hRC; + +#ifndef WINCE + if (msg == WM_NCCREATE) +#else + if (msg == WM_CREATE) +#endif + { + CREATESTRUCT* cs = (CREATESTRUCT*)lParam; + // ::SetProp(hWnd, _T("wnWindow"), (HANDLE)cs->lpCreateParams); + setWindowPtr(hWnd, cs->lpCreateParams); + w = (pxWindowNative*)cs->lpCreateParams; + w->mWindow = hWnd; + } else + w = (pxWindowNative*)getWindowPtr(hWnd); + + bool consumed = false; + + if (w) { + pxEventNativeDesc e; + + e.wnd = hWnd; + e.msg = msg; + e.wParam = wParam; + e.lParam = lParam; + + w->onEvent(e, consumed); + + if (consumed) { + // ick + if (e.msg == WM_SETCURSOR) + return 1; + else + return 0; + } + + // re resolve the window ptr since we have destroyed it + + w = (pxWindowNative*)getWindowPtr(hWnd); + if (w) { + switch (msg) { +// Special case code to handle the "fake" close button in the form +// of an OK button on win mobile +#ifdef MOBILE + case WM_COMMAND: { + unsigned int wmId = LOWORD(wParam); + unsigned int wmEvent = HIWORD(wParam); + // Parse the menu selections: + switch (wmId) { + case IDOK: + SendMessage(w->mWindow, WM_CLOSE, 0, 0); + break; + default: + return DefWindowProc(w->mWindow, msg, wParam, lParam); + } + } break; +#endif +#if 1 + case WM_CREATE: + // We have to retry setting the animation timer if it happened to + // early after creation + w->onCreate(); + PostMessage(hWnd, WM_DEFERREDCREATE, 0, 0); + break; + case WM_DEFERREDCREATE: + // w->onCreate(); + if (w->mAnimationFPS) w->setAnimationFPS(w->mAnimationFPS); + break; + + case WM_CLOSE: + w->onCloseRequest(); + return 0; + break; + + case WM_DESTROY: + w->onClose(); + // SetProp(hWnd, _T("wnWindow"), NULL); + + wglMakeCurrent(hDC, nullptr); + wglDeleteContext(hRC); +#ifdef WINCE + setWindowPtr(hWnd, NULL); +#endif + break; + +#ifndef WINCE + case WM_NCDESTROY: + setWindowPtr(hWnd, NULL); + break; +#endif + + case WM_RBUTTONDOWN: + mouseButtonShift++; + case WM_MBUTTONDOWN: + mouseButtonShift++; + case WM_LBUTTONDOWN: { +#if 1 + SetCapture(w->mWindow); + unsigned long flags = 1 << mouseButtonShift; + if (GetKeyState(VK_CONTROL) < 0) flags |= PX_MOD_CONTROL; + if (GetKeyState(VK_SHIFT) < 0) flags |= PX_MOD_SHIFT; + if (GetKeyState(VK_MENU) < 0) flags |= PX_MOD_ALT; + + w->onMouseDown(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), flags); + +#endif + } break; + case WM_RBUTTONUP: + mouseButtonShift++; + case WM_MBUTTONUP: + mouseButtonShift++; + case WM_LBUTTONUP: { +#if 1 + ReleaseCapture(); + unsigned long flags = 1 << mouseButtonShift; + if (GetKeyState(VK_CONTROL) < 0) flags |= PX_MOD_CONTROL; + if (GetKeyState(VK_SHIFT) < 0) flags |= PX_MOD_SHIFT; + if (GetKeyState(VK_MENU) < 0) flags |= PX_MOD_ALT; + + w->onMouseUp(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), flags); +#endif + } break; + + case WM_MOUSEWHEEL: { + int zDelta = GET_WHEEL_DELTA_WPARAM(wParam); + int direction = (int(wParam) > 0) ? 1 : -1; + + // w->onScrollWheel((float)(GET_X_LPARAM(lParam) * direction), + // (float)(GET_Y_LPARAM(lParam) * direction)); + w->onScrollWheel((float)0, (float)zDelta > 0 ? 16 : -16); + printf("zDelta: %d direction: %d x: %d y: %d\n", zDelta, direction, + GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + } break; + + case WM_MOUSEMOVE: +#if 1 +#ifndef WINCE + if (!w->mTrackMouse) { + TRACKMOUSEEVENT tme; + tme.cbSize = sizeof(TRACKMOUSEEVENT); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = hWnd; + + if (TrackMouseEvent(&tme)) { + w->mTrackMouse = true; + } + } +#endif + w->onMouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); +#endif + break; + +#ifndef WINCE + case WM_MOUSELEAVE: + w->mTrackMouse = false; + w->onMouseLeave(); + break; +#endif + + case WM_TIMER: + // Should filter this to a single id + w->onAnimationTimer(); + break; + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: { + unsigned long flags = 0; + + if (GetKeyState(VK_SHIFT) & 0x8000) { + flags |= PX_MOD_SHIFT; + } + if (GetKeyState(VK_CONTROL) & 0x8000) { + flags |= PX_MOD_CONTROL; + } + if (GetKeyState(VK_MENU) & 0x8000) { + flags |= PX_MOD_ALT; + } + + uint32_t keyCode = keycodeFromNative((int)wParam); + + if (keyCode) w->onKeyDown(keyCode, flags); + // w->onChar((char)wParam); + } break; + case WM_CHAR: + w->onChar((char)wParam); + break; + + case WM_KEYUP: + case WM_SYSKEYUP: { + unsigned long flags = 0; + + if (GetKeyState(VK_SHIFT) & 0x8000) { + flags |= PX_MOD_SHIFT; + } + if (GetKeyState(VK_CONTROL) & 0x8000) { + flags |= PX_MOD_CONTROL; + } + if (GetKeyState(VK_MENU) & 0x8000) { + flags |= PX_MOD_ALT; + } + + uint32_t keycode = keycodeFromNative((int)wParam); + if (keycode) w->onKeyUp(keycode, flags); + } break; + case WM_PAINT: +#if 1 + { + PAINTSTRUCT ps; + HDC dc = BeginPaint(w->mWindow, &ps); + w->onDraw(dc); + SwapBuffers( + dc); // JRJR TODO should this be moved elsewhere into gl layer + EndPaint(w->mWindow, &ps); + return 0; + } +#endif + break; + case WM_SIZE: { + w->onSize(LOWORD(lParam), HIWORD(lParam)); + } break; + case WM_ERASEBKGND: { +#if 0 + PAINTSTRUCT ps; + HDC dc = BeginPaint(w->mWindow, &ps); + w->onDraw(dc); + EndPaint(w->mWindow, &ps); +#endif + } + return 0; + break; + case WM_SYNCHRONIZEDMESSAGE: { + synchronizedMessage* m = (synchronizedMessage*)lParam; + w->onSynchronizedMessage(m->messageName, m->p1); + } break; +#endif + } + } + } + + return DefWindowProc(hWnd, msg, wParam, lParam); +} diff --git a/src/win/pxWindowNative.h b/src/win/pxWindowNative.h index 0e4a1f5b02..a48e920571 100755 --- a/src/win/pxWindowNative.h +++ b/src/win/pxWindowNative.h @@ -1,212 +1,213 @@ -/* - -pxCore Copyright 2005-2018 John Robinson - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*/ - -// pxWindowNative.h - -#ifndef PX_WINDOW_NATIVE_H -#define PX_WINDOW_NATIVE_H - -#include -#include "../pxRect.h" -#include "pxOffscreenNative.h" - -struct pxEventNativeDesc -{ - HWND wnd; - UINT msg; - WPARAM wParam; - LPARAM lParam; -}; - -#ifndef WINCE -#define PX_DEF_WINDOW_STYLE WS_OVERLAPPEDWINDOW -#else -#define PX_DEF_WINDOW_STYLE WS_VISIBLE -#endif - -typedef pxEventNativeDesc& pxEventNative; - - -class pxWindowNative -{ -public: - pxWindowNative(): mWindow(NULL), mTimerId(NULL), mAnimationFPS(0), mTrackMouse(false) {} - virtual ~pxWindowNative(); - - pxError initNative(HWND parent, int left, int top, int width, int height, DWORD style = PX_DEF_WINDOW_STYLE, DWORD styleEx = 0); - - pxError setAnimationFPS(long fps); - - void sendSynchronizedMessage(char* messageName, void* p1); - - void size(int& width, int& height); - // void frameSize(...); - - -protected: - virtual void onCreate() = 0; - - virtual void onCloseRequest() = 0; - virtual void onClose() = 0; - - virtual void onSize(int w, int h) = 0; - - virtual void onMouseDown(int x, int y, uint32_t flags) = 0; - virtual void onMouseUp(int x, int y, uint32_t flags) = 0; - - virtual void onMouseMove(int x, int y) = 0; - virtual void onScrollWheel(float dx, float dy) = 0; - - virtual void onKeyDown(uint32_t keycode, uint32_t flags) = 0; - virtual void onKeyUp(uint32_t keycode, uint32_t flags) = 0; - virtual void onChar(uint32_t c) = 0; - - virtual void onDraw(pxSurfaceNative surface) = 0; - - virtual void onAnimationTimer() = 0; - - // Windows only for now - - virtual void onMouseLeave() {} - virtual void onSynchronizedMessage(char* messageName, void* p1) {} - - // Windows only for now - // This method will get invoked before calling any of the other event - // handlers. If consumed is set to true then no other event handlers will - // be called; otherwise they will be invoked as usual - virtual void onEvent(pxEventNative event, bool& consumed) {} - - static LRESULT __stdcall windowProc(HWND hWnd, UINT msg, - WPARAM wParam, LPARAM lParam); - -public: // Add accessors - HWND mWindow; - UINT_PTR mTimerId; - long mAnimationFPS; - bool mTrackMouse; -}; - -// Key Codes - -#define PX_KEY_NATIVE_ENTER VK_RETURN -#define PX_KEY_NATIVE_BACKSPACE VK_BACK -#define PX_KEY_NATIVE_TAB VK_TAB -#define PX_KEY_NATIVE_CANCEL VK_CANCEL -#define PX_KEY_NATIVE_CLEAR VK_CLEAR -#define PX_KEY_NATIVE_SHIFT VK_SHIFT -#define PX_KEY_NATIVE_CONTROL VK_CONTROL -#define PX_KEY_NATIVE_ALT 0x12 -#define PX_KEY_NATIVE_PAUSE VK_PAUSE -#define PX_KEY_NATIVE_CAPSLOCK 0x14 -#define PX_KEY_NATIVE_ESCAPE VK_ESCAPE -#define PX_KEY_NATIVE_SPACE VK_SPACE -#define PX_KEY_NATIVE_PAGEUP VK_PRIOR -#define PX_KEY_NATIVE_PAGEDOWN VK_NEXT -#define PX_KEY_NATIVE_END VK_END -#define PX_KEY_NATIVE_HOME VK_HOME -#define PX_KEY_NATIVE_LEFT VK_LEFT -#define PX_KEY_NATIVE_UP VK_UP -#define PX_KEY_NATIVE_RIGHT VK_RIGHT -#define PX_KEY_NATIVE_DOWN VK_DOWN -#define PX_KEY_NATIVE_COMMA 0xBC -#define PX_KEY_NATIVE_PERIOD 0xBE -#define PX_KEY_NATIVE_SLASH '/' -#define PX_KEY_NATIVE_ZERO '0' -#define PX_KEY_NATIVE_ONE '1' -#define PX_KEY_NATIVE_TWO '2' -#define PX_KEY_NATIVE_THREE '3' -#define PX_KEY_NATIVE_FOUR '4' -#define PX_KEY_NATIVE_FIVE '5' -#define PX_KEY_NATIVE_SIX '6' -#define PX_KEY_NATIVE_SEVEN '7' -#define PX_KEY_NATIVE_EIGHT '8' -#define PX_KEY_NATIVE_NINE '9' -#define PX_KEY_NATIVE_SEMICOLON 0xBA -#define PX_KEY_NATIVE_EQUALS 0xBB -#define PX_KEY_NATIVE_A 'A' -#define PX_KEY_NATIVE_B 'B' -#define PX_KEY_NATIVE_C 'C' -#define PX_KEY_NATIVE_D 'D' -#define PX_KEY_NATIVE_E 'E' -#define PX_KEY_NATIVE_F 'F' -#define PX_KEY_NATIVE_G 'G' -#define PX_KEY_NATIVE_H 'H' -#define PX_KEY_NATIVE_I 'I' -#define PX_KEY_NATIVE_J 'J' -#define PX_KEY_NATIVE_K 'K' -#define PX_KEY_NATIVE_L 'L' -#define PX_KEY_NATIVE_M 'M' -#define PX_KEY_NATIVE_N 'N' -#define PX_KEY_NATIVE_O 'O' -#define PX_KEY_NATIVE_P 'P' -#define PX_KEY_NATIVE_Q 'Q' -#define PX_KEY_NATIVE_R 'R' -#define PX_KEY_NATIVE_S 'S' -#define PX_KEY_NATIVE_T 'T' -#define PX_KEY_NATIVE_U 'U' -#define PX_KEY_NATIVE_V 'V' -#define PX_KEY_NATIVE_W 'W' -#define PX_KEY_NATIVE_X 'X' -#define PX_KEY_NATIVE_Y 'Y' -#define PX_KEY_NATIVE_Z 'Z' -#define PX_KEY_NATIVE_OPENBRACKET 0xDB -#define PX_KEY_NATIVE_BACKSLASH 0xDC -#define PX_KEY_NATIVE_CLOSEBRACKET 0xDD -#define PX_KEY_NATIVE_NUMPAD0 VK_NUMPAD0 -#define PX_KEY_NATIVE_NUMPAD1 VK_NUMPAD1 -#define PX_KEY_NATIVE_NUMPAD2 VK_NUMPAD2 -#define PX_KEY_NATIVE_NUMPAD3 VK_NUMPAD3 -#define PX_KEY_NATIVE_NUMPAD4 VK_NUMPAD4 -#define PX_KEY_NATIVE_NUMPAD5 VK_NUMPAD5 -#define PX_KEY_NATIVE_NUMPAD6 VK_NUMPAD6 -#define PX_KEY_NATIVE_NUMPAD7 VK_NUMPAD7 -#define PX_KEY_NATIVE_NUMPAD8 VK_NUMPAD8 -#define PX_KEY_NATIVE_NUMPAD9 VK_NUMPAD9 -#define PX_KEY_NATIVE_MULTIPLY VK_MULTIPLY -#define PX_KEY_NATIVE_ADD VK_ADD -#define PX_KEY_NATIVE_SEPARATOR 0xBD -#define PX_KEY_NATIVE_SUBTRACT VK_SUBTRACT -#define PX_KEY_NATIVE_DECIMAL VK_DECIMAL -#define PX_KEY_NATIVE_DIVIDE VK_DIVIDE -#define PX_KEY_NATIVE_F1 VK_F1 -#define PX_KEY_NATIVE_F2 VK_F2 -#define PX_KEY_NATIVE_F3 VK_F3 -#define PX_KEY_NATIVE_F4 VK_F4 -#define PX_KEY_NATIVE_F5 VK_F5 -#define PX_KEY_NATIVE_F6 VK_F6 -#define PX_KEY_NATIVE_F7 VK_F7 -#define PX_KEY_NATIVE_F8 VK_F8 -#define PX_KEY_NATIVE_F9 VK_F9 -#define PX_KEY_NATIVE_F10 VK_F10 -#define PX_KEY_NATIVE_F11 VK_F11 -#define PX_KEY_NATIVE_F12 VK_F12 -#define PX_KEY_NATIVE_DELETE VK_DELETE -#define PX_KEY_NATIVE_NUMLOCK VK_NUMLOCK -#define PX_KEY_NATIVE_SCROLLLOCK VK_SCROLL -#define PX_KEY_NATIVE_PRINTSCREEN 0x2C -#define PX_KEY_NATIVE_INSERT VK_INSERT -#define PX_KEY_NATIVE_HELP VK_HELP -#define PX_KEY_NATIVE_BACKQUOTE 0xC0 -#define PX_KEY_NATIVE_QUOTE 0xDE - -struct synchronizedMessage -{ - char* messageName; - void* p1; -}; -#endif +/* + +pxCore Copyright 2005-2021 John Robinson + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +// pxWindowNative.h + +#ifndef PX_WINDOW_NATIVE_H +#define PX_WINDOW_NATIVE_H + +#include +#include "../pxRect.h" +#include "pxOffscreenNative.h" + +struct pxEventNativeDesc +{ + HWND wnd; + UINT msg; + WPARAM wParam; + LPARAM lParam; +}; + +#ifndef WINCE +#define PX_DEF_WINDOW_STYLE WS_OVERLAPPEDWINDOW +#else +#define PX_DEF_WINDOW_STYLE WS_VISIBLE +#endif + +typedef pxEventNativeDesc& pxEventNative; + + +class pxWindowNative +{ +public: + pxWindowNative(): mWindow(NULL), mTimerId(NULL), mAnimationFPS(0), mTrackMouse(false) {} + virtual ~pxWindowNative(); + + pxError initNative(HWND parent, int left, int top, int width, int height, DWORD style = PX_DEF_WINDOW_STYLE, DWORD styleEx = 0); + + pxError setAnimationFPS(long fps); + + void sendSynchronizedMessage(char* messageName, void* p1); + + void size(int& width, int& height); + // void frameSize(...); + + HWND getHWND() { return mWindow; } // Just because... + +protected: + virtual void onCreate() = 0; + + virtual void onCloseRequest() = 0; + virtual void onClose() = 0; + + virtual void onSize(int w, int h) = 0; + + virtual void onMouseDown(int x, int y, uint32_t flags) = 0; + virtual void onMouseUp(int x, int y, uint32_t flags) = 0; + + virtual void onMouseMove(int x, int y) = 0; + virtual void onScrollWheel(float dx, float dy) = 0; + + virtual void onKeyDown(uint32_t keycode, uint32_t flags) = 0; + virtual void onKeyUp(uint32_t keycode, uint32_t flags) = 0; + virtual void onChar(uint32_t c) = 0; + + virtual void onDraw(pxSurfaceNative surface) = 0; + + virtual void onAnimationTimer() = 0; + + // Windows only for now + + virtual void onMouseLeave() {} + virtual void onSynchronizedMessage(char* messageName, void* p1) {} + + // Windows only for now + // This method will get invoked before calling any of the other event + // handlers. If consumed is set to true then no other event handlers will + // be called; otherwise they will be invoked as usual + virtual void onEvent(pxEventNative event, bool& consumed) {} + + static LRESULT __stdcall windowProc(HWND hWnd, UINT msg, + WPARAM wParam, LPARAM lParam); + +private: // Add accessors + HWND mWindow; + UINT_PTR mTimerId; + long mAnimationFPS; + bool mTrackMouse; +}; + +// Key Codes + +#define PX_KEY_NATIVE_ENTER VK_RETURN +#define PX_KEY_NATIVE_BACKSPACE VK_BACK +#define PX_KEY_NATIVE_TAB VK_TAB +#define PX_KEY_NATIVE_CANCEL VK_CANCEL +#define PX_KEY_NATIVE_CLEAR VK_CLEAR +#define PX_KEY_NATIVE_SHIFT VK_SHIFT +#define PX_KEY_NATIVE_CONTROL VK_CONTROL +#define PX_KEY_NATIVE_ALT 0x12 +#define PX_KEY_NATIVE_PAUSE VK_PAUSE +#define PX_KEY_NATIVE_CAPSLOCK 0x14 +#define PX_KEY_NATIVE_ESCAPE VK_ESCAPE +#define PX_KEY_NATIVE_SPACE VK_SPACE +#define PX_KEY_NATIVE_PAGEUP VK_PRIOR +#define PX_KEY_NATIVE_PAGEDOWN VK_NEXT +#define PX_KEY_NATIVE_END VK_END +#define PX_KEY_NATIVE_HOME VK_HOME +#define PX_KEY_NATIVE_LEFT VK_LEFT +#define PX_KEY_NATIVE_UP VK_UP +#define PX_KEY_NATIVE_RIGHT VK_RIGHT +#define PX_KEY_NATIVE_DOWN VK_DOWN +#define PX_KEY_NATIVE_COMMA 0xBC +#define PX_KEY_NATIVE_PERIOD 0xBE +#define PX_KEY_NATIVE_SLASH '/' +#define PX_KEY_NATIVE_ZERO '0' +#define PX_KEY_NATIVE_ONE '1' +#define PX_KEY_NATIVE_TWO '2' +#define PX_KEY_NATIVE_THREE '3' +#define PX_KEY_NATIVE_FOUR '4' +#define PX_KEY_NATIVE_FIVE '5' +#define PX_KEY_NATIVE_SIX '6' +#define PX_KEY_NATIVE_SEVEN '7' +#define PX_KEY_NATIVE_EIGHT '8' +#define PX_KEY_NATIVE_NINE '9' +#define PX_KEY_NATIVE_SEMICOLON 0xBA +#define PX_KEY_NATIVE_EQUALS 0xBB +#define PX_KEY_NATIVE_A 'A' +#define PX_KEY_NATIVE_B 'B' +#define PX_KEY_NATIVE_C 'C' +#define PX_KEY_NATIVE_D 'D' +#define PX_KEY_NATIVE_E 'E' +#define PX_KEY_NATIVE_F 'F' +#define PX_KEY_NATIVE_G 'G' +#define PX_KEY_NATIVE_H 'H' +#define PX_KEY_NATIVE_I 'I' +#define PX_KEY_NATIVE_J 'J' +#define PX_KEY_NATIVE_K 'K' +#define PX_KEY_NATIVE_L 'L' +#define PX_KEY_NATIVE_M 'M' +#define PX_KEY_NATIVE_N 'N' +#define PX_KEY_NATIVE_O 'O' +#define PX_KEY_NATIVE_P 'P' +#define PX_KEY_NATIVE_Q 'Q' +#define PX_KEY_NATIVE_R 'R' +#define PX_KEY_NATIVE_S 'S' +#define PX_KEY_NATIVE_T 'T' +#define PX_KEY_NATIVE_U 'U' +#define PX_KEY_NATIVE_V 'V' +#define PX_KEY_NATIVE_W 'W' +#define PX_KEY_NATIVE_X 'X' +#define PX_KEY_NATIVE_Y 'Y' +#define PX_KEY_NATIVE_Z 'Z' +#define PX_KEY_NATIVE_OPENBRACKET 0xDB +#define PX_KEY_NATIVE_BACKSLASH 0xDC +#define PX_KEY_NATIVE_CLOSEBRACKET 0xDD +#define PX_KEY_NATIVE_NUMPAD0 VK_NUMPAD0 +#define PX_KEY_NATIVE_NUMPAD1 VK_NUMPAD1 +#define PX_KEY_NATIVE_NUMPAD2 VK_NUMPAD2 +#define PX_KEY_NATIVE_NUMPAD3 VK_NUMPAD3 +#define PX_KEY_NATIVE_NUMPAD4 VK_NUMPAD4 +#define PX_KEY_NATIVE_NUMPAD5 VK_NUMPAD5 +#define PX_KEY_NATIVE_NUMPAD6 VK_NUMPAD6 +#define PX_KEY_NATIVE_NUMPAD7 VK_NUMPAD7 +#define PX_KEY_NATIVE_NUMPAD8 VK_NUMPAD8 +#define PX_KEY_NATIVE_NUMPAD9 VK_NUMPAD9 +#define PX_KEY_NATIVE_MULTIPLY VK_MULTIPLY +#define PX_KEY_NATIVE_ADD VK_ADD +#define PX_KEY_NATIVE_SEPARATOR 0xBD +#define PX_KEY_NATIVE_SUBTRACT VK_SUBTRACT +#define PX_KEY_NATIVE_DECIMAL VK_DECIMAL +#define PX_KEY_NATIVE_DIVIDE VK_DIVIDE +#define PX_KEY_NATIVE_F1 VK_F1 +#define PX_KEY_NATIVE_F2 VK_F2 +#define PX_KEY_NATIVE_F3 VK_F3 +#define PX_KEY_NATIVE_F4 VK_F4 +#define PX_KEY_NATIVE_F5 VK_F5 +#define PX_KEY_NATIVE_F6 VK_F6 +#define PX_KEY_NATIVE_F7 VK_F7 +#define PX_KEY_NATIVE_F8 VK_F8 +#define PX_KEY_NATIVE_F9 VK_F9 +#define PX_KEY_NATIVE_F10 VK_F10 +#define PX_KEY_NATIVE_F11 VK_F11 +#define PX_KEY_NATIVE_F12 VK_F12 +#define PX_KEY_NATIVE_DELETE VK_DELETE +#define PX_KEY_NATIVE_NUMLOCK VK_NUMLOCK +#define PX_KEY_NATIVE_SCROLLLOCK VK_SCROLL +#define PX_KEY_NATIVE_PRINTSCREEN 0x2C +#define PX_KEY_NATIVE_INSERT VK_INSERT +#define PX_KEY_NATIVE_HELP VK_HELP +#define PX_KEY_NATIVE_BACKQUOTE 0xC0 +#define PX_KEY_NATIVE_QUOTE 0xDE + +struct synchronizedMessage +{ + char* messageName; + void* p1; +}; +#endif