pax_global_header00006660000000000000000000000064121210524660014511gustar00rootroot0000000000000052 comment=e2896c249851c9636782b2168d04a2d208fbaab8 lightspark-0.7.2/000077500000000000000000000000001212105246600136675ustar00rootroot00000000000000lightspark-0.7.2/.gitignore000066400000000000000000000004021212105246600156530ustar00rootroot00000000000000# Temp files *~ \#*\# .#* *.dump *.log # # Linux make # i686/* x86_64/* *.gmo # # CMAKE # CMakeFiles Makefile *.cmake # exception for files beyond conf/ !conf/* CMakeCache.txt obj/ version.h # SWF files *.swf # Cscope cscope* #Testsuite tests/tamarin lightspark-0.7.2/CMakeLists.txt000066400000000000000000000502371212105246600164360ustar00rootroot00000000000000#************************************************************************** # Lightspark, a free flash player implementation # # Copyright (C) 2010-2013 Alessandro Pignotti # Copyright (C) 2010 Giacomo Spigler # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . #************************************************************************** CMAKE_MINIMUM_REQUIRED(VERSION 2.6) # Name & Version PROJECT(LIGHTSPARK) SET(MAJOR_VERSION "0") SET(MINOR_VERSION "7") SET(PATCH_VERSION "2") SET(SUBPATCH_VERSION "0") IF(EXISTS "${CMAKE_SOURCE_DIR}/.git/") SET(GIT_VERSION "-git") #Find out if we are exactly at a tag. Then the version #is enough. Only consider the official release tags like #'lightspark-0.5.3' EXECUTE_PROCESS(COMMAND git describe --match "lightspark-*" --tags WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE GIT_DESC ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) #Check if that command failed (maybe git is not installed at all) IF(GIT_DESC) EXECUTE_PROCESS(COMMAND git describe --match "lightspark-*" --tags --abbrev=0 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE GIT_DESC_ABBREV ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) IF(${GIT_DESC} STREQUAL ${GIT_DESC_ABBREV}) #We are exactly at a tag SET(GIT_VERSION "") ELSE() #Append to GIT_VERSION #GIT_DESC_ABBREV is of the form lightspark-0.5.3 (the name of the previous tag) #GIT_DESC is of the form lightspark-0.5.3-69-gf49ec56 (tag-numberOfCommits-currentHash) #We want GIT_REVISION to be 69-gf49ec56 #which denotes the number of commits since the last tag (=release) #and the current commit's hash STRING(REPLACE "${GIT_DESC_ABBREV}-" "" GIT_REVISION "${GIT_DESC}") SET(GIT_VERSION "-${GIT_REVISION}") ENDIF() ENDIF() ELSE(EXISTS "${CMAKE_SOURCE_DIR}/.git/") SET(GIT_VERSION "") ENDIF(EXISTS "${CMAKE_SOURCE_DIR}/.git/") IF(SUBPATCH_VERSION EQUAL "0") SET(FULLVERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}${GIT_VERSION}") ELSE(SUBPATCH_VERSION EQUAL "0") SET(FULLVERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}.${SUBPATCH_VERSION}${GIT_VERSION}") ENDIF(SUBPATCH_VERSION EQUAL "0") SET(SHORTVERSION "${MINOR_VERSION}${PATCH_VERSION}${SUBPATCH_VERSION}") CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/src/version.h.in" "${CMAKE_CURRENT_BINARY_DIR}/version.h" @ONLY) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) # GCC 4.6+ is required, GCC_VERSION macro taken from GCC manual INCLUDE(CheckCSourceCompiles) IF(CMAKE_COMPILER_IS_GNUCC) CHECK_C_SOURCE_COMPILES(" #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #if GCC_VERSION < 40600 #error #endif int main() { return 0; }" GCC_IS_4_6) IF(NOT GCC_IS_4_6) MESSAGE(FATAL_ERROR "GCC 4.6+ is required.") ENDIF(NOT GCC_IS_4_6) ENDIF(CMAKE_COMPILER_IS_GNUCC) # Find put the path of the gnash executable, if available FIND_PROGRAM(GNASH_EXE_PATH NAMES gnash) IF(GNASH_EXE_PATH) MESSAGE(STATUS "Found gnash path: ${GNASH_EXE_PATH}") ELSE(GNASH_EXE_PATH) # Set a default path MESSAGE(STATUS "Gnash not found") SET(GNASH_EXE_PATH "/usr/bin/gnash") ENDIF(GNASH_EXE_PATH) # Find out CPU architecture ... # we could also use IF(CMAKE_SIZEOF_VOID_P EQUAL 4) to determine if it's a 32 or a 64bit arch # # Setting the value of LIB_SUFFIX if not specified (We could build 32bit version on 64bit) # However, some distro don't implement FHS the same way # Suse, Redhat put 64bit libs in /lib64; Debian use /lib for 64bit, but specifies /lib32 for 32bit libs # See FHS 2.3 for Lib directories under each architecture # Some directory shortcuts SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/conf) INCLUDE(Pack) # If we're gcc, then use nasm to get fastpath. If MSVC, just use inline asm to get around # CMake issues IF(CMAKE_COMPILER_IS_GNUCC) INCLUDE(CMakeASM-NASMCompiler) ENDIF(CMAKE_COMPILER_IS_GNUCC) IF(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^i[3-6]86$|^x86$") SET(i386 1) SET(LIB_SUFFIX "" CACHE STRING "Choose the suffix of the lib folder (if any) : None 32") # nasm for assembly optimizations IF(CMAKE_COMPILER_IS_GNUCC) ENABLE_LANGUAGE(ASM-NASM) ENDIF(CMAKE_COMPILER_IS_GNUCC) ELSEIF(${CMAKE_SYSTEM_PROCESSOR} MATCHES "unknown" AND ${CMAKE_SYSTEM} MATCHES "GNU-0.3") # GNU Hurd is i386 SET(i386 1) SET(LIB_SUFFIX "" CACHE STRING "Choose the suffix of the lib folder (if any) : None 32") # nasm for assembly optimizations IF(CMAKE_COMPILER_IS_GNUCC) ENABLE_LANGUAGE(ASM-NASM) ENDIF () ELSEIF(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^x86_64$|^amd64$") SET(x86_64 1) SET(LIB_SUFFIX "" CACHE STRING "Choose the suffix of the lib folder (if any) : None 64") # nasm for assembly optimizations IF(CMAKE_COMPILER_IS_GNUCC) ENABLE_LANGUAGE(ASM-NASM) ENDIF(CMAKE_COMPILER_IS_GNUCC) ELSEIF(${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc") SET(ppc 1) SET(LIB_SUFFIX "" CACHE STRING "Choose the suffix of the lib folder (if any) : None ppc") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__STDC_CONSTANT_MACROS -fPIC") IF(NOT(DISABLE_ALTIVEC)) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maltivec") ENDIF() ELSE(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^i[3-6]86$|^x86$") # All non-x86 non-ppc architectures. SET(LIB_SUFFIX "" CACHE STRING "Choose the suffix of the lib folder (if any) : None") ENDIF(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^i[3-6]86$|^x86$") IF(CMAKE_SYSTEM_NAME STREQUAL CMAKE_HOST_SYSTEM_NAME) SET(CROSSCOMPILING FALSE) ELSE() SET(CROSSCOMPILING TRUE) ENDIF() #On mingw-cross-env, all depedencies are static libs IF(CROSSCOMPILING AND MINGW) SET(STATICDEPS TRUE) ELSE() SET(STATICDEPS FALSE) ENDIF() # Using relative folders, cmake happens by itself CMAKE_INSTALL_PREFIX IF(UNIX) SET(ETCDIR "/etc") #Using absolute folder SET(BINDIR "bin") SET(DATADIR "share") # Absolute path, because this path is embedded in the binary SET(LSDATADIR "${CMAKE_INSTALL_PREFIX}/${DATADIR}/lightspark") SET(LIBDIR "lib${LIB_SUFFIX}") #We need a absolute path here because we use it for rpath #later on SET(PRIVATELIBDIR "${CMAKE_INSTALL_PREFIX}/${LIBDIR}/lightspark") SET(CMAKE_INSTALL_RPATH "${PRIVATELIBDIR}") SET(PLUGINSDIR "${PRIVATELIBDIR}/plugins") ELSE() SET(ETCDIR ".") SET(BINDIR ".") SET(DATADIR ".") SET(LSDATADIR ".") SET(LIBDIR ".") SET(PRIVATELIBDIR ".") SET(PLUGINSDIR ".") ENDIF(UNIX) # Setting variables IF(WIN32) SET(AUDIO_BACKEND "winmm" CACHE STRING "Which audio backends should be built?") ELSE() SET(AUDIO_BACKEND "pulseaudio" CACHE STRING "Which audio backends should be built?") ENDIF() SET(CMAKE_INSTALL_PREFIX "/usr/local" CACHE PATH "Install prefix, default is /usr/local (UNIX) and C:\\Program Files (Windows)") SET(COMPILE_LIGHTSPARK TRUE CACHE BOOL "Compile Lightspark?") SET(COMPILE_TIGHTSPARK TRUE CACHE BOOL "Compile Tightspark?") SET(COMPILE_PLUGIN TRUE CACHE BOOL "Compile the browser plugin?") SET(ENABLE_CURL TRUE CACHE BOOL "Enable CURL? (Required for Downloader functionality)") SET(ENABLE_GLES2 FALSE CACHE BOOL "Build with OpenGLES 2.0 support instead of OpenGL") SET(ENABLE_LIBAVCODEC TRUE CACHE BOOL "Enable libavcodec and dependent functionality?") SET(ENABLE_RTMP TRUE CACHE BOOL "Enable librtmp and dependent functionality?") SET(ENABLE_PROFILING FALSE CACHE BOOL "Enable profiling support? (Causes performance issues)") SET(ENABLE_MEMORY_USAGE_PROFILING FALSE CACHE BOOL "Enable profiling of memory usage? (Causes performance issues)") SET(PLUGIN_DIRECTORY "${LIBDIR}/mozilla/plugins" CACHE STRING "Directory to install Firefox plugin to") IF(ENABLE_DEBIAN_ALTERNATIVES OR WIN32) SET(PLUGIN_DIRECTORY ${PRIVATELIBDIR}) ENDIF() IF(NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo Profile" FORCE) ENDIF(NOT CMAKE_BUILD_TYPE) # The library is searched in its private library directory SET(CMAKE_SKIP_BUILD_RPATH FALSE) SET(CMAKE_INSTALL_RPATH "${PRIVATELIBDIR}") # Libraries we need INCLUDE(FindPkgConfig REQUIRED) INCLUDE(FindGettext REQUIRED) INCLUDE(FindLLVM REQUIRED) IF(${LLVM_STRING_VERSION} VERSION_LESS 2.8) MESSAGE(FATAL_ERROR "LLVM >=2.8 is required!") ENDIF(${LLVM_STRING_VERSION} VERSION_LESS 2.8) IF(${LLVM_STRING_VERSION} VERSION_EQUAL 2.9) MESSAGE(FATAL_ERROR "LLVM !=2.9 is required!") ENDIF(${LLVM_STRING_VERSION} VERSION_EQUAL 2.9) IF(${LLVM_STRING_VERSION} VERSION_EQUAL 2.8) ADD_DEFINITIONS(-DLLVM_28) ENDIF(${LLVM_STRING_VERSION} VERSION_EQUAL 2.8) IF(${LLVM_STRING_VERSION} VERSION_EQUAL 3.0) ADD_DEFINITIONS(-DLLVM_30) ENDIF(${LLVM_STRING_VERSION} VERSION_EQUAL 3.0) IF(${LLVM_STRING_VERSION} VERSION_GREATER 3.0) ADD_DEFINITIONS(-DLLVM_31) ENDIF(${LLVM_STRING_VERSION} VERSION_GREATER 3.0) INCLUDE(FindZLIB REQUIRED) INCLUDE(FindFreetype REQUIRED) IF(NOT(ENABLE_GLES2)) INCLUDE(FindOpenGL REQUIRED) INCLUDE(FindGLEW REQUIRED) ENDIF(NOT(ENABLE_GLES2)) INCLUDE(FindPCRE REQUIRED) INCLUDE(FindJPEG REQUIRED) INCLUDE(FindPNG REQUIRED) pkg_check_modules(XMLPP REQUIRED libxml++-2.6>=2.33.1) pkg_check_modules(LZMA REQUIRED liblzma) INCLUDE_DIRECTORIES(${LZMA_INCLUDE_DIRS}) SET(OPTIONAL_LIBRARIES ${OPTIONAL_LIBRARIES} ${LZMA_LIBRARIES}) IF(XMLPP_FOUND AND NOT(XMLPP_VERSION VERSION_LESS 2.35.1)) ADD_DEFINITIONS(-DXMLPP_2_35_1) ENDIF(XMLPP_FOUND AND NOT(XMLPP_VERSION VERSION_LESS 2.35.1)) find_package(Boost COMPONENTS filesystem system REQUIRED) if(Boost_FOUND) INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) #Without BOOST_MULTI_INDEX_DISABLE_SERIALIZATION, it will indirectly include #windows.h and pollute our namespace ADD_DEFINITIONS(-DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION) ENDIF(Boost_FOUND) pkg_check_modules(CAIRO REQUIRED cairo pangocairo) IF(UNIX) pkg_check_modules(X11 REQUIRED x11) INCLUDE_DIRECTORIES(${X11_INCLUDE_DIRS}) ENDIF(UNIX) IF(ENABLE_GLES2) pkg_check_modules(GLES2 REQUIRED egl glesv2) ADD_DEFINITIONS(-DENABLE_GLES2) ENDIF(ENABLE_GLES2) IF(WIN32) SET(EXTRA_LIBS_LIBRARIES ${EXTRA_LIBS_LIBRARIES} ws2_32.lib imagehlp.lib) ENDIF(WIN32) IF(AUDIO_BACKEND) ADD_DEFINITIONS(-DAUDIO_BACKEND="${AUDIO_BACKEND}") ENDIF(AUDIO_BACKEND) IF(ENABLE_LIBAVCODEC) pkg_check_modules(FFMPEG libavcodec libavutil libavformat) IF(NOT(FFMPEG_FOUND)) INCLUDE(FindFFMpeg REQUIRED) ENDIF(NOT(FFMPEG_FOUND)) # Compatibility checks for ffmpeg deprecated functions INCLUDE(CheckFunctionExists REQUIRED) SET(CMAKE_REQUIRED_FLAGS ${LIBAVCODEC_CFLAGS}) SET(CMAKE_REQUIRED_INCLUDES ${FFMPEG_INCLUDE_DIRS}) SET(CMAKE_REQUIRED_LIBRARIES ${FFMPEG_LIBRARIES}) CHECK_FUNCTION_EXISTS(avcodec_decode_video2 HAVE_AVCODEC_DECODE_VIDEO2) CHECK_FUNCTION_EXISTS(avcodec_decode_audio3 HAVE_AVCODEC_DECODE_AUDIO3) CHECK_FUNCTION_EXISTS(avcodec_decode_audio4 HAVE_AVCODEC_DECODE_AUDIO4) CHECK_FUNCTION_EXISTS(avio_alloc_context HAVE_AVIO_ALLOC_CONTEXT) CHECK_FUNCTION_EXISTS(avcodec_alloc_context3 HAVE_AVCODEC_ALLOC_CONTEXT3) CHECK_FUNCTION_EXISTS(avcodec_open2 HAVE_AVCODEC_OPEN2) CHECK_FUNCTION_EXISTS(avformat_close_input HAVE_AVFORMAT_CLOSE_INPUT) CHECK_FUNCTION_EXISTS(avformat_find_stream_info HAVE_AVFORMAT_FIND_STREAM_INFO) SET(CMAKE_REQUIRED_FLAGS) SET(CMAKE_REQUIRED_INCLUDES) SET(CMAKE_REQUIRED_LIBRARIES) IF(HAVE_AVCODEC_DECODE_VIDEO2) ADD_DEFINITIONS(-DHAVE_AVCODEC_DECODE_VIDEO2) ENDIF(HAVE_AVCODEC_DECODE_VIDEO2) IF(HAVE_AVCODEC_DECODE_AUDIO3) ADD_DEFINITIONS(-DHAVE_AVCODEC_DECODE_AUDIO3) ENDIF(HAVE_AVCODEC_DECODE_AUDIO3) IF(HAVE_AVCODEC_DECODE_AUDIO4) ADD_DEFINITIONS(-DHAVE_AVCODEC_DECODE_AUDIO4) ENDIF(HAVE_AVCODEC_DECODE_AUDIO4) IF(HAVE_AVIO_ALLOC_CONTEXT) ADD_DEFINITIONS(-DHAVE_AVIO_ALLOC_CONTEXT) ENDIF(HAVE_AVIO_ALLOC_CONTEXT) IF(HAVE_AVCODEC_ALLOC_CONTEXT3) ADD_DEFINITIONS(-DHAVE_AVCODEC_ALLOC_CONTEXT3) ENDIF(HAVE_AVCODEC_ALLOC_CONTEXT3) IF(HAVE_AVCODEC_OPEN2) ADD_DEFINITIONS(-DHAVE_AVCODEC_OPEN2) ENDIF(HAVE_AVCODEC_OPEN2) IF(HAVE_AVFORMAT_CLOSE_INPUT) ADD_DEFINITIONS(-DHAVE_AVFORMAT_CLOSE_INPUT) ENDIF(HAVE_AVFORMAT_CLOSE_INPUT) IF(HAVE_AVFORMAT_FIND_STREAM_INFO) ADD_DEFINITIONS(-DHAVE_AVFORMAT_FIND_STREAM_INFO) ENDIF(HAVE_AVFORMAT_FIND_STREAM_INFO) ADD_DEFINITIONS(-DENABLE_LIBAVCODEC) ENDIF(ENABLE_LIBAVCODEC) pkg_check_modules(GLIB REQUIRED glib-2.0) pkg_check_modules(GTHREAD REQUIRED gthread-2.0) pkg_check_modules(GMODULE REQUIRED gmodule-2.0) pkg_check_modules(GLIBMM REQUIRED glibmm-2.4) INCLUDE_DIRECTORIES(${GLIBMM_INCLUDE_DIRS}) pkg_check_modules(GTK REQUIRED gtk+-2.0) IF(GLIBMM_FOUND AND NOT(GLIBMM_VERSION VERSION_LESS 2.31.0)) ADD_DEFINITIONS(-DHAVE_NEW_GLIBMM_THREAD_API) ENDIF(GLIBMM_FOUND AND NOT(GLIBMM_VERSION VERSION_LESS 2.31.0)) IF(GTHREAD_FOUND AND (GTHREAD_VERSION VERSION_LESS 2.32.0)) #The definition was not removed in 2.32.0, but its #deprecated since then and makes problems in the win32 build ADD_DEFINITIONS(-DHAVE_G_THREAD_INIT) ENDIF(GTHREAD_FOUND AND (GTHREAD_VERSION VERSION_LESS 2.32.0)) INCLUDE_DIRECTORIES(${LLVM_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${FREETYPE_INCLUDE_DIRS}) IF(ENABLE_GLES2) INCLUDE_DIRECTORIES(${GLES2_INCLUDE_DIRS}) ELSE() INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${GLEW_INCLUDE_DIR}) ENDIF(ENABLE_GLES2) INCLUDE_DIRECTORIES(${PCRE_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${PNG_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${XMLPP_INCLUDE_DIRS}) INCLUDE_DIRECTORIES(${CAIRO_INCLUDE_DIRS}) INCLUDE_DIRECTORIES(${GLIB_INCLUDE_DIRS}) INCLUDE_DIRECTORIES(${GTK_INCLUDE_DIRS}) IF(ENABLE_LIBAVCODEC) INCLUDE_DIRECTORIES(${FFMPEG_INCLUDE_DIRS}) SET(OPTIONAL_LIBRARIES ${OPTIONAL_LIBRARIES} ${FFMPEG_LIBRARIES}) ENDIF(ENABLE_LIBAVCODEC) IF(CMAKE_COMPILER_IS_GNUCC) IF(MINGW) SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed,--no-undefined -mthreads ${CMAKE_EXE_LINKER_FLAGS}") SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed,--no-undefined,--enable-stdcall-fixup -mthreads ${CMAKE_SHARED_LINKER_FLAGS}") ELSE() SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--no-undefined ${CMAKE_EXE_LINKER_FLAGS}") SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed,-z,noexecstack,--no-undefined ${CMAKE_SHARED_LINKER_FLAGS}") ENDIF() SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "-s") SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "-s") ENDIF(CMAKE_COMPILER_IS_GNUCC) LINK_DIRECTORIES(${LLVM_LIB_DIR}) IF(ENABLE_CURL) pkg_check_modules(CURL REQUIRED libcurl) INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIR}) IF(STATICDEPS) SET(OPTIONAL_LIBRARIES ${OPTIONAL_LIBRARIES} ${CURL_STATIC_LIBRARIES} crypt32) ADD_DEFINITIONS(-DCURL_STATICLIB) ELSE() SET(OPTIONAL_LIBRARIES ${OPTIONAL_LIBRARIES} ${CURL_LIBRARIES}) ENDIF() ADD_DEFINITIONS(-DENABLE_CURL) ENDIF(ENABLE_CURL) IF(ENABLE_RTMP) pkg_check_modules(RTMP REQUIRED librtmp) SET(OPTIONAL_LIBRARIES ${OPTIONAL_LIBRARIES} ${RTMP_LIBRARIES}) ADD_DEFINITIONS(-DENABLE_RTMP) ENDIF(ENABLE_RTMP) IF(ENABLE_PROFILING) ADD_DEFINITIONS(-DPROFILING_SUPPORT) ENDIF(ENABLE_PROFILING) IF(ENABLE_MEMORY_USAGE_PROFILING) ADD_DEFINITIONS(-DMEMORY_USAGE_PROFILING) ENDIF(ENABLE_MEMORY_USAGE_PROFILING) # Compiler defaults flags for different profiles IF(CMAKE_COMPILER_IS_GNUCC) IF(MINGW) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mms-bitfields -mthreads -fexceptions -Wall -Wnon-virtual-dtor -Woverloaded-virtual -pipe -std=c++0x -Wdisabled-optimization -Wextra -Wno-unused-parameter -Wno-invalid-offsetof") ELSE() SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wnon-virtual-dtor -Woverloaded-virtual -pipe -fvisibility=hidden -fvisibility-inlines-hidden -std=c++0x -Wdisabled-optimization -Wextra -Wno-unused-parameter -Wno-invalid-offsetof") ENDIF() SET(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -DEXPENSIVE_DEBUG") SET(CMAKE_CXX_FLAGS_PROFILE "-g -pg -O2") SET(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -O2 -DNDEBUG") SET(CMAKE_CXX_FLAGS_LEANDEBUG "-g -O2") ADD_DEFINITIONS(-DLS_DATADIR="${LSDATADIR}" -DGNASH_PATH="${GNASH_EXE_PATH}" -DPRIVATELIBDIR="${PRIVATELIBDIR}") ENDIF(CMAKE_COMPILER_IS_GNUCC) IF(MSVC) ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS -DVPCOMPAT -DPTW32_STATIC_LIB -DPCRE_STATIC) ENDIF(MSVC) IF(STATICDEPS) ADD_DEFINITIONS(-DLIBXML_STATIC -DGLEW_STATIC) ENDIF() # Check if the system have atomic header ( gcc >= 4.6 ) INCLUDE (CheckIncludeFileCXX) CHECK_INCLUDE_FILE_CXX (atomic HAVE_ATOMIC) IF(HAVE_ATOMIC) ADD_DEFINITIONS(-DHAVE_ATOMIC) ENDIF(HAVE_ATOMIC) # Setting the output directories, so we can build all profiles without mixmatching IF(CMAKE_COMPILER_IS_GNUCC) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_SYSTEM_PROCESSOR}/${CMAKE_BUILD_TYPE}/bin") SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_SYSTEM_PROCESSOR}/${CMAKE_BUILD_TYPE}/lib${LIB_SUFFIX}") #SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/objs/${CMAKE_SYSTEM_PROCESSOR}/${CMAKE_BUILD_TYPE}/lib${LIB_SUFFIX}" CACHE PATH "Static libraries output directory") ENDIF(CMAKE_COMPILER_IS_GNUCC) #Install icons and desktop file if(UNIX) FOREACH(i 16 22 24 32 36 48 64 72 96 128 192 256 ) INSTALL(FILES media/lightspark-ico-${i}x${i}.png DESTINATION ${DATADIR}/icons/hicolor/${i}x${i}/apps RENAME lightspark.png ) ENDFOREACH(i) INSTALL(FILES media/lightspark-ico.svg DESTINATION ${DATADIR}/icons/hicolor/scalable/apps RENAME lightspark.svg ) INSTALL(FILES media/lightspark.desktop DESTINATION ${DATADIR}/applications ) endif(UNIX) # generate locales for gettext GETTEXT_CREATE_TRANSLATIONS(i18n/lightspark.pot ALL i18n/pl.po i18n/fr.po i18n/zh_CN.po) if(UNIX) INSTALL(FILES etc/xdg/lightspark.conf DESTINATION ${ETCDIR}/xdg/) ELSE() INSTALL(FILES COPYING DESTINATION "." RENAME COPYING.txt) INSTALL(FILES COPYING.LESSER DESTINATION "." RENAME COPYING.LESSER.txt) endif(UNIX) SUBDIRS(src) #-- CPack setup - use 'make package' to build SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Lightspark is an LGPLv3 licensed cross-platform Flash player and browser plugin") SET(CPACK_PACKAGE_VENDOR "Lightspark Team") SET(CPACK_PACKAGE_NAME "Lightspark") SET(CPACK_PACKAGE_VERSION_MAJOR "${MAJOR_VERSION}") SET(CPACK_PACKAGE_VERSION_MINOR "${MINOR_VERSION}") IF(SUBPATCH_VERSION EQUAL "0") SET(CPACK_PACKAGE_VERSION_PATCH "${PATCH_VERSION}${GIT_VERSION}") ELSE() SET(CPACK_PACKAGE_VERSION_PATCH "${PATCH_VERSION}.${SUBPATCH_VERSION}${GIT_VERSION}") ENDIF() SET(CPACK_NSIS_MENU_LINKS "") #In release builds, we already strip symbols (see LDFLAGS), and compress by upx #Therefore we cannot strip afterwards SET(CPACK_STRIP_FILES FALSE) SET(CPACK_RESOURCE_FILE_LICENSE ${PROJECT_SOURCE_DIR}/COPYING) SET(CPACK_NSIS_HELP_LINK "http:////www.lightspark.org") SET(CPACK_NSIS_URL_INFO_ABOUT "http:////www.lightspark.org") SET(CPACK_PACKAGE_ICON ${PROJECT_SOURCE_DIR}/media/lightspark-logo.svg) IF(WIN32) SET(CPACK_PACKAGE_INSTALL_DIRECTORY "Lightspark") SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS " WriteRegStr HKCU 'Software\\\\MozillaPlugins\\\\@lightspark.github.com/Lightspark;version=1' 'Description' 'Lightspark' WriteRegStr HKCU 'Software\\\\MozillaPlugins\\\\@lightspark.github.com/Lightspark;version=1' 'ProductName' 'Lightspark' WriteRegStr HKCU 'Software\\\\MozillaPlugins\\\\@lightspark.github.com/Lightspark;version=1' 'Vendor' 'Lightspark Team' WriteRegStr HKCU 'Software\\\\MozillaPlugins\\\\@lightspark.github.com/Lightspark;version=1' 'Version' '1' WriteRegStr HKCU 'Software\\\\MozillaPlugins\\\\@lightspark.github.com/Lightspark;version=1' 'Path' '$INSTDIR\\\\nplightsparkplugin.dll' WriteRegStr HKCU 'Software\\\\MozillaPlugins\\\\@lightspark.github.com/Lightspark;version=1\\\\MimeTypes\\\\application/x-shockwave-flash' '' '' ") SET(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS " DeleteRegKey HKLM 'Software\\\\MozillaPlugins\\\\@lightspark.github.com/Lightspark;version=1' ") ENDIF(WIN32) #Must come after the definitions INCLUDE(CPack) lightspark-0.7.2/CONTRIBUTING000066400000000000000000000006541212105246600155260ustar00rootroot00000000000000Debug builds ------------ If you need source level debugging $cmake -DCMAKE_BUILD_TYPE=Debug . && make The libs and binaries will end up in a directory called Debug gdb setup ---------- To properly output C++ objects in gdb put this line in the .gdbinit file in your Lighspark dir set print object on Development guide in the wiki ----------------------------- https://github.com/lightspark/lightspark/wiki/DevelopmentGuide lightspark-0.7.2/CONTRIBUTORS000066400000000000000000000027571212105246600155620ustar00rootroot00000000000000All Lightspark contributors recorded in git logs, in alphabetical order: Alessandro Pignotti Alexandre Demers Anand Kumria Antti Ajanki Arthur HUILLET bzztbomb cdc Daniele Di Proietto DaNiMoTh Didier Raboud Dmitry Marakasov Dongxu Li Elliott Sales de Andrade Ennio Barbaro Frank Wienberg Giacomo Spigler Gwenole Beauchesne Henri Valta Hicham HAOUARI Jacopo Corbetta Jani Monoses Jasper St. Pierre Joerg Mayer Jon Morton Joshua Roys Luca Invernizzi Luca Tettamanti Ludger Krämer Marcin 'exine' M Matthias Gehre Max Lapshin nobled Pat Wilson piotr Rémi C robert.ancell@gmail.com Thomas Dziedzic Timon Van Overveldt Tim Retout lightspark-0.7.2/COPYING000066400000000000000000001045131212105246600147260ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . lightspark-0.7.2/COPYING.LESSER000066400000000000000000000167431212105246600157310ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. lightspark-0.7.2/ChangeLog000066400000000000000000000157171212105246600154540ustar00rootroot00000000000000lightspark: An open source flash player implementation Version 0.7.2: * Improved image support: alpha in palettes, abbreviated JPEGs * Improved embedded font parsing and text positioning * Open links in a browser (plugin only) * BitmapData improvements * Fixed many crashes Version 0.7.1: * Fixes for YouTube * Support keyboard press and release events * Support mouse wheel events and other mouse event improvements * Support LLVM 3.2 * Implemented hit testing of DisplayObjects * Parse JPEG images embedded in DefineBits tags * Parse RGB15 and paletted images in DefineBitsLossless tags * Improved XML support Version 0.7.0: * Support LZMA compressed SWFs [Requires liblzma] * Improved BitmapData support * Improved ActionScript compatibility * Improved virtual machine performance and memory consumption * Improved XML support * Experimental support for bytecode optimization at runtime * Improved ExternalInterface (browser integration) support * Improved performance of JPEG loading * Support for XMLSocket * Completely redesigned and improved masking support Version 0.6.0: * Enable RTMP support by default, requires librtmp * Fixed support for IEventDispatcher implementation pattern * Improved serialization robustness * Improved matrix handling * Implement string and namespace pooling to reduce memory consumption * Proper support for private namespaces * Improved support for fonts * Support LLVM 3.1 * Fix full volume issue when PulseAudio flat volumes are enabled * Initial support for AIR desktop applications * Support for www.bbc.co.uk video player Version 0.5.7: * Fixed a few memory leaks * Improved support for BitmapData::draw * Support for BitmapData::copyPixels * Support for soft masking * Support for memory usage profiling (massif compatible) Version 0.5.6: * Fix YouTube support for several videos * Support for custom serialization/deserialization * Support RPC (NetConnection::call) * Support for PNG images * Experimental support for Google Street View Version 0.5.5: * Support Firefox 10 * Fixed mutiple bugs Version 0.5.4.1: * Fix YouTube support * Look for LLVM-3.0 when building Version 0.5.4: * Fix build against LLVM-3.0 * Drop OpenAL backend * ENABLE_RTMP=1 by default * Many fixes for crashers and hangs * API additions and fixes to XML, Vector, Matrix * Code cleanups Version 0.5.3: * Support playing RTMP streams from Flash Media Server when compiled with ENABLE_RTMP=1 * Fixed several memory leaks * Ported Lightspark to windows, including a firefox plugin * Fixed multiple hangs and crashes Version 0.5.2.1: * Patch version to fix up reported version. Version 0.5.2: * Requires llvm 2.8 * Added LIGHTSPARK_PLUGIN_PARAMFILE environment variable to let the plugin write parameter files that are compatible with lightsparks '-p' commandline switch * Many bugfixes and changes to the VM that make many more tests pass * Reorganized code that implements the Flash and AS3 API into directories and files that more closely match the respective package and class hierarchies Version 0.5.1: * Misc fixes to better support YouTube, Vimeo, Flowplayer * VM correctness improvements * Support for AS templates * Dropped half-finished AVM1 support * Support for EGL/GLES2 rendering * Support for loading external JPEGs * Better text handling(e.g. coloring) * Improved test runner, support for the Tamarin testsuite * Various API fixes for bugs uncovered by the testsuite * Dropped mozilla dependency, use internal NPAPI headers * Added LIGHTSPARK_PLUGIN_LOGLEVEL environment variable to control the log level of the browser Version 0.5.0: * Improved XML support * Improved FFMpeg based media playback * Improved robustness * Improved ExternalInterface (browser communication) * Improved masking support * Improved alpha support * Support capture phase of the event flow * Support SimpleButton * Support audio volume * Support for introspection of ActionScript objects (describeType) * Support for AMF3 serialization * Support plugin resize * Support for dynamic text * Remove SDL dependency from the core * Removed Fontconfig and FTGL dependencies * Added SDL based audio backend * More GLES compliant * Faster shader code Version 0.4.8 * Reduced memory usage on streaming videos * Fixed a couple of refcounting bugs * Improved robustness when parsing broken XML Version 0.4.8 RC1 * Experimental Vimeo support * Cleaned up Shape support * Improved Timer support * Support for JPEG parsing * Improved reference counting * Support for static text * MP4 support (FFMpeg based) Version 0.4.7.1 * Fix YouTube breakage Version 0.4.7 * Fix YouTube breakage * More robustness against deadlocks * Implement flash.net.URLVariables * XML fixes * Browser plugin is now built by default Version 0.4.6.1: * Fix YouTube breakage Version 0.4.6: * Fix YouTube breakage * Vastly improved gradient support * Fixed a large amount of graphics glitches * Add support for upcoming Gnash release 0.8.9 * Add profiling support for ActionScript code * Add support for muting all sounds using the 'm' key * Add support for copying error messages using the 'c' key in plugin Version 0.4.5.3 * Fix YouTube breakage Version 0.4.5.2 * Fix YouTube breakage Version 0.4.5.1 * Fix YouTube breakage * Add support for AMF3 parsing * Experimental support for PowerPC Linux Version 0.4.5 * Added --version command line option Version 0.4.5 RC1: * Use Advanced Graphics Engine * Masking and clipping support Version 0.4.4.3: * Add support for cross-domain policy files Version 0.4.4.2: * Pluginized architecture for audio backends Version 0.4.4.1: * Disk based caching for downloads * Fixes a crash when using flashblock Version 0.4.4: * Localization support * Exception handling support * More robust network handling * Stream controls (Play/Pause) Version 0.4.3: * Liquid layout support * Several small bug fixes Version 0.4.3 RC1: * Faster rendering of the input layer * Reduced memory consumption * Support for H263/MP3 videos * Smoother playback of audio and video Version 0.4.2.3: * Bugfix release Version 0.4.2.2: * Fallback on Gnash for older clips Version 0.4.2.1: * Small bugfix Version 0.4.2: * Use fontconfig to select fonts * Nore efficient handling of read only strings * Greater compatibility with youtube videos * Better compatibility with radeon cards * Sound synchronization * Chrome/Chromium support * Firefox's OOPP support Version 0.4.1: * Optimized rendering of simple graphics * First youtube support Version 0.4.0 RC3: * Also use NPOT if available Version 0.4.0 RC2: * Better support for older intel cards Version 0.4.0 RC1: * Better stability, the plugin should not crash * Use Power-Of-Two sized textures for better compatibility Version 0.3.9: * More complete cleanup of GL resources Version 0.3.8: * Solved deadlock issues when using FlashBlock Version 0.3.7: * Improved stability and relaxed graphics requirements Version 0.3.6: * Be more careful about glew initialization lightspark-0.7.2/Doxyfile000066400000000000000000002100561212105246600154010ustar00rootroot00000000000000# Doxyfile 1.7.0 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = Lightspark # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = docs/doxygen # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this # tag. The format is ext=language, where ext is a file extension, and language # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penality. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will rougly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = YES # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = YES # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = YES # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = YES # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. The create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = src src/plugin src/plugin/include src/scripting src/parsing src/backends src/platforms # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.d \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ \ *.idl \ *.odl \ *.cs \ *.php \ *.php3 \ *.inc \ *.m \ *.mm \ *.dox \ *.py \ *.f90 \ *.f \ *.vhd \ *.vhdl # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = * # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the stylesheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = YES # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvances is that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = NO # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans.ttf # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES lightspark-0.7.2/README000066400000000000000000000057721212105246600145620ustar00rootroot00000000000000Lightspark is an open source Flash player implementation for playing files in SWF format. Lightspark can run as a web browser plugin or as a standalone application. Lightspark supports SWF files written on the newest version of the ActionScript language, ActionScript 3.0, which was introduced at the same time as Flash player 9. INSTALLATION ============ To compile this software you need to install development packages for llvm (version 2.8, 3.0, 3.1 or 3.2), opengl, curl, zlib, libavcodec, libglew, pcre, librtmp, cairo, libboost-filesystem, libxml++ (version 2.33.1 or newer), gtk-2, libjpeg, libavformat, pango, liblzma If sound is enabled (on by default), you will also need the development package for pulseaudio-libs and/or libsdl. If the browser plugin is enabled (on by default), you will need the development package for xulrunner. Install also gcc (version 4.6.0 or newer), cmake and nasm. To build the software please follow these steps. 1) cd lightspark 2) mkdir obj 3) cd obj 4) cmake -DCMAKE_BUILD_TYPE=Release .. 5) make 6) sudo make install DEBUG MODE: To enable debug mode change the cmake command like this: 4b) cmake -DCMAKE_BUILD_TYPE=Debug CMAKE_BUILD_TYPE available: Debug Release RelWithDebInfo Profile Sound support may be disabled using the following option: -DENABLE_SOUND=0 The audio backend can be set using -DAUDIO_BACKEND= (default is pulseaudio) EXECUTION ========= Using `make install`, lightspark is installed in the system wide Firefox plugin path and Firefox should show it in the about:plugins list and in the Tools->Add-ons->Plugins window. Lightspark registers itself as the plugin for application/x-shockwave-flash and for application/x-lightspark, so it should be recognisable in the about:plugins page. Its description string is "Shockwave Flash 12.1 r". The current version is now "r710". Firefox is not able to deal very well with multiple plugins for the same MIME type. If you only see a black box where a flash app should be try to remove any other flash plugin you have installed. Keyboard shortcuts ------------------ Ctrl+Q Quit (standalone player only) Ctrl+M Mute/unmute sounds Ctrl+P Show profiling data Ctrl+C Copy an error to the clipboard (when Lightspark fails) SWF SUPPORT =========== Many web sites do not yet work yet because the implementation is incomplete. See the following page for support status of selected web sites: https://github.com/lightspark/lightspark/wiki/Site-Support You may also try Lightspark on some known-to-work Youtube movies: http://www.youtube.com/watch?v=ca20NEt4VSQ http://www.youtube.com/watch?v=4N2YWRJ-ppo http://www.youtube.com/watch?v=XITHbsUUlYI http://www.youtube.com/watch?v=-j7c0u9yZ8M http://www.youtube.com/watch?v=G4S9tV8ZLcE http://www.youtube.com/watch?v=FatHLHG2uGY REPORTING BUGS ============== If you think you have found a bug in Lightspark, please file a bug report at https://bugs.launchpad.net/lightspark. See https://github.com/lightspark/lightspark/wiki/Reporting-Bugs for help on reporting bugs. lightspark-0.7.2/README.GRAPHICS000066400000000000000000000034151212105246600157510ustar00rootroot00000000000000Overview of graphics pipeline ----------------------------- Lightspark tries to be efficient on the rendering side using both caching and multi threaded rasterization. Most of the graphic assets come in vectorial form. Cairo is used to transform vectorial data in raster (bitmap format). PangoCairo is used for dynamic text. Rendered data is then transferred onto OpenGL textures using Pixel Buffer Objects (that hopefully are implemented using DMA). Textures are only loaded when an object changes, so static objects are always cached in VRAM. Pipeline for Stage: 1) When an object changes and needs to be redrawn it will call its DisplayObject::requestInvalidation method. The method needs an InvalidateQueue parameter and will add the object to such queue. 2) Invalidation requests are gathered together in the queue, but not executed until the currently handled event ends, to make sure we are rendering a consistent state. 3) At the end of the event all objects in the queue will have their ::invalidate method called. This method returns an instance of IDrawable or NULL is rendering is not necessary. It's important that the IDrawable instance contains a copy of all the needed object state since the object may change while the rendering happens. In the future Copy On Write could be useful to save the copy of data in some cases. 4) The returned IDrawable and a reference to the object itself will then be stored inside an AsyncDrawJob. The reference to the objects is necessary to make sure the CachedSurface of the object, which stores information about the OpenGL texture where the data must end, survives until the end of the rendering. 5) The AsyncDrawJob in added to the Thread Pool, to be executed. It will use IDrawable::getPixelBuffer to get the raw pixels and upload them to the GPU. lightspark-0.7.2/README.tests000066400000000000000000000025701212105246600157140ustar00rootroot00000000000000You can get the Flex 4 SDK at: http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4 Flex 4 SDK is assumed to be installed in $FLEX_ROOT To compile and run the test suite run: ./tests Run "./tests --help" inside tests/ to see scripts usage. Compiling tests manually inside the tests/ directory: $FLEX_ROOT/bin/mxmlc -static-link-runtime-shared-libraries -compiler.omit-trace-statements=false test.mxml -output test.swf Creating new testcases ---------------------- Use template.mxml as a template for new testcases. We've provided a simple Tests class which should be used where possible to test general behaviour of AS classes. See Tests.as for its usage. Please use a naming scheme as follow: For toplevel classes: tests/CLASSNAME_test.mxml (CLASSNAME is the exact name of the class/function) For other classes: tests/NAMESPACE_CLASSNAME_test.mxml (NAMESPACE is for example "net" for "flash.net" classes/functions, e.g.: tests/net_NetStream_test.mxml) Please group all tests for one class in one file. Subdirectories -------------- tests/other: Tests that aren't suitable for testing with the Tests class should be put in here. (e.g.: testing video playing, StageScaleMode testing etc...). The naming schemes still apply to these testcases though. tests/unimplemented: Tests for unimplemented features. tests/performance: Tests aimed at measuring runtime performance. lightspark-0.7.2/README.win32000066400000000000000000000040471212105246600155150ustar00rootroot00000000000000-- How to crosscompile lightspark win32 binaries on a linux box -- (This is the only supported way to build win32 binaries) I assume that your currently one level above the directory 'git', which contains the lightspark sources. 1. Apply this patch to your local cmake installation to fix a bug with .rc file handling: http://public.kitware.com/Bug/file_download.php?file_id=4062&type=bug 2. Install MXE (M cross environment) by 1. git clone -b master https://github.com/mxe/mxe.git 2. cd mxe 3. Apply the patch from below to src/curl.mk 4. make gcc llvm glibmm gtk2 ffmpeg cairo pango boost libxml++ glew freetype curl librtmp Note: You may want to add e.g. '-j4' to build four packages in parallel, or e.g. JOBS=3 to use three cpus per package. Note: This may ask you to install additional packages. Do so using the package manager of your distribution. For Ubuntu (oneiric), use 'apt-get install libtool yasm scons flex unzip wget') 5. cd .. 3. Build lightspark 1. mkdir mingw && cd mingw 2. cmake -DCMAKE_INSTALL_PREFIX=../mingw-build -DCMAKE_BUILD_TYPE=Debug -G'Unix Makefiles' -DCMAKE_TOOLCHAIN_FILE=../mxe/usr/i686-pc-mingw32/share/cmake/mxe-conf.cmake ../git 3. make package 4. cd .. 4. Run lightspark from 'mingw-build/lightspark' ------------------------------------------------------------------------------- --- a/src/curl.mk +++ b/src/curl.mk @@ -7,7 +7,7 @@ $(PKG)_CHECKSUM := f6016a24051d98806ca3ddf754592701cb66e00c $(PKG)_SUBDIR := curl-$($(PKG)_VERSION) $(PKG)_FILE := curl-$($(PKG)_VERSION).tar.bz2 $(PKG)_URL := http://curl.haxx.se/download/$($(PKG)_FILE) -$(PKG)_DEPS := gcc gnutls libidn libssh2 +$(PKG)_DEPS := gcc gnutls libssh2 define $(PKG)_UPDATE wget -q -O- 'http://curl.haxx.se/download/?C=M;O=D' | \ @@ -23,7 +23,7 @@ define $(PKG)_BUILD --disable-shared \ --prefix='$(PREFIX)/$(TARGET)' \ --with-gnutls \ - --with-libidn \ + --without-libidn \ --enable-sspi \ --with-libssh2 $(MAKE) -C '$(1)' -j '$(JOBS)' install lightspark-0.7.2/RELEASING000066400000000000000000000024731212105246600151310ustar00rootroot00000000000000Steps used to make a new release ================================= Here's what was used to release 0.5.2. In the future slight changes will be needed to adjust for the version numbers Make the tarball ------------------- Make sure all supported sites work and there are no regressions. When you consider the tree good to release and have the changelog updated go to a git checkout $cd lightspark Bump version in CMakeLists.txt and commit the change tag it $git tag lightspark-0.5.2 $git push --tags origin master make a tarball of it $git archive --format tar --prefix=lightspark-0.5.2/ lightspark-0.5.2 |gzip -9 >../lightspark-0.5.2.tar.gz sign the tarball for publishing on Launchpad $gpg --armor --sign --detach-sig lightspark-0.5.2.tar.gz Bump debian/changelog version as that is used by the daily Ubuntu package builds in Launchpad. $dch -i Upload to Launchpad -------------------- Currently only available to project managers (Alessandro and Jani). Create milestone and release in this interface, name both lightspark-0.5.2 https://launchpad.net/lightspark/trunk LP will prompt for descriptions, changelogs and uploads of .tar.gz and .asc files. Mark bugs from "Fix committed" to "Fix released" -------------------- See https://bugs.launchpad.net/lightspark/+bugs?field.searchtext=&field.status%3Alist=FIXCOMMITTED lightspark-0.7.2/TESTING000066400000000000000000000030351212105246600147300ustar00rootroot00000000000000Instuctions for working with the Lightspark testsuite Installing Flex ---------------- In order to build SWF files from ActionScript sources you need an AS3 compiler One comes with the Flex SDK and it is recommended you install it if you plan on running the tests and doing development. Get Flex 4.1 Update. http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4 Follow the installation instuctions within, then check whether it is installed correctly $mxmlc --version Version 4.1.0 build 16076 Installing the Adobe player --------------------------- In order to get a known good Flash player to compare results against and test SFW files with you can download the free as in beer Adobe player. http://www.adobe.com/support/flashplayer/downloads.html Download the Projector content debugger and unpack it somewhere in your $PATH. Check if it is installed by running $flashplayerdebugger --version 10,3,183,7 Running the Tamarin testsuite ----------------------------- cd tests One time setup and build of the tests hg clone http://hg.mozilla.org/tamarin-redux tamarin wget ftp://ftp.mozilla.org/pub/js/tamarin/builds/asc/latest/asc.jar ./make-tamarin Run the entire suite ./tests Run the entire suite using the Adobe player - everything should pass ./tests -p Running the testsuite can take a long time and each test pops up a temporary window. In order to run the suite headless and not steal focus from other applications run xvfb-run -s '-extension GLX' -a ./tests You need to have Xvfb installed (apt-get install xvfb or similar) lightspark-0.7.2/conf/000077500000000000000000000000001212105246600146145ustar00rootroot00000000000000lightspark-0.7.2/conf/CMakeASM-NASMCompiler.cmake000066400000000000000000000006571212105246600213760ustar00rootroot00000000000000# Find the nasm assembler SET(ASM_DIALECT "-NASM") SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT nasm) IF(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER) IF(WIN32) FIND_PROGRAM(CMAKE_ASM${ASM_DIALECT}_COMPILER nasmw) ELSE(WIN32) FIND_PROGRAM(CMAKE_ASM${ASM_DIALECT}_COMPILER nasm) ENDIF(WIN32) ENDIF(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER) INCLUDE(CMakeDetermineCompilerId) INCLUDE(CMakeDetermineASMCompiler) SET(ASM_DIALECT) lightspark-0.7.2/conf/CMakeASM-NASMInformation.cmake000066400000000000000000000015171212105246600221050ustar00rootroot00000000000000# support for the nasm assembler SET(ASM_DIALECT "-NASM") SET(CMAKE_ASM${ASM_DIALECT}_SOURCE_FILE_EXTENSIONS asm) if(WIN32) if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8) SET(CMAKE_ASM${ASM_DIALECT}_OBJECT_FORMAT win64) else() SET(CMAKE_ASM${ASM_DIALECT}_OBJECT_FORMAT win32) endif() elseif(APPLE) if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8) SET(CMAKE_ASM${ASM_DIALECT}_OBJECT_FORMAT macho64) else() SET(CMAKE_ASM${ASM_DIALECT}_OBJECT_FORMAT macho) endif() else() if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8) SET(CMAKE_ASM${ASM_DIALECT}_OBJECT_FORMAT elf64) else() SET(CMAKE_ASM${ASM_DIALECT}_OBJECT_FORMAT elf) endif() endif() SET(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT " -f ${CMAKE_ASM${ASM_DIALECT}_OBJECT_FORMAT} -o ") INCLUDE(CMakeASMInformation) SET(ASM_DIALECT) lightspark-0.7.2/conf/CMakeDetermineASM-NASMCompiler.cmake000066400000000000000000000004771212105246600232330ustar00rootroot00000000000000# Find the nasm assembler SET(ASM_DIALECT "_NASM") SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT nasm) IF(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER) FIND_PROGRAM(CMAKE_ASM${ASM_DIALECT}_COMPILER nasm "$ENV{ProgramFiles}/NASM") ENDIF(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER) INCLUDE(CMakeDetermineASMCompiler) SET(ASM_DIALECT) lightspark-0.7.2/conf/CMakeTestASM-NASMCompiler.cmake000066400000000000000000000005601212105246600222270ustar00rootroot00000000000000# This file is used by EnableLanguage in cmGlobalGenerator to # determine that the selected ASM_NASM "compiler" # can actually "compile" and link the most basic of programs. If not, a # fatal error is set and cmake stops processing commands and will not generate # any makefiles or projects. SET(ASM_DIALECT "-NASM") INCLUDE(CMakeTestASMCompiler) SET(ASM_DIALECT) lightspark-0.7.2/conf/FindFFMpeg.cmake000066400000000000000000000021371212105246600175260ustar00rootroot00000000000000# - Find libavcodec (FFMPEG) # Find the native FFMPEG headers and libraries. # Only grabs what Lightspark needs currently # # FFMPEG_INCLUDE_DIRS - where to find avcodec.h # FFMPEG_LIBRARIES - List of libraries when using ffmpeg # FFMPEG_FOUND - True if ffmpeg found. # Look for the header file. FIND_PATH(FFMPEG_INCLUDE_DIR NAMES libavcodec/avcodec.h PATH_SUFFIXES ffmpeg) MARK_AS_ADVANCED(FFMPEG_INCLUDE_DIR) # Look for the library. FIND_LIBRARY(FFMPEG_AVCODEC_LIBRARY NAMES avcodec ) FIND_LIBRARY(FFMPEG_AVUTIL_LIBRARY NAMES avutil ) FIND_LIBRARY(FFMPEG_AVFORMAT_LIBRARY NAMES avformat ) SET(FFMPEG_LIBRARY ${FFMPEG_AVCODEC_LIBRARY} ${FFMPEG_AVUTIL_LIBRARY} ${FFMPEG_AVFORMAT_LIBRARY}) MARK_AS_ADVANCED(FFMPEG_LIBRARY) # handle the QUIETLY and REQUIRED arguments and set FFMPEG_FOUND to TRUE if # all listed variables are TRUE INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(FFMPEG DEFAULT_MSG FFMPEG_LIBRARY FFMPEG_INCLUDE_DIR) IF(FFMPEG_FOUND) SET(FFMPEG_LIBRARIES ${FFMPEG_LIBRARY}) SET(FFMPEG_INCLUDE_DIRS ${FFMPEG_INCLUDE_DIR}) ENDIF(FFMPEG_FOUND) lightspark-0.7.2/conf/FindFreetype.cmake000066400000000000000000000064501212105246600202070ustar00rootroot00000000000000# - Locate FreeType library # This module defines # FREETYPE_LIBRARIES, the library to link against # FREETYPE_FOUND, if false, do not try to link to FREETYPE # FREETYPE_INCLUDE_DIRS, where to find headers. # This is the concatenation of the paths: # FREETYPE_INCLUDE_DIR_ft2build # FREETYPE_INCLUDE_DIR_freetype2 # # $FREETYPE_DIR is an environment variable that would # correspond to the ./configure --prefix=$FREETYPE_DIR # used in building FREETYPE. #============================================================================= # Copyright 2007-2009 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= # (To distributed this file outside of CMake, substitute the full # License text for the above reference.) # Created by Eric Wing. # Modifications by Alexander Neundorf. # This file has been renamed to "FindFreetype.cmake" instead of the correct # "FindFreeType.cmake" in order to be compatible with the one from KDE4, Alex. # Ugh, FreeType seems to use some #include trickery which # makes this harder than it should be. It looks like they # put ft2build.h in a common/easier-to-find location which # then contains a #include to a more specific header in a # more specific location (#include ). # Then from there, they need to set a bunch of #define's # so you can do something like: # #include FT_FREETYPE_H # Unfortunately, using CMake's mechanisms like INCLUDE_DIRECTORIES() # wants explicit full paths and this trickery doesn't work too well. # I'm going to attempt to cut out the middleman and hope # everything still works. FIND_PATH(FREETYPE_INCLUDE_DIR_ft2build ft2build.h HINTS $ENV{FREETYPE_DIR} PATH_SUFFIXES include PATHS /usr/local/X11R6/include /usr/local/X11/include /usr/X11/include /sw/include /opt/local/include /usr/freeware/include ) FIND_PATH(FREETYPE_INCLUDE_DIR_freetype2 freetype/config/ftheader.h HINTS $ENV{FREETYPE_DIR}/include/freetype2 PATHS /usr/local/X11R6/include /usr/local/X11/include /usr/X11/include /sw/include /opt/local/include /usr/freeware/include PATH_SUFFIXES freetype2 ) FIND_LIBRARY(FREETYPE_LIBRARY NAMES freetype libfreetype freetype219 freetype241MT_D HINTS $ENV{FREETYPE_DIR} PATH_SUFFIXES lib64 lib x86_64-linux-gnu i386-linux-gnu PATHS /usr/local/X11R6 /usr/local/X11 /usr/X11 /sw /usr/freeware ) # set the user variables IF(FREETYPE_INCLUDE_DIR_ft2build AND FREETYPE_INCLUDE_DIR_freetype2) SET(FREETYPE_INCLUDE_DIRS "${FREETYPE_INCLUDE_DIR_ft2build};${FREETYPE_INCLUDE_DIR_freetype2}") ENDIF(FREETYPE_INCLUDE_DIR_ft2build AND FREETYPE_INCLUDE_DIR_freetype2) SET(FREETYPE_LIBRARIES "${FREETYPE_LIBRARY}") # handle the QUIETLY and REQUIRED arguments and set FREETYPE_FOUND to TRUE if # all listed variables are TRUE INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(Freetype DEFAULT_MSG FREETYPE_LIBRARY FREETYPE_INCLUDE_DIRS) MARK_AS_ADVANCED(FREETYPE_LIBRARY FREETYPE_INCLUDE_DIR_freetype2 FREETYPE_INCLUDE_DIR_ft2build) lightspark-0.7.2/conf/FindGLEW.cmake000066400000000000000000000014131212105246600171540ustar00rootroot00000000000000# - Find GLEW # Find the native GLEW headers and libraries. # # GLEW_INCLUDE_DIRS - where to find glew.h, etc. # GLEW_LIBRARIES - List of libraries when using glews # GLEW_FOUND - True if glews found. # Look for the header file. FIND_PATH(GLEW_INCLUDE_DIR NAMES GL/glew.h) MARK_AS_ADVANCED(GLEW_INCLUDE_DIR) # Look for the library. FIND_LIBRARY(GLEW_LIBRARY NAMES GLEW glew32 ) MARK_AS_ADVANCED(GLEW_LIBRARY) # handle the QUIETLY and REQUIRED arguments and set GLEW_FOUND to TRUE if # all listed variables are TRUE INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLEW DEFAULT_MSG GLEW_LIBRARY GLEW_INCLUDE_DIR) IF(GLEW_FOUND) SET(GLEW_LIBRARIES ${GLEW_LIBRARY}) SET(GLEW_INCLUDE_DIRS ${GLEW_INCLUDE_DIR}) ENDIF(GLEW_FOUND) lightspark-0.7.2/conf/FindGettext.cmake000066400000000000000000000057551212105246600200570ustar00rootroot00000000000000# - Find GNU gettext tools # This module looks for the GNU gettext tools. This module defines the # following values: # GETTEXT_MSGMERGE_EXECUTABLE: the full path to the msgmerge tool. # GETTEXT_MSGFMT_EXECUTABLE: the full path to the msgfmt tool. # GETTEXT_FOUND: True if gettext has been found. # # Additionally it provides the following macros: # GETTEXT_CREATE_TRANSLATIONS ( outputFile [ALL] file1 ... fileN ) # This will create a target "translations" which will convert the # given input po files into the binary output mo file. If the # ALL option is used, the translations will also be created when # building the default target. #============================================================================= # Copyright 2007-2009 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= # (To distributed this file outside of CMake, substitute the full # License text for the above reference.) FIND_PROGRAM(GETTEXT_MSGMERGE_EXECUTABLE msgmerge) FIND_PROGRAM(GETTEXT_MSGFMT_EXECUTABLE msgfmt) MACRO(GETTEXT_CREATE_TRANSLATIONS _potFile _firstPoFileArg) # make it a real variable, so we can modify it here SET(_firstPoFile "${_firstPoFileArg}") SET(_gmoFiles) GET_FILENAME_COMPONENT(_potBasename ${_potFile} NAME_WE) GET_FILENAME_COMPONENT(_absPotFile ${_potFile} ABSOLUTE) SET(_addToAll) IF(${_firstPoFile} STREQUAL "ALL") SET(_addToAll "ALL") SET(_firstPoFile) ENDIF(${_firstPoFile} STREQUAL "ALL") FOREACH (_currentPoFile ${_firstPoFile} ${ARGN}) GET_FILENAME_COMPONENT(_absFile ${_currentPoFile} ABSOLUTE) GET_FILENAME_COMPONENT(_abs_PATH ${_absFile} PATH) GET_FILENAME_COMPONENT(_lang ${_absFile} NAME_WE) SET(_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_lang}.gmo) ADD_CUSTOM_COMMAND( OUTPUT ${_gmoFile} COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} --quiet --update --backup=none -s ${_absFile} ${_absPotFile} COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${_gmoFile} ${_absFile} DEPENDS ${_absPotFile} ${_absFile} ) INSTALL(FILES ${_gmoFile} DESTINATION ${DATADIR}/locale/${_lang}/LC_MESSAGES RENAME ${_potBasename}.mo) SET(_gmoFiles ${_gmoFiles} ${_gmoFile}) ENDFOREACH (_currentPoFile ) ADD_CUSTOM_TARGET(translations ${_addToAll} DEPENDS ${_gmoFiles}) ENDMACRO(GETTEXT_CREATE_TRANSLATIONS ) IF (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE ) SET(GETTEXT_FOUND TRUE) ELSE (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE ) SET(GETTEXT_FOUND FALSE) IF (GetText_REQUIRED) MESSAGE(FATAL_ERROR "GetText not found") ENDIF (GetText_REQUIRED) ENDIF (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE ) lightspark-0.7.2/conf/FindLLVM.cmake000066400000000000000000000206261212105246600171770ustar00rootroot00000000000000# Detect LLVM and set various variable to link against the different component of LLVM # # NOTE: This is a modified version of the module originally found in the OpenGTL project # at www.opengtl.org # # LLVM_BIN_DIR : directory with LLVM binaries # LLVM_LIB_DIR : directory with LLVM library # LLVM_INCLUDE_DIR : directory with LLVM include # # LLVM_COMPILE_FLAGS : compile flags needed to build a program using LLVM headers # LLVM_LDFLAGS : ldflags needed to link # LLVM_LIBS_CORE : ldflags needed to link against a LLVM core library # LLVM_LIBS_JIT : ldflags needed to link against a LLVM JIT # LLVM_LIBS_JIT_OBJECTS : objects you need to add to your source when using LLVM JIT if(WIN32) find_path(LLVM_INCLUDE_DIR NAMES llvm/LLVMContext.h) message(STATUS "Found LLVM include directory: ${LLVM_INCLUDE_DIR}") find_library(LLVM_SOMELIB NAMES LLVMCore) GET_FILENAME_COMPONENT(LLVM_LIB_DIR ${LLVM_SOMELIB} PATH CACHE) message(STATUS "Found LLVM lib directory: ${LLVM_LIB_DIR}") #Starting from 3.0, that file exists find_path(LLVM_3_0 NAMES llvm/Support/TargetSelect.h) if(LLVM_3_0) set(LLVM_STRING_VERSION "3.0") set(LLVM_LIBS_CORE LLVMLinker LLVMArchive LLVMBitWriter LLVMBitReader LLVMInstrumentation LLVMipo LLVMInstCombine) set(LLVM_LIBS_JIT LLVMX86AsmParser LLVMX86AsmPrinter LLVMX86CodeGen LLVMX86Desc LLVMSelectionDAG LLVMAsmPrinter LLVMX86Utils LLVMX86Info LLVMJIT LLVMExecutionEngine LLVMCodeGen LLVMScalarOpts LLVMTransformUtils LLVMipa LLVMAnalysis LLVMTarget LLVMMC LLVMCore LLVMSupport) else() set(LLVM_STRING_VERSION "2.8") set(LLVM_LIBS_CORE LLVMLinker LLVMArchive LLVMBitWriter LLVMBitReader LLVMInstrumentation LLVMScalarOpts LLVMipo LLVMTransformUtils LLVMipa LLVMAnalysis LLVMTarget LLVMMC LLVMCore LLVMSupport LLVMSystem LLVMInstCombine) set(LLVM_LIBS_JIT LLVMX86AsmParser LLVMX86AsmPrinter LLVMX86CodeGen LLVMSelectionDAG LLVMAsmPrinter LLVMX86Info LLVMJIT LLVMExecutionEngine LLVMCodeGen LLVMScalarOpts LLVMTransformUtils LLVMipa LLVMAnalysis LLVMTarget LLVMMC LLVMCore LLVMSupport LLVMSystem) endif() message(STATUS "_Guessed_ LLVM version ${LLVM_STRING_VERSION}") set(LLVM_COMPILE_FLAGS "") set(LLVM_LDFLAGS "") set(LLVM_LIBS_JIT_OBJECTS "") endif (WIN32) if (LLVM_INCLUDE_DIR) set(LLVM_FOUND TRUE) else (LLVM_INCLUDE_DIR) find_program(LLVM_CONFIG_EXECUTABLE NAMES llvm-config PATHS /opt/local/bin /opt/llvm/2.7/bin /opt/llvm/bin /usr/lib/llvm-2.7/bin /usr/lib/llvm-2.8/bin /usr/lib/llvm-2.9/bin /usr/lib/llvm-3.0/bin ) find_program(LLVM_GCC_EXECUTABLE NAMES llvm-gcc llvmgcc PATHS /opt/local/bin /opt/llvm/2.7/bin /opt/llvm/bin /Developer/usr/bin /usr/lib/llvm-2.7/bin ) find_program(LLVM_GXX_EXECUTABLE NAMES llvm-g++ llvmg++ PATHS /opt/local/bin /opt/llvm/2.7/bin /opt/llvm/bin /Developer/usr/bin /usr/lib/llvm/llvm/gcc-4.2/bin /usr/lib/llvm-2.7/bin ) if(LLVM_GCC_EXECUTABLE) MESSAGE(STATUS "LLVM llvm-gcc found at: ${LLVM_GCC_EXECUTABLE}") #CMAKE_FORCE_C_COMPILER(${LLVM_GCC_EXECUTABLE} GNU) endif(LLVM_GCC_EXECUTABLE) if(LLVM_GXX_EXECUTABLE) MESSAGE(STATUS "LLVM llvm-g++ found at: ${LLVM_GXX_EXECUTABLE}") #CMAKE_FORCE_CXX_COMPILER(${LLVM_GXX_EXECUTABLE} GNU) endif(LLVM_GXX_EXECUTABLE) if(LLVM_CONFIG_EXECUTABLE) MESSAGE(STATUS "LLVM llvm-config found at: ${LLVM_CONFIG_EXECUTABLE}") else(LLVM_CONFIG_EXECUTABLE) MESSAGE(FATAL_ERROR "Could NOT find LLVM executable") endif(LLVM_CONFIG_EXECUTABLE) MACRO(FIND_LLVM_LIBS LLVM_CONFIG_EXECUTABLE _libname_ LIB_VAR OBJECT_VAR) exec_program( ${LLVM_CONFIG_EXECUTABLE} ARGS --libs ${_libname_} OUTPUT_VARIABLE ${LIB_VAR} ) STRING(REGEX MATCHALL "[^ ]*[.]o[ $]" ${OBJECT_VAR} ${${LIB_VAR}}) SEPARATE_ARGUMENTS(${OBJECT_VAR}) STRING(REGEX REPLACE "[^ ]*[.]o[ $]" "" ${LIB_VAR} ${${LIB_VAR}}) SEPARATE_ARGUMENTS(${LIB_VAR}) ENDMACRO(FIND_LLVM_LIBS) # this function borrowed from PlPlot, Copyright (C) 2006 Alan W. Irwin function(TRANSFORM_VERSION numerical_result version) # internal_version ignores everything in version after any character that # is not 0-9 or ".". This should take care of the case when there is # some non-numerical data in the patch version. #message(STATUS "DEBUG: version = ${version}") string(REGEX REPLACE "^([0-9.]+).*$" "\\1" internal_version ${version}) # internal_version is normally a period-delimited triplet string of the form # "major.minor.patch", but patch and/or minor could be missing. # Transform internal_version into a numerical result that can be compared. string(REGEX REPLACE "^([0-9]*).+$" "\\1" major ${internal_version}) string(REGEX REPLACE "^[0-9]*\\.([0-9]*).*$" "\\1" minor ${internal_version}) #string(REGEX REPLACE "^[0-9]*\\.[0-9]*\\.([0-9]*)$" "\\1" patch ${internal_version}) #if(NOT patch MATCHES "[0-9]+") # set(patch 0) #endif(NOT patch MATCHES "[0-9]+") set(patch 0) if(NOT minor MATCHES "[0-9]+") set(minor 0) endif(NOT minor MATCHES "[0-9]+") if(NOT major MATCHES "[0-9]+") set(major 0) endif(NOT major MATCHES "[0-9]+") #message(STATUS "DEBUG: internal_version = ${internal_version}") #message(STATUS "DEBUG: major = ${major}") #message(STATUS "DEBUG: minor= ${minor}") #message(STATUS "DEBUG: patch = ${patch}") math(EXPR internal_numerical_result #"${major}*1000000 + ${minor}*1000 + ${patch}" "${major}*1000000 + ${minor}*1000" ) #message(STATUS "DEBUG: ${numerical_result} = ${internal_numerical_result}") set(${numerical_result} ${internal_numerical_result} PARENT_SCOPE) endfunction(TRANSFORM_VERSION) exec_program(${LLVM_CONFIG_EXECUTABLE} ARGS --version OUTPUT_VARIABLE LLVM_STRING_VERSION ) MESSAGE(STATUS "LLVM version: " ${LLVM_STRING_VERSION}) transform_version(LLVM_VERSION ${LLVM_STRING_VERSION}) exec_program(${LLVM_CONFIG_EXECUTABLE} ARGS --bindir OUTPUT_VARIABLE LLVM_BIN_DIR ) exec_program(${LLVM_CONFIG_EXECUTABLE} ARGS --libdir OUTPUT_VARIABLE LLVM_LIB_DIR ) #MESSAGE(STATUS "LLVM lib dir: " ${LLVM_LIB_DIR}) exec_program(${LLVM_CONFIG_EXECUTABLE} ARGS --includedir OUTPUT_VARIABLE LLVM_INCLUDE_DIR ) INCLUDE(CheckIncludeFileCXX) set(CMAKE_REQUIRED_INCLUDES ${LLVM_INCLUDE_DIR}) check_include_file_cxx("llvm/Support/TargetSelect.h" HAVE_SUPPORT_TARGETSELECT_H) unset(CMAKE_REQUIRED_INCLUDES) MESSAGE(STATUS "HAVE_SUPPORT_TARGETSELECT_H: " ${HAVE_SUPPORT_TARGETSELECT_H}) IF(HAVE_SUPPORT_TARGETSELECT_H) ADD_DEFINITIONS(-DHAVE_SUPPORT_TARGETSELECT_H) ENDIF(HAVE_SUPPORT_TARGETSELECT_H) set(CMAKE_REQUIRED_INCLUDES ${LLVM_INCLUDE_DIR}) set(CMAKE_REQUIRED_DEFINITIONS -D__STDC_LIMIT_MACROS=1 -D__STDC_CONSTANT_MACROS=1) check_include_file_cxx("llvm/IRBuilder.h" HAVE_IRBUILDER_H) unset(CMAKE_REQUIRED_INCLUDES) MESSAGE(STATUS "HAVE_IRBUILDER_H: " ${HAVE_IRBUILDER_H}) IF(HAVE_IRBUILDER_H) ADD_DEFINITIONS(-DHAVE_IRBUILDER_H) ENDIF(HAVE_IRBUILDER_H) set(CMAKE_REQUIRED_INCLUDES ${LLVM_INCLUDE_DIR}) check_include_file_cxx("llvm/DataLayout.h" HAVE_DATALAYOUT_H) unset(CMAKE_REQUIRED_INCLUDES) MESSAGE(STATUS "HAVE_DATALAYOUT_H: " ${HAVE_DATALAYOUT_H}) IF(HAVE_DATALAYOUT_H) ADD_DEFINITIONS(-DHAVE_DATALAYOUT_H) ENDIF(HAVE_DATALAYOUT_H) exec_program(${LLVM_CONFIG_EXECUTABLE} ARGS --cxxflags OUTPUT_VARIABLE LLVM_COMPILE_FLAGS ) MESSAGE(STATUS "LLVM CXX flags: " ${LLVM_COMPILE_FLAGS}) exec_program(${LLVM_CONFIG_EXECUTABLE} ARGS --ldflags OUTPUT_VARIABLE LLVM_LDFLAGS ) MESSAGE(STATUS "LLVM LD flags: " ${LLVM_LDFLAGS}) FIND_LLVM_LIBS( ${LLVM_CONFIG_EXECUTABLE} "core ipa ipo instrumentation bitreader bitwriter linker" LLVM_LIBS_CORE LLVM_LIBS_CORE_OBJECTS ) MESSAGE(STATUS "LLVM core libs: " ${LLVM_LIBS_CORE}) IF(APPLE AND UNIVERSAL) FIND_LLVM_LIBS( ${LLVM_CONFIG_EXECUTABLE} "jit native x86 PowerPC ARM" LLVM_LIBS_JIT LLVM_LIBS_JIT_OBJECTS ) ELSE(APPLE AND UNIVERSAL) FIND_LLVM_LIBS( ${LLVM_CONFIG_EXECUTABLE} "jit native" LLVM_LIBS_JIT LLVM_LIBS_JIT_OBJECTS ) ENDIF(APPLE AND UNIVERSAL) MESSAGE(STATUS "LLVM JIT libs: " ${LLVM_LIBS_JIT}) MESSAGE(STATUS "LLVM JIT objs: " ${LLVM_LIBS_JIT_OBJECTS}) if(LLVM_INCLUDE_DIR) set(LLVM_FOUND TRUE) endif(LLVM_INCLUDE_DIR) if(LLVM_FOUND) message(STATUS "Found LLVM: ${LLVM_INCLUDE_DIR}") else(LLVM_FOUND) if(LLVM_FIND_REQUIRED) message(FATAL_ERROR "Could NOT find LLVM") endif(LLVM_FIND_REQUIRED) endif(LLVM_FOUND) endif (LLVM_INCLUDE_DIR) lightspark-0.7.2/conf/FindPCRE.cmake000066400000000000000000000015261212105246600171540ustar00rootroot00000000000000# - Find PCRE # Find the native PCRE headers and libraries. # # PCRE_INCLUDE_DIRS - where to find pcre.h, etc. # PCRE_LIBRARIES - List of libraries when using pcrecpp # PCRE_FOUND - True if pcrecpp found. # Look for the header file. FIND_PATH(PCRE_INCLUDE_DIR NAMES pcre.h) MARK_AS_ADVANCED(PCRE_INCLUDE_DIR) # Look for the library. FIND_LIBRARY(PCRE_LIBRARY NAMES pcre pcred PATH_SUFFIXES lib64 lib x86_64-linux-gnu i386-linux-gnu ) MARK_AS_ADVANCED(PCRE_LIBRARY) # handle the QUIETLY and REQUIRED arguments and set PCRECPP_FOUND to TRUE if # all listed variables are TRUE INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE DEFAULT_MSG PCRE_LIBRARY PCRE_INCLUDE_DIR PCRE_LIBRARY) IF(PCRE_FOUND) SET(PCRE_LIBRARIES ${PCRE_LIBRARY}) SET(PCRE_INCLUDE_DIRS ${PCRE_INCLUDE_DIR}) ENDIF(PCRE_FOUND) lightspark-0.7.2/conf/FindWin32Stdint.cmake000066400000000000000000000010621212105246600205060ustar00rootroot00000000000000# - Find stdint # Find the win32 stdint headers # # STDINT_INCLUDE_DIRS - where to find stdint # STDINT_FOUND - True if glews found. # Look for the header file. FIND_PATH(STDINT_INCLUDE_DIR NAMES stdint.h) MARK_AS_ADVANCED(STDINT_INCLUDE_DIR) # handle the QUIETLY and REQUIRED arguments and set STDINT_FOUND to TRUE if # all listed variables are TRUE INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(STDINT DEFAULT_MSG STDINT_INCLUDE_DIR) IF(STDINT_FOUND) SET(STDINT_INCLUDE_DIRS ${STDINT_INCLUDE_DIR}) ENDIF(STDINT_FOUND) lightspark-0.7.2/conf/Pack.cmake000066400000000000000000000021441212105246600164750ustar00rootroot00000000000000IF(${CMAKE_BUILD_TYPE} MATCHES "Release" AND MINGW) INCLUDE(FindSelfPackers) IF(SELF_PACKER_FOR_EXECUTABLE) message(STATUS "Found ${SELF_PACKER_FOR_EXECUTABLE}, using it for compression") ELSE() message(WARNING "Did not find 'upx', binaries will not be packed") ENDIF() MACRO(PACK_EXECUTABLE _target) GET_TARGET_PROPERTY(_filename _target LOCATION) IF(SELF_PACKER_FOR_EXECUTABLE) GET_TARGET_PROPERTY(_filename ${_target} LOCATION) ADD_CUSTOM_COMMAND(TARGET ${_target} POST_BUILD COMMAND ${SELF_PACKER_FOR_EXECUTABLE} ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} ${_filename} VERBATIM) ENDIF() ENDMACRO() MACRO(PACK_LIBRARY _target) IF(SELF_PACKER_FOR_SHARED_LIB) GET_TARGET_PROPERTY(_filename ${_target} LOCATION) ADD_CUSTOM_COMMAND(TARGET ${_target} POST_BUILD COMMAND ${SELF_PACKER_FOR_SHARED_LIB} ${SELF_PACKER_FOR_SHARED_LIB_FLAGS} ${_filename} VERBATIM) ENDIF() ENDMACRO() ELSE(${CMAKE_BUILD_TYPE} MATCHES "Release") #Do not pack when build type is not Release MACRO(PACK_EXECUTABLE _target) ENDMACRO() MACRO(PACK_LIBRARY _target) ENDMACRO() ENDIF() lightspark-0.7.2/debian/000077500000000000000000000000001212105246600151115ustar00rootroot00000000000000lightspark-0.7.2/debian/README.Debian000066400000000000000000000000001212105246600171400ustar00rootroot00000000000000lightspark-0.7.2/debian/TODO.Debian000066400000000000000000000001511212105246600167570ustar00rootroot00000000000000Debian package TODO list: - Add Provide/Replace/Conflict: swf-player ? - see swfdec shlibs.local lightspark-0.7.2/debian/browser-plugin-lightspark.install000066400000000000000000000000571212105246600236300ustar00rootroot00000000000000usr/lib/mozilla/plugins/liblightsparkplugin.so lightspark-0.7.2/debian/changelog000066400000000000000000000176561212105246600170020ustar00rootroot00000000000000lightspark (0.7.2-0ubuntu1~ppa1) quantal; urgency=low * New release -- Antti Ajanki Sat, 16 Mar 2013 13:14:14 +0200 lightspark (0.7.1-0ubuntu1~ppa1) quantal; urgency=low * New release -- Alessandro Pignotti Sun, 23 Dec 2012 00:38:19 +0100 lightspark (0.7.0-0ubuntu1~ppa1) quantal; urgency=low * New release -- Alessandro Pignotti Sat, 27 Oct 2012 17:57:52 +0200 lightspark (0.6.0.1-0ubuntu1~ppa1) precise; urgency=low * New release -- Alessandro Pignotti Sun, 10 Jun 2012 11:29:30 +0200 lightspark (0.5.7-0ubuntu1~ppa2) precise; urgency=low * Fix email -- Alessandro Pignotti Wed, 16 May 2012 13:09:05 +0200 lightspark (0.5.7-0ubuntu1~ppa1) precise; urgency=low * New release -- Alessandro Pignotti Tue, 15 May 2012 23:48:53 +0200 lightspark (0.5.6-0ubuntu1~ppa1) oneiric; urgency=low * New release -- Alessandro Pignotti Wed, 11 Apr 2012 23:01:24 +0200 lightspark (0.5.5-0ubuntu1~ppa1) oneiric; urgency=low * New release -- Alessandro Pignotti Sun, 11 Mar 2012 16:20:12 +0100 lightspark (0.5.4.1-0ubuntu1~ppa1) precise; urgency=low * New release -- Jani Monoses Thu, 02 Feb 2012 10:59:03 +0200 lightspark (0.5.4-0ubuntu1~ppa1) precise; urgency=low * New release -- Jani Monoses Tue, 24 Jan 2012 23:45:26 +0200 lightspark (0.5.3-0ubuntu1~ppa2) precise; urgency=low * New release -- Jani Monoses Thu, 01 Dec 2011 15:42:15 +0200 lightspark (0.5.2.1-0ubuntu1~ppa1) oneiric; urgency=low * New release -- Jani Monoses Fri, 28 Oct 2011 17:18:53 +0300 lightspark (0.5.1-0ubuntu1~ppa1) oneiric; urgency=low * New release -- Jani Monoses Wed, 21 Sep 2011 11:56:46 +0300 lightspark (0.5.0-0ubuntu1~ppa) natty; urgency=low * New release -- Alessandro Pignotti Sat, 02 Jul 2011 15:52:43 +0200 lightspark (0.4.8-0ubuntu1~ppa) natty; urgency=low * New release -- Alessandro Pignotti Sat, 21 May 2011 20:00:52 +0200 lightspark (0.4.7.1-0ubuntu1~ppa) natty; urgency=low * Bugfix release -- Alessandro Pignotti Thu, 05 May 2011 00:24:45 +0200 lightspark (0.4.7-0ubuntu1~ppa) natty; urgency=low * New release -- Alessandro Pignotti Thu, 28 Apr 2011 04:03:06 +0200 lightspark (0.4.6.1-0ubuntu0) maverick; urgency=low * Bugfix release -- Alessandro Pignotti Fri, 18 Mar 2011 04:21:46 +0100 lightspark (0.4.6-0ubuntu1) maverick; urgency=low * New release -- Alessandro Pignotti Sun, 13 Mar 2011 16:08:31 +0100 lightspark (0.4.5.3-0ubuntu1) maverick; urgency=low * Bugfix release -- Alessandro Pignotti Sat, 19 Feb 2011 04:30:02 +0100 lightspark (0.4.5.2-0ubuntu1) maverick; urgency=low * Bugfix release -- Timon Van Overveldt Fri, 04 Feb 2011 00:41:00 +0100 lightspark (0.4.5.1-0ubuntu1) maverick; urgency=low * Bugfix release -- Alessandro Pignotti Thu, 16 Dec 2010 06:27:39 +0100 lightspark (0.4.5-0ubuntu1) maverick; urgency=low * New release -- Alessandro Pignotti Wed, 08 Dec 2010 17:55:25 +0100 lightspark (0.4.5~rc1-0ubuntu1) lucid; urgency=low * New release candidate -- Alessandro Pignotti Thu, 25 Nov 2010 18:11:49 +0100 lightspark (0.4.4.3-0ubuntu1) lucid; urgency=low * Bugfix release -- Alessandro Pignotti Thu, 23 Sep 2010 23:24:46 +0200 lightspark (0.4.4.2-0ubuntu1) lucid; urgency=low * Bugfix release -- Alessandro Pignotti Sat, 11 Sep 2010 14:52:03 +0200 lightspark (0.4.4.1-0ubuntu1) lucid; urgency=low * Bugfix release -- Alessandro Pignotti Thu, 02 Sep 2010 14:58:38 +0200 lightspark (0.4.4-0ubuntu1) lucid; urgency=low * New release -- Alessandro Pignotti Sun, 29 Aug 2010 13:39:39 +0200 lightspark (0.4.3-0ubuntu1) lucid; urgency=low * New release -- Alessandro Pignotti Tue, 10 Aug 2010 13:13:08 +0200 lightspark (0.4.3~rc1-0ubuntu1) lucid; urgency=low * New release candidate -- Alessandro Pignotti Sun, 08 Aug 2010 19:30:11 +0200 lightspark (0.4.2.3-0ubuntu1) lucid; urgency=low * New point release -- Alessandro Pignotti Wed, 04 Aug 2010 19:13:32 +0200 lightspark (0.4.2.2-0ubuntu1) lucid; urgency=low * New point release -- Alessandro Pignotti Tue, 27 Jul 2010 04:54:57 +0200 lightspark (0.4.2.1-0ubuntu1) lucid; urgency=low * Small bugfix release -- Alessandro Pignotti Sat, 24 Jul 2010 00:35:58 +0200 lightspark (0.4.2-0ubuntu1) lucid; urgency=low * New release -- Alessandro Pignotti Tue, 20 Jul 2010 04:14:06 +0200 lightspark (0.4.2~rc3-0ubuntu1) lucid; urgency=low * New release candidate -- Alessandro Pignotti Fri, 16 Jul 2010 22:24:42 +0200 lightspark (0.4.2~rc2-0ubuntu1) lucid; urgency=low * New release candidate -- Alessandro Pignotti Sat, 03 Jul 2010 23:56:37 +0200 lightspark (0.4.2~rc1-0ubuntu1) lucid; urgency=low * New release candidate -- Alessandro Pignotti Thu, 01 Jul 2010 03:20:36 +0200 lightspark (0.4.1-0ubuntu1) lucid; urgency=low * New release -- Alessandro Pignotti Sat, 05 Jun 2010 03:13:43 +0200 lightspark (0.4.0~rc3-0ubuntu1) lucid; urgency=low * New release -- Alessandro Pignotti Sat, 29 May 2010 19:16:49 +0200 lightspark (0.4.0~rc2-0ubuntu1) lucid; urgency=low * New release -- Alessandro Pignotti Sat, 29 May 2010 04:06:21 +0200 lightspark (0.4.0~rc1-ubuntu1) lucid; urgency=low * New release -- Alessandro Pignotti Fri, 28 May 2010 06:23:06 +0200 lightspark (0.3.9-ubuntu1) lucid; urgency=low * New release -- Alessandro Pignotti Mon, 24 May 2010 13:14:46 +0200 lightspark (0.3.8-ubuntu1) lucid; urgency=low * New release -- Alessandro Pignotti Sun, 23 May 2010 01:16:32 +0200 lightspark (0.3.7-ubuntu1) lucid; urgency=low * New release -- Alessandro Pignotti Fri, 21 May 2010 23:12:25 +0200 lightspark (0.3.6-ubuntu1) lucid; urgency=low * New release -- Alessandro Pignotti Thu, 20 May 2010 23:42:28 +0200 lightspark (0.3.5-ubuntu1) lucid; urgency=low * A fix in SWF parsing * Show debug message also in standalone version -- Alessandro Pignotti Thu, 20 May 2010 02:02:18 +0200 lightspark (0.3.4-ubuntu1) lucid; urgency=low * Fixed a bug triggered by compiler optimizations -- Alessandro Pignotti Wed, 19 May 2010 19:33:43 +0200 lightspark (0.3.3-ubuntu1) lucid; urgency=low * Enable assertions in release builds -- Alessandro Pignotti Wed, 19 May 2010 05:26:49 +0200 lightspark (0.3.2-ubuntu1) lucid; urgency=low * Enable debug output in release -- Alessandro Pignotti Tue, 18 May 2010 21:25:44 +0200 lightspark (0.3.1-ubuntu3) lucid; urgency=low * Beta release * Improved robustness * Apply filtering to video -- Alessandro Pignotti Tue, 18 May 2010 01:37:37 +0200 lightspark (0.2.1-ubuntu1) lucid; urgency=low * Mouse input support * Better tesselation * Plugin packaged -- Alessandro Pignotti Tue, 27 Apr 2010 17:31:03 +0200 lightspark (0.2.0-ubuntu1) lucid; urgency=low * Youtube support -- Alessandro Pignotti Tue, 20 Apr 2010 17:15:05 +0200 lightspark (0.techdemo2) unstable; urgency=low * Initial Release. -- Jacopo Corbetta Sat, 27 Jun 2009 19:20:39 +0200 lightspark-0.7.2/debian/common.shlibs000066400000000000000000000000721212105246600176060ustar00rootroot00000000000000liblightspark 0.7 lightspark-common (= ${binary:Version}) lightspark-0.7.2/debian/compat000066400000000000000000000000021212105246600163070ustar00rootroot000000000000007 lightspark-0.7.2/debian/control000066400000000000000000000103711212105246600165160ustar00rootroot00000000000000Source: lightspark Section: utils Priority: optional Maintainer: Alessandro Pignotti Build-Depends: g++ (>=4.5), gnash, cmake, cdbs, nasm, debhelper (>= 7), llvm-3.0-dev, libgl1-mesa-dev, libxext-dev, libcurl4-gnutls-dev | libcurl4-openssl-dev, libxml2-dev, zlib1g-dev, libavcodec-dev, libpcre3-dev, libglew1.5-dev, libboost-filesystem-dev, libboost-system-dev, libxml++2.6-dev (>= 2.33.1), libcairo2-dev, libgtk2.0-dev, libjpeg8-dev, libavformat-dev, libpango1.0-dev, libpulse-dev, librtmp-dev, liblzma-dev Standards-Version: 3.8.4 Homepage: http://lightspark.sf.net Vcs-git: git://github.com/alexp-sssup/lightspark.git Vcs-Browser: http://github.com/alexp-sssup/lightspark Package: lightspark Architecture: i386 amd64 Depends: ${shlibs:Depends}, ${misc:Depends} Description: Experimental high-performance SWF (Adobe Flash) player Lightspark is a free Flash player for Linux which aims for high-performance by using modern technologies such as JIT compilation and OpenGL shaders. . The project is currently in an beta status, users are invited to test lightspark and report any issue . Nice features: * JIT compilation of ActionScript to native x86 bytecode * Hardware accelerated rendering using OpenGL shaders (GLSL) * Aims to support current-generation ActionScript 3 * A new, clean, codebase exploiting multithreading and optimized for modern hardware. Designed from scratch after the official Flash documentation was released. Package: lightspark-common Architecture: i386 amd64 Depends: ${shlibs:Depends}, ${misc:Depends} Description: Experimental high-performance SWF (Adobe Flash) player Lightspark is a free Flash player for Linux which aims for high-performance by using modern technologies such as JIT compilation and OpenGL shaders. . The project is currently in an beta status, users are invited to test lightspark and report any issue . Nice features: * JIT compilation of ActionScript to native x86 bytecode * Hardware accelerated rendering using OpenGL shaders (GLSL) * Aims to support current-generation ActionScript 3 * A new, clean, codebase exploiting multithreading and optimized for modern hardware. Designed from scratch after the official Flash documentation was released. . Common library and data Package: browser-plugin-lightspark Architecture: i386 amd64 Xb-Npp-Applications: ec8030f7-c20a-464f-9b0e-13a3a9e97384 Xb-Npp-MimeType: application/x-shockwave-flash Xb-Npp-Name: Lightspark SWF Player Xb-Npp-Description: High performance SWF Player Xb-Npp-File: liblightsparkplugin.so Depends: ${shlibs:Depends}, ${misc:Depends} Recommends: gnash Description: Experimental high-performance SWF (Adobe Flash) player Lightspark is a free Flash player for Linux which aims for high-performance by using modern technologies such as JIT compilation and OpenGL shaders. . The project is currently in an beta status, users are invited to test lightspark and report any issue . Nice features: * JIT compilation of ActionScript to native x86 bytecode * Hardware accelerated rendering using OpenGL shaders (GLSL) * Aims to support current-generation ActionScript 3 * A new, clean, codebase exploiting multithreading and optimized for modern hardware. Designed from scratch after the official Flash documentation was released. . Mozilla plugin package Package: lightspark-dbg Section: debug Priority: extra Architecture: i386 amd64 Depends: ${shlibs:Depends}, ${misc:Depends}, lightspark (= ${binary:Version}) | browser-plugin-lightspark (= ${binary:Version}) | lightspark-common (= ${binary:Version}) Description: High-performance SWF player (experimental) - Debug symbols Lightspark is a free Flash player for Linux which aims for high-performance by using modern technologies such as JIT compilation and OpenGL shaders. . The project is currently in an beta status, users are invited to test lightspark and report any issue . Nice features: * JIT compilation of ActionScript to native x86 bytecode * Hardware accelerated rendering using OpenGL shaders (GLSL) * Aims to support current-generation ActionScript 3 * A new, clean, codebase exploiting multithreading and optimized for modern hardware. Designed from scratch after the official Flash documentation was released. . This package contains the debug symbols. lightspark-0.7.2/debian/copyright000066400000000000000000000020061212105246600170420ustar00rootroot00000000000000Name: Lightspark Maintainer: Alessandro Pignotti Source: git://github.com/alexp-sssup/lightspark.git Copyright: 2009-2013, Alessandro Pignotti License: LGPL-3+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. . This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. . You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . . On Debian systems, the complete text of the GNU Lesser General Public License version 3 can be found in `/usr/share/common-licenses/LGPL-3'. lightspark-0.7.2/debian/docs000066400000000000000000000000071212105246600157610ustar00rootroot00000000000000README lightspark-0.7.2/debian/lightspark-common.install000066400000000000000000000001271212105246600221370ustar00rootroot00000000000000usr/share/lightspark/ usr/lib/lightspark/liblightspark.so* usr/lib/lightspark/plugins/ lightspark-0.7.2/debian/lightspark.install000066400000000000000000000000261212105246600206470ustar00rootroot00000000000000usr/bin usr/share/man lightspark-0.7.2/debian/lightspark.manpages000066400000000000000000000000271212105246600207750ustar00rootroot00000000000000docs/man/lightspark.1 lightspark-0.7.2/debian/rules000077500000000000000000000011771212105246600161770ustar00rootroot00000000000000#!/usr/bin/make -f %: dh --parallel $@ override_dh_auto_configure: dh_auto_configure -- \ -DCOMPILE_PLUGIN=1 \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr override_dh_strip: dh_strip --dbg-package=lightspark-dbg override_dh_install: dh_install --list-missing override_dh_shlibdeps: export LD_LIBRARY_PATH="$(CURDIR)/debian/lightspark-common/usr/lib/lightspark:$$LD_LIBRARY_PATH" ; \ dh_shlibdeps -Llightspark-common \ -pbrowser-plugin-lightspark -plightspark \ -- -Ldebian/common.shlibs dh_shlibdeps --remaining-packages override_dh_makeshlibs: dh_makeshlibs -X/usr/lib/lightspark lightspark-0.7.2/debian/watch000066400000000000000000000000751212105246600161440ustar00rootroot00000000000000version=3 http://sf.net/lightspark/lightspark-(.*)\.tar\.bz2 lightspark-0.7.2/docs/000077500000000000000000000000001212105246600146175ustar00rootroot00000000000000lightspark-0.7.2/docs/man/000077500000000000000000000000001212105246600153725ustar00rootroot00000000000000lightspark-0.7.2/docs/man/lightspark.1000066400000000000000000000047061212105246600176330ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH LIGHTSPARK 1 "May 29, 2010" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME lightspark \- a free Flash player .SH SYNOPSIS .B lightspark [\-\-url|\-u http://loader.url/file.swf] [\-\-disable-interpreter|\-ni] [\-\-enable\-jit|\-j] [\-\-log\-level|\-l 0-4] [\-\-parameters\-file|\-p params-file] [\-\-version|\-v] file.swf .SH DESCRIPTION .B Lightspark is a free, modern Flash Player implementation, this documents the options accepted by the standalone version of the program. .PP .\" TeX users may be more comfortable with the \fB\fP and .\" \fI\fP escape sequences to invode bold face and italics, .\" respectively. The player is currently in Beta, support for any particular SWF file is not guaranteed .PP You might wish to see the project website at http://lightspark.sf.net or our technical blog at http://allievi.sssup.it/techblog .SH OPTIONS .HP \fB\-\-url\fP loader.url/file.swf, \fB\-u\fP loader.url/file.swf .IP Pretends to be loading the file from an url .HP \fB\-\-disable-interpreter\fP, \fB\-ni\fP .IP Disable the ActionScript interpreter .HP \fB\-\-enable-jit\fP, \fB\-j\fP .IP Enable the ActionScript JIT compilation engine .HP \fB\-\-log-level\fP 0-4, \fB\-l\fP 0-4 .IP Sets the verbosity of the output, the default is 2 .HP \fB\-\-parameters-file\fP params-file, \fB\-p\fP params-file .IP Load flash parameters from file. Every odd line will be interpreted as a parameter name, with the following one as the value. .HP \fB\-\-profiling-output\fP profiling-file, \fB\-o\fP profiling-file .IP Output profiling data to profiling-file in a callgrind/KCachegrind compatible format .HP \fB\-\-version\fP, \fB\-v\fP .IP Shows lightspark version and exits. .SH AUTHOR lightspark was written by Alessandro Pignotti. .PP This manual page was written by Jacopo Corbetta , for the Debian project (and may be used by others). lightspark-0.7.2/etc/000077500000000000000000000000001212105246600144425ustar00rootroot00000000000000lightspark-0.7.2/etc/xdg/000077500000000000000000000000001212105246600152245ustar00rootroot00000000000000lightspark-0.7.2/etc/xdg/lightspark.conf000066400000000000000000000005301212105246600202410ustar00rootroot00000000000000# Commented lines start with '#' # All values are case-sensitive # Non-existing entries default to their hard-coded default values [audio] # Audio backend to use, possible values: pulseaudio, sdl backend = pulseaudio [cache] # Directory where cached files are saved to directory = ~/.cache/lightspark # Prefix for cached files prefix = cache lightspark-0.7.2/i18n/000077500000000000000000000000001212105246600144465ustar00rootroot00000000000000lightspark-0.7.2/i18n/extract_translatable_strings.sh000066400000000000000000000001361212105246600227610ustar00rootroot00000000000000#!/bin/sh xgettext -k_ -d lightspark -s -o lightspark.pot ../*.cpp ../*/*.cpp ../*.h ../*/*.h lightspark-0.7.2/i18n/fr.po000066400000000000000000001666271212105246600154370ustar00rootroot00000000000000# French translations for Lightspark package # # Copyright (C) 2010 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Emmanuel Andry , 2010. # msgid "" msgstr "" "Project-Id-Version: Lightspark\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2010-08-24 23:48-0500\n" "PO-Revision-Date: 2010-08-22 17:26+0100\n" "Last-Translator: Emmanuel Andry \n" "Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: teplain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: French\n" "X-Poedit-Country: FRANCE\n" #: ../scripting/abc.cpp:925 msgid "\t" msgstr "\t" #: ../scripting/abc.cpp:913 msgid "\tFinal" msgstr "\tFinal" #: ../scripting/abc.cpp:915 msgid "\tInterface" msgstr "\tInterface" #: ../scripting/abc.cpp:917 msgid "\tProtectedNS " msgstr "" #: ../scripting/abc.cpp:911 msgid "\tSealed" msgstr "\tScellé" #: ../asobject.cpp:704 ../scripting/abc_codesynt.cpp:789 #: ../scripting/abc_codesynt.cpp:2253 ../scripting/abc.cpp:1513 #: ../scripting/abc.cpp:1786 ../scripting/abc_opcodes.cpp:1888 msgid " " msgstr " " #: ../scripting/abc.cpp:1418 ../scripting/abc.cpp:1480 #: ../scripting/abc.cpp:1583 ../scripting/abc.cpp:1622 #: ../scripting/abc.cpp:1662 msgid " #" msgstr " #" #: ../swf.cpp:65 ../swf.cpp:69 msgid " Length " msgstr "Durée" #: ../asobject.cpp:82 ../asobject.cpp:165 msgid " and type " msgstr " et type" #: ../parsing/tags.cpp:52 msgid " at byte " msgstr " à l'octet" #: ../parsing/tags.cpp:52 ../scripting/actions.cpp:405 msgid " bytes" msgstr " octets" #: ../scripting/actions.cpp:1175 msgid " constants" msgstr " constantes" #: ../backends/input.cpp:190 ../backends/input.cpp:266 msgid " events" msgstr " événements" #: ../scripting/abc.cpp:1355 msgid " events missing before exit" msgstr " événements manquants avant la sortie" #: ../parsing/tags.cpp:224 ../parsing/tags.cpp:229 msgid " expected: " msgstr " attendu :" #: ../backends/graphics.cpp:132 ../backends/graphics.cpp:174 #: ../backends/graphics.cpp:199 msgid " height=" msgstr " hauteur=" #: ../scripting/abc.cpp:1576 msgid " id " msgstr " id" #: ../scripting/flashnet.cpp:726 msgid " in FLV" msgstr " dans FLV" #: ../scripting/abc_opcodes.cpp:1774 ../scripting/abc_opcodes.cpp:1837 #: ../scripting/abc_opcodes.cpp:1888 msgid " is " msgstr " est" #: ../scripting/abc.cpp:1137 msgid " is not yet valid" msgstr " n'est pas encore valide" #: ../scripting/abc_opcodes.cpp:2277 msgid " is not yet valid (as interface)" msgstr " n'est pas encore valide (comme interface)" #: ../parsing/tags.cpp:1364 ../parsing/tags.cpp:1531 msgid " name " msgstr " nom" #: ../scripting/abc.cpp:1131 msgid " not found in global" msgstr " non trouvé dans global" #: ../scripting/abc_opcodes.cpp:667 msgid " not supported in construct" msgstr " non supporté dans construct" #: ../swftypes.cpp:1087 msgid " of action data" msgstr "" #: ../scripting/abc_opcodes.cpp:349 ../scripting/abc_opcodes.cpp:783 msgid " on obj " msgstr " sur objet" #: ../scripting/abc_opcodes.cpp:825 msgid " on obj type " msgstr " sur type d'objet" #: ../scripting/abc_opcodes.cpp:388 msgid " on type " msgstr " sur type" #: ../backends/graphics.cpp:53 msgid " openGL errors" msgstr " erreurs openGL" #: ../backends/rendering.cpp:285 ../backends/rendering.cpp:760 msgid " renderings" msgstr "" #: ../scripting/abc_codesynt.cpp:1482 msgid " should be intrinsic" msgstr " devrait être intrinsèque" #: ../threading.cpp:74 msgid " times" msgstr " fois" #: ../asobject.cpp:185 msgid " to float" msgstr "" #: ../asobject.cpp:178 msgid " to int" msgstr "" #: ../scripting/abc.cpp:1729 ../scripting/abc.cpp:1749 #: ../scripting/abc.cpp:1755 msgid " type " msgstr " type " #: ../scripting/abc.cpp:1576 msgid " type Class name " msgstr "" #: ../scripting/abc.cpp:1755 msgid " vindex 0 " msgstr "" #: ../threading.cpp:74 msgid " waited " msgstr " attendu" #: ../parsing/tags.cpp:52 ../scripting/actions.cpp:405 msgid " with length " msgstr " de longueur" #: ../parsing/tags.cpp:1325 ../parsing/tags.cpp:1492 msgid " with name " msgstr " de nom" #: ../scripting/flashutils.cpp:326 msgid "' not found." msgstr "' non trouvé." #: ../scripting/abc_opcodes.cpp:164 msgid ") " msgstr ")" #: ../parsing/tags.cpp:1815 msgid ", ScriptTimeoutSeconds: " msgstr "" #: ../parsing/tags.cpp:1851 msgid ", password: " msgstr ", mot de passe : " #: ../scripting/abc_opcodes.cpp:1332 ../scripting/abc_opcodes.cpp:1373 msgid ", pushing Undefined" msgstr "" #: ../scripting/abc.cpp:1122 msgid ". Not binding" msgstr "" #: ../parsing/tags.cpp:224 ../parsing/tags.cpp:229 msgid ". Size=" msgstr ". Taille =" #: ../swftypes.cpp:667 ../swftypes.cpp:699 ../backends/rendering.cpp:581 msgid "... Aborting" msgstr "... Annule" #: ../scripting/abc.cpp:1976 msgid "0 not allowed" msgstr "0 non autorisé" #: ../scripting/abc_interpreter.cpp:773 ../scripting/abc_interpreter.cpp:1210 msgid ": " msgstr ":" #: ../scripting/abc.cpp:1418 ../scripting/abc.cpp:1444 #: ../scripting/abc.cpp:1449 ../scripting/abc.cpp:1475 #: ../scripting/abc.cpp:1480 ../scripting/abc.cpp:1506 #: ../scripting/abc.cpp:1576 ../scripting/abc.cpp:1583 #: ../scripting/abc.cpp:1617 ../scripting/abc.cpp:1622 #: ../scripting/abc.cpp:1657 ../scripting/abc.cpp:1662 #: ../scripting/abc.cpp:1698 msgid "::" msgstr "::" #: ../scripting/abc_opcodes.cpp:1080 ../scripting/abc_opcodes.cpp:1091 msgid "<<" msgstr "<<" #: ../scripting/abc_opcodes.cpp:1103 ../scripting/abc_opcodes.cpp:1113 #: ../scripting/abc_opcodes.cpp:1122 msgid ">>" msgstr ">>" #: ../scripting/abc.cpp:78 msgid "ABC Exec " msgstr "" #: ../scripting/abc.cpp:887 msgid "ABCVm version " msgstr "Version d'ABCVm" #: ../scripting/toplevel.cpp:2099 msgid "ASString::charCodeAt not really implemented" msgstr "" #: ../scripting/actions.cpp:83 ../scripting/actions.cpp:150 msgid "AVM1 not supported" msgstr "AVM1 non supporté" #: ../scripting/actions.h:311 msgid "ActionAdd2" msgstr "" #: ../scripting/actions.h:598 msgid "ActionAsciiToChar" msgstr "" #: ../scripting/actions.h:535 msgid "ActionBitAnd" msgstr "" #: ../scripting/actions.h:556 msgid "ActionBitLShift" msgstr "" #: ../scripting/actions.h:542 msgid "ActionBitOr" msgstr "" #: ../scripting/actions.h:563 msgid "ActionBitRShift" msgstr "" #: ../scripting/actions.h:549 msgid "ActionBitXor" msgstr "" #: ../scripting/actions.h:402 msgid "ActionCallFunction" msgstr "" #: ../scripting/actions.h:395 msgid "ActionCallMethod" msgstr "" #: ../scripting/actions.h:528 msgid "ActionCastOp" msgstr "" #: ../scripting/actions.h:409 msgid "ActionCloneSprite" msgstr "" #: ../scripting/actions.cpp:1397 ../scripting/actions.h:263 msgid "ActionConstantPool" msgstr "" #: ../scripting/actions.h:437 msgid "ActionDecrement" msgstr "" #: ../scripting/actions.h:146 msgid "ActionDefineFunction" msgstr "" #: ../scripting/actions.h:184 msgid "ActionDefineFunction2" msgstr "" #: ../scripting/actions.h:353 msgid "ActionDefineLocal" msgstr "" #: ../scripting/actions.h:458 msgid "ActionDelete" msgstr "" #: ../scripting/actions.h:325 msgid "ActionDivide" msgstr "" #: ../scripting/actions.h:479 msgid "ActionEnumerate" msgstr "" #: ../scripting/actions.h:507 msgid "ActionEnumerate2" msgstr "" #: ../scripting/actions.h:612 msgid "ActionEquals2" msgstr "" #: ../scripting/actions.h:430 msgid "ActionExtends" msgstr "" #: ../scripting/actions.h:110 msgid "ActionGetMember" msgstr "" #: ../scripting/actions.h:339 msgid "ActionGetProperty" msgstr "" #: ../scripting/actions.h:486 msgid "ActionGetTime" msgstr "" #: ../scripting/actions.h:252 msgid "ActionGetURL" msgstr "" #: ../scripting/actions.h:241 msgid "ActionGetURL2" msgstr "" #: ../scripting/actions.h:647 msgid "ActionGetVariable" msgstr "" #: ../scripting/actions.cpp:1408 ../scripting/actions.h:283 msgid "ActionGoToLabel" msgstr "" #: ../scripting/actions.h:231 msgid "ActionGotoFrame" msgstr "" #: ../scripting/actions.h:577 msgid "ActionGreater" msgstr "" #: ../scripting/actions.h:221 msgid "ActionIf" msgstr "" #: ../scripting/actions.h:423 msgid "ActionImplementsOp" msgstr "" #: ../scripting/actions.h:570 msgid "ActionIncrement" msgstr "" #: ../scripting/actions.h:465 msgid "ActionInitArray" msgstr "" #: ../scripting/actions.h:444 msgid "ActionInitObject" msgstr "" #: ../scripting/actions.h:493 msgid "ActionInstanceOf" msgstr "" #: ../scripting/actions.h:201 msgid "ActionJump" msgstr "" #: ../scripting/actions.cpp:999 msgid "ActionJump: " msgstr "" #: ../scripting/actions.h:591 msgid "ActionLess2" msgstr "" #: ../scripting/actions.h:318 msgid "ActionModulo" msgstr "" #: ../scripting/actions.h:360 msgid "ActionMultiply" msgstr "" #: ../scripting/actions.h:451 msgid "ActionNewMethod" msgstr "" #: ../scripting/actions.h:304 msgid "ActionNewObject" msgstr "" #: ../scripting/actions.h:388 msgid "ActionNot" msgstr "" #: ../scripting/actions.h:124 msgid "ActionPlay" msgstr "" #: ../scripting/actions.h:374 msgid "ActionPop" msgstr "" #: ../scripting/actions.cpp:1314 msgid "ActionPush" msgstr "" #: ../scripting/actions.h:332 msgid "ActionPushDuplicate" msgstr "" #: ../scripting/actions.h:346 msgid "ActionReturn" msgstr "" #: ../scripting/actions.h:117 msgid "ActionSetMember" msgstr "" #: ../scripting/actions.h:500 msgid "ActionSetProperty" msgstr "" #: ../scripting/actions.h:273 msgid "ActionSetTarget" msgstr "" #: ../scripting/actions.h:633 msgid "ActionSetTarget2" msgstr "" #: ../scripting/actions.h:626 msgid "ActionSetVariable" msgstr "" #: ../scripting/actions.h:131 msgid "ActionStop" msgstr "" #: ../scripting/actions.h:663 msgid "ActionStoreRegister" msgstr "" #: ../scripting/actions.h:605 msgid "ActionStrictEquals" msgstr "" #: ../scripting/actions.h:290 msgid "ActionStringAdd" msgstr "" #: ../scripting/actions.h:619 msgid "ActionStringEquals" msgstr "" #: ../scripting/actions.h:297 msgid "ActionStringExtract" msgstr "" #: ../scripting/actions.h:584 msgid "ActionStringGreater" msgstr "" #: ../scripting/actions.h:367 msgid "ActionSubtract" msgstr "" #: ../scripting/actions.cpp:859 ../scripting/actions.h:381 msgid "ActionToInteger" msgstr "" #: ../scripting/actions.h:521 msgid "ActionToNumber" msgstr "" #: ../scripting/actions.h:514 msgid "ActionToString" msgstr "" #: ../scripting/actions.h:416 msgid "ActionTrace" msgstr "" #: ../scripting/actions.h:472 msgid "ActionTypeOf" msgstr "" #: ../scripting/actions.h:211 msgid "ActionWith" msgstr "" #: ../scripting/abc_opcodes.cpp:1025 msgid "Add between integer and " msgstr "" #: ../scripting/abc_opcodes.cpp:980 msgid "Add between types " msgstr "" #: ../scripting/abc_opcodes.cpp:1068 msgid "Add between types number and " msgstr "" #: ../asobject.cpp:114 msgid "Add buildTraits for class " msgstr "" #: ../scripting/toplevel.cpp:3046 msgid "Array to bool" msgstr "" #: ../scripting/toplevel.cpp:179 msgid "Array::filter STUB" msgstr "" #: ../scripting/abc_opcodes.cpp:402 ../scripting/abc_opcodes.cpp:1381 msgid "Attaching this to function " msgstr "" #: ../backends/decoder.cpp:446 msgid "Audio channels " msgstr "Canaux audio" #: ../backends/decoder.cpp:438 msgid "Audio sample rate " msgstr "Taux d'échantillonnage auio" #: ../scripting/abc.cpp:109 msgid "Binding " msgstr "Liaison" #: ../scripting/abc.cpp:1037 msgid "Binding of " msgstr "Liaison de" #: ../scripting/toplevel.cpp:3079 msgid "Boolean conversion for type " msgstr "" #: ../scripting/toplevel.cpp:3031 msgid "Boolean to bool " msgstr "" #: ../scripting/abc_opcodes.cpp:2232 msgid "Building class traits" msgstr "" #: ../scripting/abc.cpp:1286 msgid "Building entry script traits: " msgstr "" #: ../scripting/abc.cpp:1067 ../scripting/toplevel.cpp:2725 msgid "Building instance traits" msgstr "" #: ../scripting/abc_opcodes.cpp:641 ../scripting/abc_opcodes.cpp:2002 msgid "Building method traits" msgstr "" #: ../scripting/abc.cpp:1264 msgid "Building script traits: " msgstr "" #: ../scripting/toplevel.cpp:2616 msgid "Building traits for " msgstr "" #: ../parsing/tags_stub.cpp:100 msgid "CSMTextSettingsTag" msgstr "" #: ../backends/netutils.cpp:278 msgid "CURL not enabled in this build. Downloader will always fail." msgstr "" "CURL non activé dans cette version compilée. Le téléchargement échouera " "toujours." #: ../scripting/toplevel.cpp:459 msgid "Called ASXML::load " msgstr "" #: ../scripting/toplevel.cpp:134 msgid "Called Array constructor" msgstr "" #: ../scripting/toplevel.cpp:426 msgid "Called MovieClipLoader constructor" msgstr "" #: ../scripting/toplevel.cpp:432 msgid "Called MovieClipLoader::addListener" msgstr "" #: ../scripting/toplevel.cpp:444 msgid "Called XML constructor" msgstr "" #: ../scripting/flashdisplay.cpp:524 msgid "Called swapDepths" msgstr "" #: ../scripting/abc_opcodes.cpp:2292 msgid "Calling Class init " msgstr "" #: ../scripting/toplevel.cpp:2660 msgid "Calling Instance init " msgstr "" #: ../scripting/abc_opcodes.cpp:1710 msgid "Calling an undefined function" msgstr "" #: ../scripting/abc_opcodes.cpp:349 ../scripting/abc_opcodes.cpp:783 #: ../scripting/abc_opcodes.cpp:1635 msgid "Calling an undefined function " msgstr "" #: ../scripting/toplevel.cpp:2818 msgid "Calling interface init for " msgstr "" #: ../asobject.cpp:596 ../asobject.cpp:639 ../asobject.cpp:864 msgid "Calling the getter" msgstr "" #: ../asobject.cpp:592 msgid "Calling the getter on type " msgstr "" #: ../asobject.cpp:352 ../asobject.cpp:385 msgid "Calling the setter" msgstr "" #: ../scripting/toplevel.cpp:1674 ../scripting/toplevel.cpp:1760 msgid "Calling with closure " msgstr "" #: ../asobject.cpp:178 ../asobject.cpp:185 msgid "Cannot convert object of type " msgstr "" #: ../plugin/plugin.cpp:351 msgid "Cannot handle UTF8 URLs" msgstr "Ne peut pas gérer les URLs en UTF8" #: ../scripting/abc_opcodes.cpp:586 msgid "Cannot increment type " msgstr "Ne peut pas incrémenter le type" #: ../backends/rendering.cpp:514 #, fuzzy msgid "Cannot initialize GLEW: cause " msgstr "Ne peut pas initialiser GLEW" #: ../scripting/abc_opcodes.cpp:1726 msgid "Cannot retrieve type" msgstr "" #: ../scripting/abc_codesynt.cpp:789 ../scripting/abc_codesynt.cpp:2253 msgid "Case " msgstr "" #: ../scripting/abc_opcodes.cpp:691 msgid "Check" msgstr "" #: ../swf.cpp:528 msgid "Child process creation failed, lightspark continues" msgstr "La création de l'enfant a échoué, lightspark continue" #: ../scripting/abc.cpp:908 ../scripting/abc.cpp:1131 #: ../scripting/abc.cpp:1137 ../scripting/abc_opcodes.cpp:2277 msgid "Class " msgstr "" #: ../scripting/abc.cpp:1576 msgid "Class slot " msgstr "" #: ../scripting/toplevel.cpp:3041 msgid "Class to bool" msgstr "" #: ../scripting/actions.cpp:461 msgid "CodeSize not consistent" msgstr "" #: ../scripting/actions.cpp:578 msgid "CodeSize not consistent with file offset " msgstr "" #: ../swf.cpp:69 msgid "Compressed SWF file: Version " msgstr "Fichier compressé SWF : Version" #: ../backends/sound.cpp:258 msgid "Connection to PulseAudio server failed" msgstr "Connexion au serveur PulseAudio échouée" #: ../scripting/abc.cpp:1729 msgid "Const " msgstr "" #: ../scripting/abc.cpp:1542 msgid "Constant kind " msgstr "" #: ../scripting/actions.cpp:1175 msgid "ConstantPool: Reading " msgstr "" #: ../scripting/abc_opcodes.cpp:610 ../scripting/abc_opcodes.cpp:700 #: ../scripting/abc_opcodes.cpp:1985 msgid "Constructing" msgstr "" #: ../scripting/abc.cpp:66 msgid "Corrupted ABC data: missing " msgstr "Donnée ABC corrompue : manque" #: ../backends/rendering.cpp:203 msgid "Could not find any GLX configuration" msgstr "Ne peut pas trouver de configuration GLX" #: ../swf.cpp:607 msgid "Creating VM" msgstr "Création de la VM" #: ../scripting/toplevel.cpp:129 msgid "Creating array of length " msgstr "" #: ../backends/input.cpp:39 msgid "Creating input thread" msgstr "" #: ../scripting/abc_opcodes.cpp:1413 msgid "Cur prototype name " msgstr "" #: ../parsing/tags.cpp:1820 msgid "DebugIDTag Tag" msgstr "" #: ../parsing/tags.cpp:1825 msgid "DebugId " msgstr "" #: ../parsing/tags.cpp:1840 msgid "Debugger enabled, password: " msgstr "Débogueur activé, mot de passe :" #: ../parsing/tags.cpp:1851 msgid "Debugger enabled, reserved: " msgstr "Débogueur activé, réservé :" #: ../scripting/abc_opcodes.cpp:1387 ../scripting/abc_opcodes.cpp:1978 msgid "Deferred definition of property " msgstr "" #: ../parsing/tags.cpp:1757 msgid "DefineBinaryDataTag" msgstr "" #: ../parsing/tags_stub.cpp:76 msgid "DefineBitsJPEG2Tag Tag" msgstr "" #: ../parsing/tags.cpp:670 msgid "DefineBitsLossless2Tag::Render" msgstr "" #: ../parsing/tags.cpp:1672 msgid "DefineButton2Tag::Render" msgstr "" #: ../parsing/tags.cpp:266 msgid "DefineEditTextTag ID " msgstr "" #: ../parsing/tags.cpp:307 msgid "DefineEditTextTag: Render" msgstr "" #: ../parsing/tags.cpp:440 msgid "DefineFont" msgstr "" #: ../parsing/tags.cpp:465 msgid "DefineFont2" msgstr "" #: ../parsing/tags.cpp:554 msgid "DefineFont3" msgstr "" #: ../parsing/tags_stub.cpp:70 msgid "DefineFontAlignZonesTag Tag" msgstr "" #: ../parsing/tags_stub.cpp:40 msgid "DefineFontInfo Tag" msgstr "" #: ../parsing/tags_stub.cpp:64 msgid "DefineFontNameTag Tag" msgstr "" #: ../parsing/tags_stub.cpp:83 msgid "DefineScalingGridTag Tag on ID " msgstr "" #: ../parsing/tags_stub.cpp:94 msgid "DefineSceneAndFrameLabelDataTag" msgstr "" #: ../parsing/tags.cpp:867 msgid "DefineShape2Tag" msgstr "" #: ../parsing/tags.cpp:874 msgid "DefineShape3Tag" msgstr "" #: ../parsing/tags.cpp:881 msgid "DefineShape4Tag" msgstr "" #: ../parsing/tags.cpp:860 msgid "DefineShapeTag" msgstr "" #: ../parsing/tags.cpp:1785 msgid "DefineSound Tag" msgstr "" #: ../parsing/tags.cpp:343 msgid "DefineSprite ID: " msgstr "" #: ../parsing/tags.cpp:676 msgid "DefineText ID " msgstr "" #: ../parsing/tags.cpp:750 msgid "DefineText Render" msgstr "" #: ../parsing/tags.cpp:1730 msgid "DefineVideoStreamTag" msgstr "" #: ../parsing/tags.cpp:1741 msgid "DefineVideoStreamTag Render" msgstr "" #: ../scripting/actions.cpp:433 msgid "Defining function " msgstr "" #: ../scripting/actions.cpp:538 msgid "Defining function2 " msgstr "" #: ../scripting/flashutils.cpp:326 msgid "Definition for '" msgstr "" #: ../plugin/plugin.cpp:436 msgid "DestroyStream on main stream?" msgstr "" #: ../scripting/abc.cpp:59 msgid "DoABCTag Name: " msgstr "" #: ../scripting/actions.cpp:54 msgid "DoActionTag" msgstr "" #: ../scripting/actions.cpp:121 msgid "DoInitActionTag" msgstr "" #: ../backends/netutils.cpp:123 msgid "Downloaded file bigger than buffer: " msgstr "Fichier téléchargé plus grand que le tampon :" #: ../scripting/abc.cpp:1206 msgid "Empty stack" msgstr "Pile vide" #: ../parsing/tags.cpp:1845 msgid "EnableDebugger2Tag Tag" msgstr "" #: ../parsing/tags.cpp:1836 msgid "EnableDebuggerTag Tag" msgstr "" #: ../scripting/abc.cpp:1475 ../scripting/abc.cpp:1617 msgid "End Getter trait: " msgstr "" #: ../scripting/abc.cpp:1444 ../scripting/abc.cpp:1698 msgid "End Method trait: " msgstr "" #: ../scripting/abc.cpp:1506 ../scripting/abc.cpp:1657 msgid "End Setter trait: " msgstr "" #: ../scripting/actions.cpp:447 ../scripting/actions.cpp:563 msgid "End action in function" msgstr "" #: ../scripting/abc_opcodes.cpp:2297 msgid "End of Class init " msgstr "" #: ../scripting/abc.cpp:1299 msgid "End of Entry Point" msgstr "" #: ../scripting/abc.cpp:1039 msgid "End of binding of " msgstr "" #: ../scripting/abc_opcodes.cpp:2378 msgid "End of call " msgstr "" #: ../scripting/abc_opcodes.cpp:1638 msgid "End of callSuper " msgstr "" #: ../scripting/abc_opcodes.cpp:1712 msgid "End of callSuperVoid " msgstr "" #: ../scripting/abc_opcodes.cpp:343 ../scripting/abc_opcodes.cpp:353 #: ../scripting/abc_opcodes.cpp:817 ../scripting/abc_opcodes.cpp:835 msgid "End of calling " msgstr "" #: ../scripting/abc_opcodes.cpp:706 msgid "End of constructing" msgstr "" #: ../scripting/abc_opcodes.cpp:674 ../scripting/abc_opcodes.cpp:2030 msgid "End of constructing " msgstr "" #: ../scripting/abc_opcodes.cpp:1391 ../scripting/abc_opcodes.cpp:1982 msgid "End of deferred definition of property " msgstr "" #: ../scripting/abc.cpp:1140 ../scripting/abc_opcodes.cpp:2280 msgid "End of deferred init of class " msgstr "" #: ../asobject.cpp:603 ../asobject.cpp:643 ../asobject.cpp:869 msgid "End of getter" msgstr "" #: ../swf.cpp:828 msgid "End of parsing @ " msgstr "" #: ../asobject.cpp:363 ../asobject.cpp:392 msgid "End of setter" msgstr "" #: ../scripting/abc_opcodes.cpp:1420 msgid "End super construct " msgstr "" #: ../parsing/tags.cpp:392 msgid "EndDefineSprite ID: " msgstr "" #: ../parsing/tags.cpp:56 msgid "EndTag at position " msgstr "" #: ../asobject.cpp:165 msgid "Equal comparison between type " msgstr "" #: ../scripting/abc.cpp:1369 msgid "Error in VM " msgstr "Erreur dans la VM " #: ../parsing/tags.cpp:224 ../parsing/tags.cpp:229 msgid "Error while reading tag " msgstr "Erreur lors de la lecture de la balise " #: ../scripting/toplevel.cpp:2266 msgid "Error.getStackTrace not yet implemented." msgstr "" #: ../scripting/flashevents.cpp:323 msgid "Event not found" msgstr "Événement non trouvé" #: ../swf.cpp:870 msgid "Exception in ParseThread " msgstr "" #: ../backends/rendering.cpp:402 ../backends/rendering.cpp:894 msgid "Exception in RenderThread " msgstr "" #: ../swf.cpp:1102 msgid "Exception in RootMovieClip::tick " msgstr "" #: ../thread_pool.cpp:108 msgid "Exception in ThreadPool " msgstr "" #: ../scripting/flashnet.cpp:766 msgid "Exception in reading: " msgstr "" #: ../scripting/actions.cpp:701 msgid "Exec: ActionBitAnd" msgstr "" #: ../scripting/actions.cpp:716 msgid "Exec: ActionBitLShift" msgstr "" #: ../scripting/actions.cpp:706 msgid "Exec: ActionBitOr" msgstr "" #: ../scripting/actions.cpp:721 msgid "Exec: ActionBitRShift" msgstr "" #: ../scripting/actions.cpp:711 msgid "Exec: ActionBitXor" msgstr "" #: ../scripting/actions.cpp:741 msgid "Exec: ActionCastOp" msgstr "" #: ../scripting/actions.cpp:797 msgid "Exec: ActionCloneSprite" msgstr "" #: ../scripting/actions.cpp:654 msgid "Exec: ActionDecrement" msgstr "" #: ../scripting/actions.cpp:1005 msgid "Exec: ActionDelete" msgstr "" #: ../scripting/actions.cpp:681 msgid "Exec: ActionEnumerate" msgstr "" #: ../scripting/actions.cpp:726 msgid "Exec: ActionEnumerate2" msgstr "" #: ../scripting/actions.cpp:686 msgid "Exec: ActionGetTime" msgstr "" #: ../scripting/actions.cpp:696 msgid "Exec: ActionImplementsOp" msgstr "" #: ../scripting/actions.cpp:1086 msgid "Exec: ActionInitArray" msgstr "" #: ../scripting/actions.cpp:1091 msgid "Exec: ActionInitObject" msgstr "" #: ../scripting/actions.cpp:691 msgid "Exec: ActionInstanceOf" msgstr "" #: ../scripting/actions.cpp:1010 msgid "Exec: ActionNewMethod" msgstr "" #: ../scripting/actions.cpp:586 msgid "Exec: ActionPushDuplicate" msgstr "" #: ../scripting/actions.cpp:1015 ../scripting/actions.cpp:1020 msgid "Exec: ActionStringAdd" msgstr "" #: ../scripting/actions.cpp:1096 msgid "Exec: ActionStringEquals" msgstr "" #: ../scripting/actions.cpp:1025 msgid "Exec: ActionStringExtract" msgstr "" #: ../scripting/actions.cpp:772 msgid "Exec: ActionStringGreater" msgstr "" #: ../scripting/actions.cpp:736 msgid "Exec: ActionToNumber" msgstr "" #: ../scripting/actions.cpp:731 msgid "Exec: ActionToString" msgstr "" #: ../scripting/actions.cpp:1147 msgid "Exec: ActionToggleQuality" msgstr "" #: ../scripting/actions.cpp:802 msgid "Exec: ActionTrace" msgstr "" #: ../scripting/actions.cpp:676 msgid "Exec: ActionTypeOf" msgstr "" #: ../scripting/actions.cpp:1319 msgid "Exec: ActionWith" msgstr "" #: ../swf.cpp:561 msgid "Execve failed, content will not be rendered" msgstr "" #: ../scripting/actions.cpp:37 msgid "ExportAssetsTag Tag" msgstr "" #: ../parsing/flv.cpp:38 msgid "FLV file: Version " msgstr "Fichier FLV : Version " #: ../backends/rendering.cpp:909 msgid "FPS: " msgstr "FPS :" #: ../scripting/toplevel.cpp:2680 msgid "Failure in reference counting" msgstr "" #: ../backends/rendering.cpp:285 ../backends/rendering.cpp:760 msgid "Faking " msgstr "Simule " #: ../backends/rendering.cpp:199 msgid "Falling back to no double buffering" msgstr "" #: ../parsing/tags.cpp:168 msgid "FileAttributes tag not in the beginning" msgstr "" #: ../parsing/tags.cpp:1768 msgid "FileAttributesTag Tag" msgstr "" #: ../swftypes.cpp:288 ../swftypes.cpp:304 msgid "Fill array extended not supported" msgstr "" #: ../swftypes.h:603 msgid "Fixed point bit field wider than 32 bit not supported" msgstr "" #: ../scripting/abc.cpp:909 msgid "Flags:" msgstr "" #: ../backends/rendering.cpp:85 msgid "Font File is " msgstr "Le fichier de police est " #: ../scripting/flashsystem.cpp:105 msgid "Found definition for " msgstr "Définition trouvée pour " #: ../backends/rendering.cpp:442 msgid "Fragment shader compilation " msgstr "" #: ../swf.cpp:809 msgid "FrameRate " msgstr "" #: ../scripting/abc_opcodes.cpp:2375 msgid "Function not good " msgstr "Mauvaise fonction " #: ../scripting/abc.cpp:2199 msgid "Function not implemented" msgstr "Fonction non implémentée" #: ../backends/graphics.cpp:45 msgid "GL error " msgstr "Erreur GL" #: ../backends/rendering.cpp:584 msgid "GL errors during initialization: " msgstr "Erreurs GL lors de l'initialisation :" #: ../backends/graphics.cpp:132 ../backends/graphics.cpp:174 #: ../backends/graphics.cpp:199 msgid "GL_INVALID_VALUE after glTexImage2D, width=" msgstr "" #: ../scripting/actions.cpp:1367 msgid "GetURL2" msgstr "" #: ../scripting/actions.cpp:1378 msgid "GetURL2: exec" msgstr "" #: ../scripting/actions.cpp:1373 msgid "GetURL: exec" msgstr "" #: ../scripting/abc.cpp:1472 msgid "Getter not linkable" msgstr "" #: ../scripting/abc.cpp:1449 ../scripting/abc.cpp:1583 msgid "Getter trait: " msgstr "" #: ../scripting/flashsystem.cpp:138 ../scripting/flashutils.cpp:341 msgid "Getting definition for " msgstr "" #: ../scripting/abc.cpp:961 msgid "Global is " msgstr "Global est " #: ../scripting/flashevents.cpp:372 msgid "Handling event " msgstr "" #: ../backends/graphics.cpp:53 msgid "Ignoring " msgstr "Ignore" #: ../scripting/abc_codesynt.cpp:685 ../scripting/abc_codesynt.cpp:1596 msgid "Ignoring at " msgstr "" #: ../scripting/abc.cpp:922 msgid "Implements" msgstr "" #: ../backends/rendering.cpp:581 msgid "Incomplete FBO status " msgstr "Statut FBO incomplet" #: ../parsing/tags.cpp:388 msgid "Inconsistent frame count " msgstr "" #: ../scripting/toplevel.cpp:3070 msgid "Integer to bool" msgstr "" #: ../swf.cpp:511 msgid "Invoking gnash!" msgstr "Invocation de gnash !" #: ../threading.cpp:51 msgid "Job terminated" msgstr "Travail terminé" #: ../scripting/toplevel.cpp:1779 msgid "LOG10E" msgstr "" #: ../scripting/toplevel.cpp:1780 msgid "LOG2E" msgstr "" #: ../scripting/abc_codesynt.cpp:1569 msgid "Last instruction before a new block was not a branch." msgstr "" #: ../scripting/abc.cpp:1277 msgid "Last script (Entry Point)" msgstr "Dernier script (Point d'entrée)" #: ../asobject.cpp:82 msgid "Less than comparison between type " msgstr "" #: ../swftypes.cpp:238 ../swftypes.cpp:265 msgid "Line array extended not supported" msgstr "" #: ../scripting/abc_opcodes.cpp:2193 msgid "Linking with interface " msgstr "Liaison avec l'interface " #: ../scripting/flashdisplay.cpp:196 msgid "Loader async execution " msgstr "" #: ../backends/netutils.cpp:394 msgid "LocalDownloader::execute: could not open local file: " msgstr "" #: ../backends/netutils.cpp:386 msgid "LocalDownloader::execute: reading from local file failed: " msgstr "" #: ../backends/netutils.cpp:359 msgid "LocalDownloader::execute: reading local file: " msgstr "" #: ../scripting/flashsystem.cpp:86 ../scripting/flashsystem.cpp:121 #: ../scripting/flashutils.cpp:319 msgid "Looking for definition of " msgstr "Cherche la définition de " #: ../parsing/tags.cpp:1815 msgid "MaxRecusionDepth: " msgstr "" #: ../parsing/tags.cpp:1858 msgid "MetaData: " msgstr "MétaDonnée :" #: ../parsing/tags.cpp:1856 msgid "MetadataTag Tag" msgstr "" #: ../scripting/abc_codesynt.cpp:1482 msgid "Method " msgstr "Méthode " #: ../scripting/abc.cpp:1441 msgid "Method not linkable" msgstr "" #: ../scripting/abc.cpp:1418 ../scripting/abc.cpp:1662 msgid "Method trait: " msgstr "" #: ../parsing/tags.cpp:1333 ../parsing/tags.cpp:1500 msgid "Moving of registered objects not really supported" msgstr "" #: ../scripting/abc.cpp:1933 msgid "Multibyte not handled" msgstr "Multioctet non géré" #: ../scripting/abc.cpp:339 ../scripting/abc.cpp:356 ../scripting/abc.cpp:488 #: ../scripting/abc.cpp:584 ../scripting/abc.cpp:619 ../scripting/abc.cpp:636 #: ../scripting/abc.cpp:782 msgid "Multiname to String not yet implemented for this kind " msgstr "" #: ../scripting/abc.cpp:1122 msgid "Multiple binding on " msgstr "" #: ../threading.cpp:74 msgid "Mutex " msgstr "" #: ../scripting/abc_opcodes.cpp:1332 ../scripting/abc_opcodes.cpp:1373 msgid "NOT found " msgstr "NON trouvé " #: ../scripting/abc_opcodes.cpp:1498 msgid "NOT found, pushing Undefined" msgstr "" #: ../scripting/abc_opcodes.cpp:1455 msgid "NOT found, pushing global" msgstr "" #: ../scripting/abc_opcodes.cpp:1369 ../scripting/abc_opcodes.cpp:1491 msgid "NOT found, trying Global" msgstr "" #: ../scripting/flashnet.cpp:439 msgid "NetStream constructor" msgstr "" #: ../scripting/flashnet.cpp:516 msgid "NetStream::close called" msgstr "" #: ../scripting/abc_codesynt.cpp:676 ../scripting/abc_codesynt.cpp:731 msgid "New block at " msgstr "" #: ../plugin/plugin.cpp:365 msgid "Newstream for " msgstr "" #: ../scripting/abc.cpp:1412 ../scripting/abc.cpp:1558 msgid "Next slot has flags " msgstr "" #: ../parsing/flv.cpp:43 msgid "No FLV file signature found" msgstr "Pas de signature de fichier FLV trouvée" #: ../swf.cpp:73 msgid "No SWF file signature found" msgstr "Pas de signature de fichier SWF trouvée" #: ../backends/geometry.cpp:46 msgid "No edges in this shape" msgstr "" #: ../main.cpp:196 ../tightspark.cpp:94 msgid "No execution model enabled" msgstr "" #: ../plugin/plugin.cpp:266 msgid "No size in SetWindow" msgstr "" #: ../swf.cpp:1063 msgid "No such Id on dictionary " msgstr "" #: ../backends/rendering.cpp:217 msgid "No suitable graphics configuration available" msgstr "" #: ../backends/rendering.cpp:573 msgid "Non enough color attachments available, input disabled" msgstr "" #: ../scripting/flashdisplay.cpp:492 msgid "Not a function" msgstr "N'est pas une fonction" #: ../scripting/flashdisplay.cpp:601 msgid "Not enough frames loaded" msgstr "" #: ../scripting/flashevents.cpp:368 msgid "Not handled event " msgstr "Événement non géré" #: ../scripting/actions.h:640 msgid "Not implemented action" msgstr "Action non implémentée" #: ../scripting/abc_codesynt.cpp:1356 ../scripting/abc_codesynt.cpp:3928 msgid "Not implemented instruction @" msgstr "Instruction non implémentée @" #: ../scripting/flashevents.cpp:281 msgid "Not implemented mode for addEventListener" msgstr "" #: ../scripting/abc_interpreter.cpp:1261 msgid "Not intepreted instruction @" msgstr "Instruction non interprétée @" #: ../scripting/actions.cpp:68 ../scripting/actions.cpp:135 #: ../scripting/actions.cpp:453 ../scripting/actions.cpp:569 msgid "Not supported action opcode" msgstr "" #: ../swftypes.cpp:667 ../swftypes.cpp:699 msgid "Not supported fill style " msgstr "Type de remplissage non supporté" #: ../scripting/toplevel.cpp:3056 msgid "Null to bool" msgstr "" #: ../scripting/toplevel.cpp:3061 msgid "Number to bool" msgstr "" #: ../scripting/abc_opcodes.cpp:1740 ../scripting/abc_opcodes.cpp:1794 #: ../scripting/abc_opcodes.cpp:1855 msgid "Numeric type is " msgstr "Le type numérique est " #: ../scripting/abc_opcodes.cpp:303 msgid "Object" msgstr "Objet" #: ../scripting/toplevel.cpp:3036 msgid "Object to bool" msgstr "" #: ../scripting/abc_opcodes.cpp:667 msgid "Object type " msgstr "Type d'objet" #: ../asobject.cpp:139 ../asobject.cpp:161 msgid "Overloaded isEqual" msgstr "" #: ../asobject.cpp:78 msgid "Overloaded isLess" msgstr "" #: ../swf.cpp:266 msgid "Parameters file not found" msgstr "Fichier de paramètres non trouvé" #: ../asobject.cpp:503 msgid "Passthorugh of " msgstr "" #: ../parsing/tags.cpp:1373 msgid "PlaceObject2" msgstr "" #: ../parsing/tags.cpp:1540 msgid "PlaceObject3" msgstr "" #: ../parsing/tags.cpp:1271 ../parsing/tags.cpp:1438 msgid "Placing ID " msgstr "" #: ../parsing/tags.cpp:1602 msgid "ProductInfoTag Tag" msgstr "" #: ../scripting/abc_opcodes.cpp:388 ../scripting/abc_opcodes.cpp:392 msgid "Property not found " msgstr "" #: ../parsing/tags_stub.cpp:34 msgid "Protect Tag" msgstr "" #: ../scripting/abc_opcodes.cpp:338 ../scripting/abc_opcodes.cpp:811 msgid "Proxy::callProperty" msgstr "" #: ../scripting/flashutils.cpp:628 msgid "Proxy::getProperty" msgstr "" #: ../scripting/flashutils.cpp:638 msgid "Proxy::hasNext" msgstr "" #: ../scripting/flashutils.cpp:656 msgid "Proxy::nextName" msgstr "" #: ../scripting/flashutils.cpp:601 msgid "Proxy::setProperty" msgstr "" #: ../scripting/actions.cpp:1304 msgid "Push type: " msgstr "" #: ../scripting/actions.cpp:1262 msgid "Push: Read bool " msgstr "" #: ../scripting/actions.cpp:1290 msgid "Push: Read constant index " msgstr "" #: ../scripting/actions.cpp:1271 msgid "Push: Read double " msgstr "" #: ../scripting/actions.cpp:1231 msgid "Push: Read float " msgstr "" #: ../scripting/actions.cpp:1280 msgid "Push: Read integer " msgstr "" #: ../scripting/actions.cpp:1300 msgid "Push: Read long constant index " msgstr "" #: ../scripting/actions.cpp:1253 msgid "Push: Read reg number " msgstr "" #: ../scripting/actions.cpp:1222 msgid "Push: Read string " msgstr "" #: ../scripting/actions.cpp:1237 msgid "Push: null" msgstr "" #: ../scripting/actions.cpp:1243 msgid "Push: undefined" msgstr "" #: ../parsing/tags.cpp:52 msgid "Reading tag type: " msgstr "" #: ../backends/graphics.cpp:192 msgid "Reallocating texture to size " msgstr "" #: ../parsing/tags.cpp:1325 ../parsing/tags.cpp:1492 msgid "Registering ID " msgstr "" #: ../parsing/tags.cpp:239 msgid "RemoveObject2 Depth: " msgstr "" #: ../backends/rendering.cpp:57 msgid "RenderThread this=" msgstr "" #: ../scripting/abc.cpp:1177 msgid "Requested invalid method" msgstr "" #: ../swftypes.cpp:395 msgid "Reserved bits not so reserved" msgstr "" #: ../swftypes.cpp:538 msgid "Reverting to fixed function" msgstr "" #: ../main.cpp:218 msgid "Running in local-with-filesystem sandbox" msgstr "" #: ../main.cpp:214 msgid "Running in remote sandbox" msgstr "" #: ../parsing/tags.cpp:1611 msgid "SWF Info:" msgstr "Info SWF :" #: ../scripting/abc.cpp:1256 msgid "Script N: " msgstr "" #: ../parsing/tags.cpp:1813 msgid "ScriptLimitsTag Tag" msgstr "" #: ../scripting/flashsystem.cpp:199 msgid "Security::allowDomain" msgstr "" #: ../scripting/flashsystem.cpp:205 msgid "Security::allowInsecureDomain" msgstr "" #: ../scripting/flashsystem.cpp:211 msgid "Security::loadPolicyFile" msgstr "" #: ../scripting/flashsystem.cpp:217 msgid "Security::showSettings" msgstr "" #: ../scripting/abc.cpp:1503 msgid "Setter not linkable" msgstr "" #: ../scripting/abc.cpp:1480 ../scripting/abc.cpp:1622 msgid "Setter trait: " msgstr "" #: ../scripting/abc.cpp:1126 msgid "Setting class name to " msgstr "" #: ../backends/rendering.cpp:428 msgid "Shader lightspark.frag not found" msgstr "" #: ../backends/rendering.cpp:465 msgid "Shader lightspark.vert not found" msgstr "" #: ../parsing/tags.cpp:768 msgid "Should be a FontTag" msgstr "" #: ../parsing/tags.cpp:1224 msgid "ShowFrame" msgstr "" #: ../swftypes.h:665 msgid "Signed bit field wider than 32 bit not supported" msgstr "" #: ../swftypes.cpp:1087 msgid "Skipping " msgstr "" #: ../scripting/abc.cpp:1749 ../scripting/abc.cpp:1755 msgid "Slot " msgstr "Emplacement " #: ../parsing/tags_stub.cpp:88 msgid "SoundStreamBlockTag" msgstr "" #: ../parsing/tags_stub.cpp:52 msgid "SoundStreamHead Tag" msgstr "" #: ../parsing/tags_stub.cpp:58 msgid "SoundStreamHead2 Tag" msgstr "" #: ../scripting/flashmedia.cpp:45 msgid "SoundTransform constructor" msgstr "" #: ../scripting/abc.cpp:1230 msgid "Stack not clean at the end of function" msgstr "" #: ../parsing/tags_stub.cpp:46 msgid "StartSound Tag" msgstr "" #: ../scripting/abc_codesynt.cpp:1574 msgid "Starting block at " msgstr "" #: ../scripting/toplevel.cpp:3021 msgid "String to bool" msgstr "" #: ../swftypes.cpp:621 msgid "Style not implemented" msgstr "Style non implémenté" #: ../scripting/abc.cpp:919 msgid "Super " msgstr "" #: ../scripting/abc_opcodes.cpp:1416 msgid "Super prototype name " msgstr "" #: ../scripting/abc_interpreter.cpp:397 msgid "Switch default dest " msgstr "" #: ../scripting/abc_interpreter.cpp:404 msgid "Switch dest " msgstr "" #: ../scripting/abc.cpp:93 msgid "SymbolClassTag" msgstr "" #: ../scripting/abc.cpp:105 msgid "SymbolClassTag Exec" msgstr "" #: ../parsing/tags.cpp:300 msgid "Sync to variable name " msgstr "" #: ../scripting/flashevents.cpp:119 msgid "Target for event " msgstr "" #: ../scripting/flashtext.cpp:100 msgid "TextField::Render" msgstr "" #: ../scripting/abc.cpp:1513 ../scripting/abc.cpp:1786 msgid "Trait not supported " msgstr "" #: ../asobject.cpp:84 ../asobject.cpp:167 ../scripting/abc_opcodes.cpp:1774 #: ../scripting/abc_opcodes.cpp:1837 ../scripting/abc_opcodes.cpp:1888 msgid "Type " msgstr "Type " #: ../backends/rendering.cpp:78 msgid "Unable to find suitable Serif font" msgstr "Impossible de trouver une police Serif adéquate" #: ../backends/rendering.cpp:238 msgid "Unable to load serif font" msgstr "Impossible de charger la police Serif" #: ../parsing/tags.cpp:375 msgid "Unclassified tag inside Sprite?" msgstr "" #: ../swf.cpp:65 msgid "Uncompressed SWF file: Version " msgstr "Fichier SWF non compressé : Version" #: ../scripting/toplevel.cpp:1180 msgid "Undefined function" msgstr "Fonction indéfinie" #: ../scripting/toplevel.cpp:3051 msgid "Undefined to bool" msgstr "" #: ../timer.cpp:164 msgid "Unexpected failure of sem_timedwait.. Trying to go on. errno=" msgstr "" #: ../scripting/abc.cpp:2113 msgid "Unexpected kind " msgstr "" #: ../scripting/abc.cpp:2021 msgid "Unexpected multiname kind " msgstr "" #: ../scripting/abc.cpp:2045 msgid "Unexpected options type" msgstr "Type d'options inattendu" #: ../scripting/flashnet.cpp:726 msgid "Unexpected tag type " msgstr "Type de balise inattendu" #: ../scripting/toplevel.cpp:2162 msgid "Unicode not supported in String::fromCharCode" msgstr "Unicode non supporté dans String::fromCharCode" #: ../parsing/tags_stub.cpp:106 msgid "Unimplemented Tag " msgstr "Balise non implémentée" #: ../swftypes.h:647 msgid "Unsigned bit field wider than 32 bit not supported" msgstr "" #: ../scripting/actions.cpp:405 msgid "Unsupported ActionCode " msgstr "ActionCode non supporté " #: ../swftypes.cpp:907 msgid "Unsupported Filter Id " msgstr "" #: ../parsing/tags.cpp:209 msgid "Unsupported tag type " msgstr "Type de balise non supporté " #: ../backends/rendering.cpp:473 msgid "Vertex shader compilation " msgstr "" #: ../backends/rendering.cpp:519 msgid "Video card does not support OpenGL 2.0... Aborting" msgstr "La carte graphique ne supporte pas OpenGL 2.0... Annulation" #: ../backends/decoder.cpp:40 msgid "Video frame size " msgstr "Taille de cadre video" #: ../scripting/abc_opcodes.cpp:1596 ../scripting/abc_opcodes.cpp:1680 msgid "We got a Undefined function" msgstr "" #: ../scripting/abc_opcodes.cpp:825 ../scripting/abc_opcodes.cpp:829 msgid "We got a Undefined function " msgstr "" #: ../scripting/abc_opcodes.cpp:303 msgid "We got a Undefined function on obj " msgstr "" #: ../scripting/abc_opcodes.cpp:285 msgid "We got a function not yet valid" msgstr "" #: ../scripting/abc_opcodes.cpp:1322 ../scripting/flashsystem.cpp:96 #: ../scripting/flashutils.cpp:333 msgid "We got an object not yet valid" msgstr "" #: ../backends/input.cpp:190 ../backends/input.cpp:266 msgid "We still miss " msgstr "" #: ../scripting/flashevents.cpp:292 msgid "Weird event reregistration" msgstr "" #: ../backends/rendering.cpp:259 msgid "Window resize not supported in plugin" msgstr "Redimensionnement de fenêtre non supporté dans le greffon" #: ../asobject.cpp:704 msgid "[" msgstr "[" #: ../scripting/abc_opcodes.cpp:169 ../scripting/abc_opcodes.cpp:174 msgid "]" msgstr "]" #: ../asobject.cpp:704 ../scripting/abc_opcodes.cpp:921 #: ../scripting/abc_opcodes.cpp:927 ../scripting/abc_opcodes.cpp:933 msgid "] " msgstr "] " #: ../scripting/abc_opcodes.cpp:164 msgid "] (" msgstr "] (" #: ../scripting/abc_opcodes.cpp:159 ../scripting/abc_opcodes.cpp:179 msgid "] (int)= " msgstr "] (int)= " #: ../scripting/abc_opcodes.cpp:184 msgid "] = " msgstr "] = " #: ../scripting/abc_opcodes.cpp:948 ../scripting/abc_opcodes.cpp:964 #: ../scripting/abc_opcodes.cpp:973 ../scripting/abc_opcodes.cpp:995 #: ../scripting/abc_opcodes.cpp:1003 ../scripting/abc_opcodes.cpp:1012 #: ../scripting/abc_opcodes.cpp:1039 ../scripting/abc_opcodes.cpp:1047 #: ../scripting/abc_opcodes.cpp:1055 msgid "add " msgstr "" #: ../scripting/abc_opcodes.cpp:1846 msgid "asTypelate" msgstr "" #: ../scripting/abc_opcodes.cpp:44 msgid "bitAnd_oi " msgstr "" #: ../scripting/abc_opcodes.cpp:35 msgid "bitAnd_oo " msgstr "" #: ../scripting/abc_opcodes.cpp:223 msgid "bitNot " msgstr "" #: ../scripting/abc_opcodes.cpp:242 ../scripting/abc_opcodes.cpp:252 msgid "bitOr " msgstr "" #: ../scripting/abc_opcodes.cpp:233 msgid "bitXor " msgstr "" #: ../scripting/abc_codesynt.cpp:751 msgid "block analysis: branches" msgstr "" #: ../scripting/abc_codesynt.cpp:713 msgid "block analysis: kill" msgstr "" #: ../scripting/abc_opcodes.cpp:2351 msgid "call " msgstr "" #: ../scripting/abc_opcodes.cpp:748 msgid "callPropVoid " msgstr "" #: ../scripting/abc_opcodes.cpp:263 msgid "callProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:1568 msgid "callSuper " msgstr "" #: ../scripting/abc_opcodes.cpp:1651 msgid "callSuperVoid " msgstr "" #: ../scripting/toplevel.cpp:2028 msgid "capturing groups " msgstr "" #: ../scripting/abc_opcodes.cpp:149 msgid "coerce " msgstr "" #: ../scripting/abc_opcodes.cpp:133 msgid "coerce_a" msgstr "" #: ../scripting/abc_opcodes.cpp:143 msgid "coerce_s" msgstr "" #: ../scripting/abc_opcodes.cpp:593 msgid "construct " msgstr "" #: ../scripting/abc_opcodes.cpp:682 msgid "constructGenericType " msgstr "" #: ../scripting/abc_opcodes.cpp:1957 msgid "constructProp " msgstr "" #: ../scripting/abc_opcodes.cpp:1399 msgid "constructSuper " msgstr "" #: ../scripting/abc_opcodes.cpp:87 msgid "convert_b" msgstr "" #: ../scripting/abc_opcodes.cpp:74 msgid "convert_d" msgstr "" #: ../scripting/abc_opcodes.cpp:103 msgid "convert_i" msgstr "" #: ../scripting/abc_opcodes.cpp:95 msgid "convert_u" msgstr "" #: ../scripting/abc_codesynt.cpp:784 ../scripting/abc_codesynt.cpp:2248 msgid "count " msgstr "" #: ../scripting/flashdisplay.cpp:505 msgid "createEmptyMovieClip" msgstr "" #: ../scripting/abc.cpp:876 msgid "dMultiname to String not yet implemented for this kind " msgstr "" #: ../scripting/abc_interpreter.cpp:1233 msgid "debug" msgstr "" #: ../scripting/abc_codesynt.cpp:37 msgid "debug_d " msgstr "" #: ../scripting/abc_codesynt.cpp:42 msgid "debug_i " msgstr "" #: ../scripting/abc_interpreter.cpp:1255 msgid "debugfile" msgstr "" #: ../scripting/abc_interpreter.cpp:1247 msgid "debugline" msgstr "" #: ../scripting/abc_opcodes.cpp:465 msgid "decrement" msgstr "" #: ../scripting/abc_opcodes.cpp:474 msgid "decrement_i" msgstr "" #: ../scripting/abc_codesynt.cpp:781 ../scripting/abc_codesynt.cpp:2245 msgid "default " msgstr "défaut" #: ../scripting/abc_opcodes.cpp:2386 msgid "deleteProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:437 msgid "divide " msgstr "" #: ../scripting/abc_opcodes.cpp:429 msgid "divide: HACK" msgstr "" #: ../scripting/abc_codesynt.cpp:1359 ../scripting/abc_codesynt.cpp:3931 #: ../scripting/abc_interpreter.cpp:1262 msgid "dump " msgstr "" #: ../scripting/abc_opcodes.cpp:1183 msgid "dup: DONE" msgstr "" #: ../scripting/abc_opcodes.cpp:1137 msgid "equals " msgstr "" #: ../scripting/abc_opcodes.cpp:1467 msgid "findPropStrict " msgstr "" #: ../scripting/abc_opcodes.cpp:1430 msgid "findProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:458 msgid "getGlobalScope: " msgstr "" #: ../scripting/abc_opcodes.cpp:1342 msgid "getLex: " msgstr "" #: ../scripting/abc_interpreter.cpp:773 ../scripting/abc_interpreter.cpp:1210 msgid "getLocal " msgstr "" #: ../scripting/abc_opcodes.cpp:159 ../scripting/abc_opcodes.cpp:164 #: ../scripting/abc_opcodes.cpp:169 msgid "getLocal[" msgstr "" #: ../scripting/abc.cpp:306 msgid "getMultinameRTData not yet implemented for this kind " msgstr "" #: ../scripting/abc_opcodes.cpp:372 msgid "getProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:361 msgid "getProperty_i " msgstr "" #: ../scripting/abc_opcodes.cpp:2415 msgid "getScopeObject: " msgstr "" #: ../scripting/abc_opcodes.cpp:204 msgid "getSlot " msgstr "" #: ../scripting/abc_opcodes.cpp:1298 msgid "getSuper " msgstr "" #: ../scripting/toplevel.cpp:1463 msgid "getTimezoneOffset" msgstr "" #: ../backends/rendering.cpp:190 msgid "glX not present" msgstr "glX non présent" #: ../scripting/abc_opcodes.cpp:1521 msgid "greaterEquals" msgstr "" #: ../scripting/abc_opcodes.cpp:1510 msgid "greaterThan" msgstr "" #: ../scripting/abc_opcodes.cpp:2035 msgid "hasNext2 " msgstr "" #: ../scripting/abc_opcodes.cpp:1903 msgid "ifEq (" msgstr "" #: ../scripting/abc_opcodes.cpp:1943 msgid "ifFalse (" msgstr "" #: ../scripting/abc_opcodes.cpp:1252 msgid "ifGE (" msgstr "" #: ../scripting/abc_opcodes.cpp:1209 msgid "ifGT (" msgstr "" #: ../scripting/abc_opcodes.cpp:1232 msgid "ifLE (" msgstr "" #: ../scripting/abc_opcodes.cpp:496 msgid "ifLT (" msgstr "" #: ../scripting/abc_opcodes.cpp:520 msgid "ifLT_io " msgstr "" #: ../scripting/abc_opcodes.cpp:505 msgid "ifLT_oi" msgstr "" #: ../scripting/abc_opcodes.cpp:532 ../scripting/abc_opcodes.cpp:545 msgid "ifNE (" msgstr "" #: ../scripting/abc_opcodes.cpp:1262 msgid "ifNGE (" msgstr "" #: ../scripting/abc_opcodes.cpp:1221 msgid "ifNGT (" msgstr "" #: ../scripting/abc_opcodes.cpp:1242 msgid "ifNLE (" msgstr "" #: ../scripting/abc_opcodes.cpp:485 msgid "ifNLT (" msgstr "" #: ../scripting/abc_opcodes.cpp:1921 msgid "ifStrictEq " msgstr "" #: ../scripting/abc_opcodes.cpp:1927 msgid "ifStrictNE" msgstr "" #: ../scripting/abc_opcodes.cpp:846 msgid "ifTrue (" msgstr "" #: ../scripting/abc_opcodes.cpp:1933 msgid "in" msgstr "" #: ../scripting/abc_opcodes.cpp:578 msgid "incLocal_i " msgstr "" #: ../scripting/abc_opcodes.cpp:2130 msgid "increment_i" msgstr "" #: ../scripting/abc_opcodes.cpp:1547 msgid "initProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:1720 msgid "isType " msgstr "" #: ../scripting/abc_opcodes.cpp:1768 msgid "isType on non classed object " msgstr "" #: ../scripting/abc_opcodes.cpp:1782 msgid "isTypelate" msgstr "" #: ../scripting/abc_opcodes.cpp:1830 msgid "isTypelate on non classed object " msgstr "" #: ../scripting/abc_opcodes.cpp:840 msgid "jump " msgstr "" #: ../scripting/abc_opcodes.cpp:938 msgid "kill " msgstr "" #: ../scripting/abc_opcodes.cpp:1080 ../scripting/abc_opcodes.cpp:1091 msgid "lShift " msgstr "" #: ../scripting/abc_opcodes.cpp:111 msgid "label" msgstr "" #: ../scripting/abc_opcodes.cpp:1532 msgid "lessEquals" msgstr "" #: ../scripting/abc_opcodes.cpp:2334 msgid "lessThan" msgstr "" #: ../scripting/abc_opcodes.cpp:116 msgid "lookupswitch" msgstr "" #: ../scripting/abc_opcodes.cpp:859 msgid "modulo " msgstr "" #: ../scripting/abc_opcodes.cpp:572 msgid "multiply " msgstr "" #: ../scripting/abc_opcodes.cpp:562 msgid "multiply_oi " msgstr "" #: ../scripting/abc_opcodes.cpp:213 msgid "negate" msgstr "" #: ../scripting/abc_opcodes.cpp:2309 msgid "newActivation" msgstr "" #: ../scripting/abc_opcodes.cpp:2434 msgid "newArray " msgstr "" #: ../scripting/abc_opcodes.cpp:2428 msgid "newCatch " msgstr "" #: ../scripting/abc_opcodes.cpp:2200 msgid "newClass " msgstr "" #: ../scripting/abc_opcodes.cpp:2398 msgid "newFunction " msgstr "" #: ../scripting/abc_opcodes.cpp:2090 msgid "newObject " msgstr "" #: ../scripting/abc_opcodes.cpp:2164 msgid "nextName" msgstr "" #: ../scripting/abc_opcodes.cpp:2139 msgid "nextValue" msgstr "" #: ../parsing/tags.cpp:1364 ../parsing/tags.cpp:1531 msgid "no char to move at depth " msgstr "" #: ../scripting/abc_opcodes.cpp:1128 msgid "not" msgstr "" #: ../scripting/abc_opcodes.cpp:1888 msgid "not " msgstr "" #: ../scripting/abc.cpp:1184 msgid "not implement opcode 0x" msgstr "" #: ../scripting/abc_opcodes.cpp:1943 msgid "not taken" msgstr "" #: ../scripting/abc_opcodes.cpp:485 ../scripting/abc_opcodes.cpp:496 #: ../scripting/abc_opcodes.cpp:532 ../scripting/abc_opcodes.cpp:545 #: ../scripting/abc_opcodes.cpp:846 ../scripting/abc_opcodes.cpp:1209 #: ../scripting/abc_opcodes.cpp:1221 ../scripting/abc_opcodes.cpp:1232 #: ../scripting/abc_opcodes.cpp:1242 ../scripting/abc_opcodes.cpp:1252 #: ../scripting/abc_opcodes.cpp:1262 ../scripting/abc_opcodes.cpp:1903 msgid "not taken)" msgstr "" #: ../scripting/abc.cpp:1839 msgid "parsing s32" msgstr "" #: ../scripting/abc.cpp:1889 ../scripting/abc.cpp:1893 msgid "parsing u30" msgstr "" #: ../scripting/abc.cpp:1814 msgid "parsing u32 " msgstr "" #: ../scripting/abc_opcodes.cpp:154 msgid "pop: DONE" msgstr "" #: ../scripting/abc_opcodes.cpp:2327 msgid "popScope" msgstr "" #: ../thread_pool.cpp:68 msgid "pthread_join failed in ~ThreadPool" msgstr "" #: ../scripting/abc.cpp:989 msgid "pthread_join in ABCVm failed" msgstr "" #: ../scripting/abc_opcodes.cpp:553 msgid "pushByte " msgstr "" #: ../scripting/abc_opcodes.cpp:933 msgid "pushDouble [" msgstr "" #: ../scripting/abc_opcodes.cpp:1194 msgid "pushFalse" msgstr "" #: ../scripting/abc_opcodes.cpp:927 msgid "pushInt [" msgstr "" #: ../scripting/abc_opcodes.cpp:1200 msgid "pushNaN" msgstr "" #: ../scripting/abc_opcodes.cpp:127 msgid "pushNull" msgstr "" #: ../scripting/abc_opcodes.cpp:451 msgid "pushScope " msgstr "" #: ../scripting/abc_opcodes.cpp:189 msgid "pushShort " msgstr "" #: ../scripting/abc_opcodes.cpp:2422 msgid "pushString " msgstr "" #: ../scripting/abc_opcodes.cpp:1188 msgid "pushTrue" msgstr "" #: ../scripting/abc_opcodes.cpp:921 msgid "pushUInt [" msgstr "" #: ../scripting/abc_opcodes.cpp:121 msgid "pushUndefined" msgstr "" #: ../scripting/abc_opcodes.cpp:444 msgid "pushWith " msgstr "" #: ../scripting/abc_opcodes.cpp:1103 msgid "rShift " msgstr "" #: ../scripting/toplevel.cpp:2026 msgid "re: " msgstr "" #: ../scripting/abc_interpreter.cpp:636 msgid "returnValue " msgstr "" #: ../scripting/abc_interpreter.cpp:629 msgid "returnVoid" msgstr "" #: ../scripting/abc_interpreter.cpp:782 ../scripting/abc_interpreter.cpp:1222 msgid "setLocal " msgstr "" #: ../scripting/abc_opcodes.cpp:174 ../scripting/abc_opcodes.cpp:179 #: ../scripting/abc_opcodes.cpp:184 msgid "setLocal[" msgstr "" #: ../scripting/abc_opcodes.cpp:50 msgid "setProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:66 msgid "setProperty_i " msgstr "" #: ../scripting/abc_opcodes.cpp:195 msgid "setSlot " msgstr "" #: ../scripting/abc_opcodes.cpp:1277 msgid "setSuper " msgstr "" #: ../scripting/abc_opcodes.cpp:1174 msgid "strictEquals" msgstr "" #: ../scripting/abc_opcodes.cpp:914 msgid "subtract " msgstr "" #: ../scripting/abc_opcodes.cpp:889 ../scripting/abc_opcodes.cpp:906 msgid "subtract: HACK" msgstr "" #: ../scripting/abc_opcodes.cpp:880 msgid "subtract_do " msgstr "" #: ../scripting/abc_opcodes.cpp:896 msgid "subtract_io " msgstr "" #: ../scripting/abc_opcodes.cpp:869 msgid "subtract_oi " msgstr "" #: ../scripting/abc_opcodes.cpp:2304 msgid "swap" msgstr "" #: ../scripting/abc_codesynt.cpp:3287 msgid "synt add" msgstr "" #: ../scripting/abc_codesynt.cpp:3184 msgid "synt astypelate" msgstr "" #: ../scripting/abc_codesynt.cpp:3594 msgid "synt bitand" msgstr "" #: ../scripting/abc_codesynt.cpp:3270 msgid "synt bitnot" msgstr "" #: ../scripting/abc_codesynt.cpp:3627 msgid "synt bitor" msgstr "" #: ../scripting/abc_codesynt.cpp:3649 msgid "synt bitxor" msgstr "" #: ../scripting/abc_codesynt.cpp:2542 msgid "synt call" msgstr "" #: ../scripting/abc_codesynt.cpp:2578 msgid "synt callproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:2692 msgid "synt callpropvoid" msgstr "" #: ../scripting/abc_codesynt.cpp:2564 msgid "synt callsuper" msgstr "" #: ../scripting/abc_codesynt.cpp:2679 msgid "synt callsupervoid" msgstr "" #: ../scripting/abc_codesynt.cpp:3139 msgid "synt checkfilter" msgstr "" #: ../scripting/abc_codesynt.cpp:3149 msgid "synt coerce" msgstr "" #: ../scripting/abc_codesynt.cpp:3160 msgid "synt coerce_a" msgstr "" #: ../scripting/abc_codesynt.cpp:3174 msgid "synt coerce_s" msgstr "" #: ../scripting/abc_codesynt.cpp:2553 msgid "synt construct" msgstr "" #: ../scripting/abc_codesynt.cpp:2705 msgid "synt constructgenerictype" msgstr "" #: ../scripting/abc_codesynt.cpp:2666 msgid "synt constructprop" msgstr "" #: ../scripting/abc_codesynt.cpp:2655 msgid "synt constructsuper" msgstr "" #: ../scripting/abc_codesynt.cpp:3125 msgid "synt convert_b" msgstr "" #: ../scripting/abc_codesynt.cpp:3110 msgid "synt convert_d" msgstr "" #: ../scripting/abc_codesynt.cpp:3080 msgid "synt convert_i" msgstr "" #: ../scripting/abc_codesynt.cpp:3074 msgid "synt convert_s" msgstr "" #: ../scripting/abc_codesynt.cpp:3095 msgid "synt convert_u" msgstr "" #: ../scripting/abc_codesynt.cpp:3900 msgid "synt debug" msgstr "" #: ../scripting/abc_codesynt.cpp:3922 msgid "synt debugfile" msgstr "" #: ../scripting/abc_codesynt.cpp:3914 msgid "synt debugline" msgstr "" #: ../scripting/abc_codesynt.cpp:3228 msgid "synt decrement" msgstr "" #: ../scripting/abc_codesynt.cpp:3791 msgid "synt decrement_i" msgstr "" #: ../scripting/abc_codesynt.cpp:3025 msgid "synt deleteproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:3444 msgid "synt divide" msgstr "" #: ../scripting/abc_codesynt.cpp:2404 msgid "synt dup" msgstr "" #: ../scripting/abc_codesynt.cpp:3672 msgid "synt equals" msgstr "" #: ../scripting/abc_codesynt.cpp:2812 msgid "synt findproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:2779 msgid "synt findpropstrict" msgstr "" #: ../scripting/abc_codesynt.cpp:2757 msgid "synt getdescendants" msgstr "" #: ../scripting/abc_codesynt.cpp:2949 msgid "synt getglobalscope" msgstr "" #: ../scripting/abc_codesynt.cpp:2824 msgid "synt getlex" msgstr "" #: ../scripting/abc_codesynt.cpp:2882 msgid "synt getlocal" msgstr "" #: ../scripting/abc_codesynt.cpp:3833 msgid "synt getlocal_n " msgstr "" #: ../scripting/abc_codesynt.cpp:2968 msgid "synt getproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:2957 msgid "synt getscopeobject" msgstr "" #: ../scripting/abc_codesynt.cpp:3036 msgid "synt getslot" msgstr "" #: ../scripting/abc_codesynt.cpp:1630 msgid "synt getsuper" msgstr "" #: ../scripting/abc_codesynt.cpp:3738 msgid "synt greaterequals" msgstr "" #: ../scripting/abc_codesynt.cpp:3725 msgid "synt greaterthan" msgstr "" #: ../scripting/abc_codesynt.cpp:2497 msgid "synt hasnext2" msgstr "" #: ../scripting/abc_codesynt.cpp:1908 msgid "synt ifeq" msgstr "" #: ../scripting/abc_codesynt.cpp:1876 msgid "synt iffalse " msgstr "" #: ../scripting/abc_codesynt.cpp:2127 msgid "synt ifge" msgstr "" #: ../scripting/abc_codesynt.cpp:2093 msgid "synt ifgt" msgstr "" #: ../scripting/abc_codesynt.cpp:2055 msgid "synt ifle" msgstr "" #: ../scripting/abc_codesynt.cpp:2015 msgid "synt iflt " msgstr "" #: ../scripting/abc_codesynt.cpp:1965 msgid "synt ifne " msgstr "" #: ../scripting/abc_codesynt.cpp:1784 msgid "synt ifnge" msgstr "" #: ../scripting/abc_codesynt.cpp:1751 msgid "synt ifngt" msgstr "" #: ../scripting/abc_codesynt.cpp:1719 msgid "synt ifnle" msgstr "" #: ../scripting/abc_codesynt.cpp:1680 msgid "synt ifnlt" msgstr "" #: ../scripting/abc_codesynt.cpp:2161 msgid "synt ifstricteq" msgstr "" #: ../scripting/abc_codesynt.cpp:2193 msgid "synt ifstrictne" msgstr "" #: ../scripting/abc_codesynt.cpp:1837 msgid "synt iftrue" msgstr "" #: ../scripting/abc_codesynt.cpp:3762 msgid "synt in" msgstr "" #: ../scripting/abc_codesynt.cpp:3808 msgid "synt inclocal_i" msgstr "" #: ../scripting/abc_codesynt.cpp:3205 msgid "synt increment" msgstr "" #: ../scripting/abc_codesynt.cpp:3774 msgid "synt increment_i" msgstr "" #: ../scripting/abc_codesynt.cpp:3014 msgid "synt initproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:3751 msgid "synt istypelate" msgstr "" #: ../scripting/abc_codesynt.cpp:1821 msgid "synt jump " msgstr "" #: ../scripting/abc_codesynt.cpp:1654 msgid "synt kill " msgstr "" #: ../scripting/abc_codesynt.cpp:1672 msgid "synt label" msgstr "" #: ../scripting/abc_codesynt.cpp:3712 msgid "synt lessequals" msgstr "" #: ../scripting/abc_codesynt.cpp:3699 msgid "synt lessthan" msgstr "" #: ../scripting/abc_codesynt.cpp:774 ../scripting/abc_codesynt.cpp:2236 msgid "synt lookupswitch" msgstr "" #: ../scripting/abc_codesynt.cpp:3514 msgid "synt lshift" msgstr "" #: ../scripting/abc_codesynt.cpp:3474 msgid "synt modulo" msgstr "" #: ../scripting/abc_codesynt.cpp:3401 msgid "synt multiply" msgstr "" #: ../scripting/abc_codesynt.cpp:3195 msgid "synt negate" msgstr "" #: ../scripting/abc_codesynt.cpp:2738 msgid "synt newactivation" msgstr "" #: ../scripting/abc_codesynt.cpp:2727 msgid "synt newarray" msgstr "" #: ../scripting/abc_codesynt.cpp:2768 msgid "synt newcatch" msgstr "" #: ../scripting/abc_codesynt.cpp:2746 msgid "synt newclass" msgstr "" #: ../scripting/abc_codesynt.cpp:2531 msgid "synt newfunction" msgstr "" #: ../scripting/abc_codesynt.cpp:2716 msgid "synt newobject" msgstr "" #: ../scripting/abc_codesynt.cpp:2303 msgid "synt nextname" msgstr "" #: ../scripting/abc_codesynt.cpp:2332 msgid "synt nextvalue" msgstr "" #: ../scripting/abc_codesynt.cpp:3256 msgid "synt not" msgstr "" #: ../scripting/abc_codesynt.cpp:2393 msgid "synt pop" msgstr "" #: ../scripting/abc_codesynt.cpp:2295 msgid "synt popscope" msgstr "" #: ../scripting/abc_codesynt.cpp:2345 msgid "synt pushbyte" msgstr "" #: ../scripting/abc_codesynt.cpp:2472 msgid "synt pushdouble" msgstr "" #: ../scripting/abc_codesynt.cpp:2377 msgid "synt pushfalse" msgstr "" #: ../scripting/abc_codesynt.cpp:2440 msgid "synt pushint" msgstr "" #: ../scripting/abc_codesynt.cpp:2385 msgid "synt pushnan" msgstr "" #: ../scripting/abc_codesynt.cpp:2316 msgid "synt pushnull" msgstr "" #: ../scripting/abc_codesynt.cpp:2489 msgid "synt pushscope" msgstr "" #: ../scripting/abc_codesynt.cpp:2357 msgid "synt pushshort" msgstr "" #: ../scripting/abc_codesynt.cpp:2429 msgid "synt pushstring" msgstr "" #: ../scripting/abc_codesynt.cpp:2369 msgid "synt pushtrue" msgstr "" #: ../scripting/abc_codesynt.cpp:2456 msgid "synt pushuint" msgstr "" #: ../scripting/abc_codesynt.cpp:2324 msgid "synt pushundefined" msgstr "" #: ../scripting/abc_codesynt.cpp:2287 msgid "synt pushwith" msgstr "" #: ../scripting/abc_codesynt.cpp:2626 msgid "synt returnvalue" msgstr "" #: ../scripting/abc_codesynt.cpp:2604 msgid "synt returnvoid" msgstr "" #: ../scripting/abc_codesynt.cpp:3538 msgid "synt rshift" msgstr "" #: ../scripting/abc_codesynt.cpp:2928 msgid "synt setlocal " msgstr "" #: ../scripting/abc_codesynt.cpp:3878 msgid "synt setlocal_n " msgstr "" #: ../scripting/abc_codesynt.cpp:2835 msgid "synt setproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:3049 msgid "synt setslot" msgstr "" #: ../scripting/abc_codesynt.cpp:1641 msgid "synt setsuper" msgstr "" #: ../scripting/abc_codesynt.cpp:3689 msgid "synt strictequals" msgstr "" #: ../scripting/abc_codesynt.cpp:3348 msgid "synt subtract" msgstr "" #: ../scripting/abc_codesynt.cpp:2417 msgid "synt swap" msgstr "" #: ../scripting/abc_codesynt.cpp:1605 msgid "synt throw" msgstr "" #: ../scripting/abc_codesynt.cpp:3246 msgid "synt typeof" msgstr "" #: ../scripting/abc_codesynt.cpp:3559 msgid "synt urshift" msgstr "" #: ../scripting/abc_opcodes.cpp:1943 msgid "taken" msgstr "" #: ../scripting/abc_opcodes.cpp:485 ../scripting/abc_opcodes.cpp:496 #: ../scripting/abc_opcodes.cpp:532 ../scripting/abc_opcodes.cpp:545 #: ../scripting/abc_opcodes.cpp:846 ../scripting/abc_opcodes.cpp:1209 #: ../scripting/abc_opcodes.cpp:1221 ../scripting/abc_opcodes.cpp:1232 #: ../scripting/abc_opcodes.cpp:1242 ../scripting/abc_opcodes.cpp:1252 #: ../scripting/abc_opcodes.cpp:1262 ../scripting/abc_opcodes.cpp:1903 msgid "taken)" msgstr "" #: ../scripting/abc_opcodes.cpp:713 msgid "typeOf" msgstr "" #: ../scripting/abc_opcodes.cpp:1113 ../scripting/abc_opcodes.cpp:1122 msgid "urShift " msgstr "" #: ../backends/rendering.cpp:106 msgid "~RenderThread this=" msgstr "" #~ msgid " :: " #~ msgstr " ::" lightspark-0.7.2/i18n/lightspark.pot000066400000000000000000001616731212105246600173600ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2010-08-24 23:48-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: ../scripting/abc.cpp:925 msgid "\t" msgstr "" #: ../scripting/abc.cpp:913 msgid "\tFinal" msgstr "" #: ../scripting/abc.cpp:915 msgid "\tInterface" msgstr "" #: ../scripting/abc.cpp:917 msgid "\tProtectedNS " msgstr "" #: ../scripting/abc.cpp:911 msgid "\tSealed" msgstr "" #: ../asobject.cpp:704 ../scripting/abc_codesynt.cpp:789 #: ../scripting/abc_codesynt.cpp:2253 ../scripting/abc.cpp:1513 #: ../scripting/abc.cpp:1786 ../scripting/abc_opcodes.cpp:1888 msgid " " msgstr "" #: ../scripting/abc.cpp:1418 ../scripting/abc.cpp:1480 #: ../scripting/abc.cpp:1583 ../scripting/abc.cpp:1622 #: ../scripting/abc.cpp:1662 msgid " #" msgstr "" #: ../swf.cpp:65 ../swf.cpp:69 msgid " Length " msgstr "" #: ../asobject.cpp:82 ../asobject.cpp:165 msgid " and type " msgstr "" #: ../parsing/tags.cpp:52 msgid " at byte " msgstr "" #: ../parsing/tags.cpp:52 ../scripting/actions.cpp:405 msgid " bytes" msgstr "" #: ../scripting/actions.cpp:1175 msgid " constants" msgstr "" #: ../backends/input.cpp:190 ../backends/input.cpp:266 msgid " events" msgstr "" #: ../scripting/abc.cpp:1355 msgid " events missing before exit" msgstr "" #: ../parsing/tags.cpp:224 ../parsing/tags.cpp:229 msgid " expected: " msgstr "" #: ../backends/graphics.cpp:132 ../backends/graphics.cpp:174 #: ../backends/graphics.cpp:199 msgid " height=" msgstr "" #: ../scripting/abc.cpp:1576 msgid " id " msgstr "" #: ../scripting/flashnet.cpp:726 msgid " in FLV" msgstr "" #: ../scripting/abc_opcodes.cpp:1774 ../scripting/abc_opcodes.cpp:1837 #: ../scripting/abc_opcodes.cpp:1888 msgid " is " msgstr "" #: ../scripting/abc.cpp:1137 msgid " is not yet valid" msgstr "" #: ../scripting/abc_opcodes.cpp:2277 msgid " is not yet valid (as interface)" msgstr "" #: ../parsing/tags.cpp:1364 ../parsing/tags.cpp:1531 msgid " name " msgstr "" #: ../scripting/abc.cpp:1131 msgid " not found in global" msgstr "" #: ../scripting/abc_opcodes.cpp:667 msgid " not supported in construct" msgstr "" #: ../swftypes.cpp:1087 msgid " of action data" msgstr "" #: ../scripting/abc_opcodes.cpp:349 ../scripting/abc_opcodes.cpp:783 msgid " on obj " msgstr "" #: ../scripting/abc_opcodes.cpp:825 msgid " on obj type " msgstr "" #: ../scripting/abc_opcodes.cpp:388 msgid " on type " msgstr "" #: ../backends/graphics.cpp:53 msgid " openGL errors" msgstr "" #: ../backends/rendering.cpp:285 ../backends/rendering.cpp:760 msgid " renderings" msgstr "" #: ../scripting/abc_codesynt.cpp:1482 msgid " should be intrinsic" msgstr "" #: ../threading.cpp:74 msgid " times" msgstr "" #: ../asobject.cpp:185 msgid " to float" msgstr "" #: ../asobject.cpp:178 msgid " to int" msgstr "" #: ../scripting/abc.cpp:1729 ../scripting/abc.cpp:1749 #: ../scripting/abc.cpp:1755 msgid " type " msgstr "" #: ../scripting/abc.cpp:1576 msgid " type Class name " msgstr "" #: ../scripting/abc.cpp:1755 msgid " vindex 0 " msgstr "" #: ../threading.cpp:74 msgid " waited " msgstr "" #: ../parsing/tags.cpp:52 ../scripting/actions.cpp:405 msgid " with length " msgstr "" #: ../parsing/tags.cpp:1325 ../parsing/tags.cpp:1492 msgid " with name " msgstr "" #: ../scripting/flashutils.cpp:326 msgid "' not found." msgstr "" #: ../scripting/abc_opcodes.cpp:164 msgid ") " msgstr "" #: ../parsing/tags.cpp:1815 msgid ", ScriptTimeoutSeconds: " msgstr "" #: ../parsing/tags.cpp:1851 msgid ", password: " msgstr "" #: ../scripting/abc_opcodes.cpp:1332 ../scripting/abc_opcodes.cpp:1373 msgid ", pushing Undefined" msgstr "" #: ../scripting/abc.cpp:1122 msgid ". Not binding" msgstr "" #: ../parsing/tags.cpp:224 ../parsing/tags.cpp:229 msgid ". Size=" msgstr "" #: ../swftypes.cpp:667 ../swftypes.cpp:699 ../backends/rendering.cpp:581 msgid "... Aborting" msgstr "" #: ../scripting/abc.cpp:1976 msgid "0 not allowed" msgstr "" #: ../scripting/abc_interpreter.cpp:773 ../scripting/abc_interpreter.cpp:1210 msgid ": " msgstr "" #: ../scripting/abc.cpp:1418 ../scripting/abc.cpp:1444 #: ../scripting/abc.cpp:1449 ../scripting/abc.cpp:1475 #: ../scripting/abc.cpp:1480 ../scripting/abc.cpp:1506 #: ../scripting/abc.cpp:1576 ../scripting/abc.cpp:1583 #: ../scripting/abc.cpp:1617 ../scripting/abc.cpp:1622 #: ../scripting/abc.cpp:1657 ../scripting/abc.cpp:1662 #: ../scripting/abc.cpp:1698 msgid "::" msgstr "" #: ../scripting/abc_opcodes.cpp:1080 ../scripting/abc_opcodes.cpp:1091 msgid "<<" msgstr "" #: ../scripting/abc_opcodes.cpp:1103 ../scripting/abc_opcodes.cpp:1113 #: ../scripting/abc_opcodes.cpp:1122 msgid ">>" msgstr "" #: ../scripting/abc.cpp:78 msgid "ABC Exec " msgstr "" #: ../scripting/abc.cpp:887 msgid "ABCVm version " msgstr "" #: ../scripting/toplevel.cpp:2099 msgid "ASString::charCodeAt not really implemented" msgstr "" #: ../scripting/actions.cpp:83 ../scripting/actions.cpp:150 msgid "AVM1 not supported" msgstr "" #: ../scripting/actions.h:311 msgid "ActionAdd2" msgstr "" #: ../scripting/actions.h:598 msgid "ActionAsciiToChar" msgstr "" #: ../scripting/actions.h:535 msgid "ActionBitAnd" msgstr "" #: ../scripting/actions.h:556 msgid "ActionBitLShift" msgstr "" #: ../scripting/actions.h:542 msgid "ActionBitOr" msgstr "" #: ../scripting/actions.h:563 msgid "ActionBitRShift" msgstr "" #: ../scripting/actions.h:549 msgid "ActionBitXor" msgstr "" #: ../scripting/actions.h:402 msgid "ActionCallFunction" msgstr "" #: ../scripting/actions.h:395 msgid "ActionCallMethod" msgstr "" #: ../scripting/actions.h:528 msgid "ActionCastOp" msgstr "" #: ../scripting/actions.h:409 msgid "ActionCloneSprite" msgstr "" #: ../scripting/actions.cpp:1397 ../scripting/actions.h:263 msgid "ActionConstantPool" msgstr "" #: ../scripting/actions.h:437 msgid "ActionDecrement" msgstr "" #: ../scripting/actions.h:146 msgid "ActionDefineFunction" msgstr "" #: ../scripting/actions.h:184 msgid "ActionDefineFunction2" msgstr "" #: ../scripting/actions.h:353 msgid "ActionDefineLocal" msgstr "" #: ../scripting/actions.h:458 msgid "ActionDelete" msgstr "" #: ../scripting/actions.h:325 msgid "ActionDivide" msgstr "" #: ../scripting/actions.h:479 msgid "ActionEnumerate" msgstr "" #: ../scripting/actions.h:507 msgid "ActionEnumerate2" msgstr "" #: ../scripting/actions.h:612 msgid "ActionEquals2" msgstr "" #: ../scripting/actions.h:430 msgid "ActionExtends" msgstr "" #: ../scripting/actions.h:110 msgid "ActionGetMember" msgstr "" #: ../scripting/actions.h:339 msgid "ActionGetProperty" msgstr "" #: ../scripting/actions.h:486 msgid "ActionGetTime" msgstr "" #: ../scripting/actions.h:252 msgid "ActionGetURL" msgstr "" #: ../scripting/actions.h:241 msgid "ActionGetURL2" msgstr "" #: ../scripting/actions.h:647 msgid "ActionGetVariable" msgstr "" #: ../scripting/actions.cpp:1408 ../scripting/actions.h:283 msgid "ActionGoToLabel" msgstr "" #: ../scripting/actions.h:231 msgid "ActionGotoFrame" msgstr "" #: ../scripting/actions.h:577 msgid "ActionGreater" msgstr "" #: ../scripting/actions.h:221 msgid "ActionIf" msgstr "" #: ../scripting/actions.h:423 msgid "ActionImplementsOp" msgstr "" #: ../scripting/actions.h:570 msgid "ActionIncrement" msgstr "" #: ../scripting/actions.h:465 msgid "ActionInitArray" msgstr "" #: ../scripting/actions.h:444 msgid "ActionInitObject" msgstr "" #: ../scripting/actions.h:493 msgid "ActionInstanceOf" msgstr "" #: ../scripting/actions.h:201 msgid "ActionJump" msgstr "" #: ../scripting/actions.cpp:999 msgid "ActionJump: " msgstr "" #: ../scripting/actions.h:591 msgid "ActionLess2" msgstr "" #: ../scripting/actions.h:318 msgid "ActionModulo" msgstr "" #: ../scripting/actions.h:360 msgid "ActionMultiply" msgstr "" #: ../scripting/actions.h:451 msgid "ActionNewMethod" msgstr "" #: ../scripting/actions.h:304 msgid "ActionNewObject" msgstr "" #: ../scripting/actions.h:388 msgid "ActionNot" msgstr "" #: ../scripting/actions.h:124 msgid "ActionPlay" msgstr "" #: ../scripting/actions.h:374 msgid "ActionPop" msgstr "" #: ../scripting/actions.cpp:1314 msgid "ActionPush" msgstr "" #: ../scripting/actions.h:332 msgid "ActionPushDuplicate" msgstr "" #: ../scripting/actions.h:346 msgid "ActionReturn" msgstr "" #: ../scripting/actions.h:117 msgid "ActionSetMember" msgstr "" #: ../scripting/actions.h:500 msgid "ActionSetProperty" msgstr "" #: ../scripting/actions.h:273 msgid "ActionSetTarget" msgstr "" #: ../scripting/actions.h:633 msgid "ActionSetTarget2" msgstr "" #: ../scripting/actions.h:626 msgid "ActionSetVariable" msgstr "" #: ../scripting/actions.h:131 msgid "ActionStop" msgstr "" #: ../scripting/actions.h:663 msgid "ActionStoreRegister" msgstr "" #: ../scripting/actions.h:605 msgid "ActionStrictEquals" msgstr "" #: ../scripting/actions.h:290 msgid "ActionStringAdd" msgstr "" #: ../scripting/actions.h:619 msgid "ActionStringEquals" msgstr "" #: ../scripting/actions.h:297 msgid "ActionStringExtract" msgstr "" #: ../scripting/actions.h:584 msgid "ActionStringGreater" msgstr "" #: ../scripting/actions.h:367 msgid "ActionSubtract" msgstr "" #: ../scripting/actions.cpp:859 ../scripting/actions.h:381 msgid "ActionToInteger" msgstr "" #: ../scripting/actions.h:521 msgid "ActionToNumber" msgstr "" #: ../scripting/actions.h:514 msgid "ActionToString" msgstr "" #: ../scripting/actions.h:416 msgid "ActionTrace" msgstr "" #: ../scripting/actions.h:472 msgid "ActionTypeOf" msgstr "" #: ../scripting/actions.h:211 msgid "ActionWith" msgstr "" #: ../scripting/abc_opcodes.cpp:1025 msgid "Add between integer and " msgstr "" #: ../scripting/abc_opcodes.cpp:980 msgid "Add between types " msgstr "" #: ../scripting/abc_opcodes.cpp:1068 msgid "Add between types number and " msgstr "" #: ../asobject.cpp:114 msgid "Add buildTraits for class " msgstr "" #: ../scripting/toplevel.cpp:3046 msgid "Array to bool" msgstr "" #: ../scripting/toplevel.cpp:179 msgid "Array::filter STUB" msgstr "" #: ../scripting/abc_opcodes.cpp:402 ../scripting/abc_opcodes.cpp:1381 msgid "Attaching this to function " msgstr "" #: ../backends/decoder.cpp:446 msgid "Audio channels " msgstr "" #: ../backends/decoder.cpp:438 msgid "Audio sample rate " msgstr "" #: ../scripting/abc.cpp:109 msgid "Binding " msgstr "" #: ../scripting/abc.cpp:1037 msgid "Binding of " msgstr "" #: ../scripting/toplevel.cpp:3079 msgid "Boolean conversion for type " msgstr "" #: ../scripting/toplevel.cpp:3031 msgid "Boolean to bool " msgstr "" #: ../scripting/abc_opcodes.cpp:2232 msgid "Building class traits" msgstr "" #: ../scripting/abc.cpp:1286 msgid "Building entry script traits: " msgstr "" #: ../scripting/abc.cpp:1067 ../scripting/toplevel.cpp:2725 msgid "Building instance traits" msgstr "" #: ../scripting/abc_opcodes.cpp:641 ../scripting/abc_opcodes.cpp:2002 msgid "Building method traits" msgstr "" #: ../scripting/abc.cpp:1264 msgid "Building script traits: " msgstr "" #: ../scripting/toplevel.cpp:2616 msgid "Building traits for " msgstr "" #: ../parsing/tags_stub.cpp:100 msgid "CSMTextSettingsTag" msgstr "" #: ../backends/netutils.cpp:278 msgid "CURL not enabled in this build. Downloader will always fail." msgstr "" #: ../scripting/toplevel.cpp:459 msgid "Called ASXML::load " msgstr "" #: ../scripting/toplevel.cpp:134 msgid "Called Array constructor" msgstr "" #: ../scripting/toplevel.cpp:426 msgid "Called MovieClipLoader constructor" msgstr "" #: ../scripting/toplevel.cpp:432 msgid "Called MovieClipLoader::addListener" msgstr "" #: ../scripting/toplevel.cpp:444 msgid "Called XML constructor" msgstr "" #: ../scripting/flashdisplay.cpp:524 msgid "Called swapDepths" msgstr "" #: ../scripting/abc_opcodes.cpp:2292 msgid "Calling Class init " msgstr "" #: ../scripting/toplevel.cpp:2660 msgid "Calling Instance init " msgstr "" #: ../scripting/abc_opcodes.cpp:1710 msgid "Calling an undefined function" msgstr "" #: ../scripting/abc_opcodes.cpp:349 ../scripting/abc_opcodes.cpp:783 #: ../scripting/abc_opcodes.cpp:1635 msgid "Calling an undefined function " msgstr "" #: ../scripting/toplevel.cpp:2818 msgid "Calling interface init for " msgstr "" #: ../asobject.cpp:596 ../asobject.cpp:639 ../asobject.cpp:864 msgid "Calling the getter" msgstr "" #: ../asobject.cpp:592 msgid "Calling the getter on type " msgstr "" #: ../asobject.cpp:352 ../asobject.cpp:385 msgid "Calling the setter" msgstr "" #: ../scripting/toplevel.cpp:1674 ../scripting/toplevel.cpp:1760 msgid "Calling with closure " msgstr "" #: ../asobject.cpp:178 ../asobject.cpp:185 msgid "Cannot convert object of type " msgstr "" #: ../plugin/plugin.cpp:351 msgid "Cannot handle UTF8 URLs" msgstr "" #: ../scripting/abc_opcodes.cpp:586 msgid "Cannot increment type " msgstr "" #: ../backends/rendering.cpp:514 msgid "Cannot initialize GLEW: cause " msgstr "" #: ../scripting/abc_opcodes.cpp:1726 msgid "Cannot retrieve type" msgstr "" #: ../scripting/abc_codesynt.cpp:789 ../scripting/abc_codesynt.cpp:2253 msgid "Case " msgstr "" #: ../scripting/abc_opcodes.cpp:691 msgid "Check" msgstr "" #: ../swf.cpp:528 msgid "Child process creation failed, lightspark continues" msgstr "" #: ../scripting/abc.cpp:908 ../scripting/abc.cpp:1131 #: ../scripting/abc.cpp:1137 ../scripting/abc_opcodes.cpp:2277 msgid "Class " msgstr "" #: ../scripting/abc.cpp:1576 msgid "Class slot " msgstr "" #: ../scripting/toplevel.cpp:3041 msgid "Class to bool" msgstr "" #: ../scripting/actions.cpp:461 msgid "CodeSize not consistent" msgstr "" #: ../scripting/actions.cpp:578 msgid "CodeSize not consistent with file offset " msgstr "" #: ../swf.cpp:69 msgid "Compressed SWF file: Version " msgstr "" #: ../backends/sound.cpp:258 msgid "Connection to PulseAudio server failed" msgstr "" #: ../scripting/abc.cpp:1729 msgid "Const " msgstr "" #: ../scripting/abc.cpp:1542 msgid "Constant kind " msgstr "" #: ../scripting/actions.cpp:1175 msgid "ConstantPool: Reading " msgstr "" #: ../scripting/abc_opcodes.cpp:610 ../scripting/abc_opcodes.cpp:700 #: ../scripting/abc_opcodes.cpp:1985 msgid "Constructing" msgstr "" #: ../scripting/abc.cpp:66 msgid "Corrupted ABC data: missing " msgstr "" #: ../backends/rendering.cpp:203 msgid "Could not find any GLX configuration" msgstr "" #: ../swf.cpp:607 msgid "Creating VM" msgstr "" #: ../scripting/toplevel.cpp:129 msgid "Creating array of length " msgstr "" #: ../backends/input.cpp:39 msgid "Creating input thread" msgstr "" #: ../scripting/abc_opcodes.cpp:1413 msgid "Cur prototype name " msgstr "" #: ../parsing/tags.cpp:1820 msgid "DebugIDTag Tag" msgstr "" #: ../parsing/tags.cpp:1825 msgid "DebugId " msgstr "" #: ../parsing/tags.cpp:1840 msgid "Debugger enabled, password: " msgstr "" #: ../parsing/tags.cpp:1851 msgid "Debugger enabled, reserved: " msgstr "" #: ../scripting/abc_opcodes.cpp:1387 ../scripting/abc_opcodes.cpp:1978 msgid "Deferred definition of property " msgstr "" #: ../parsing/tags.cpp:1757 msgid "DefineBinaryDataTag" msgstr "" #: ../parsing/tags_stub.cpp:76 msgid "DefineBitsJPEG2Tag Tag" msgstr "" #: ../parsing/tags.cpp:670 msgid "DefineBitsLossless2Tag::Render" msgstr "" #: ../parsing/tags.cpp:1672 msgid "DefineButton2Tag::Render" msgstr "" #: ../parsing/tags.cpp:266 msgid "DefineEditTextTag ID " msgstr "" #: ../parsing/tags.cpp:307 msgid "DefineEditTextTag: Render" msgstr "" #: ../parsing/tags.cpp:440 msgid "DefineFont" msgstr "" #: ../parsing/tags.cpp:465 msgid "DefineFont2" msgstr "" #: ../parsing/tags.cpp:554 msgid "DefineFont3" msgstr "" #: ../parsing/tags_stub.cpp:70 msgid "DefineFontAlignZonesTag Tag" msgstr "" #: ../parsing/tags_stub.cpp:40 msgid "DefineFontInfo Tag" msgstr "" #: ../parsing/tags_stub.cpp:64 msgid "DefineFontNameTag Tag" msgstr "" #: ../parsing/tags_stub.cpp:83 msgid "DefineScalingGridTag Tag on ID " msgstr "" #: ../parsing/tags_stub.cpp:94 msgid "DefineSceneAndFrameLabelDataTag" msgstr "" #: ../parsing/tags.cpp:867 msgid "DefineShape2Tag" msgstr "" #: ../parsing/tags.cpp:874 msgid "DefineShape3Tag" msgstr "" #: ../parsing/tags.cpp:881 msgid "DefineShape4Tag" msgstr "" #: ../parsing/tags.cpp:860 msgid "DefineShapeTag" msgstr "" #: ../parsing/tags.cpp:1785 msgid "DefineSound Tag" msgstr "" #: ../parsing/tags.cpp:343 msgid "DefineSprite ID: " msgstr "" #: ../parsing/tags.cpp:676 msgid "DefineText ID " msgstr "" #: ../parsing/tags.cpp:750 msgid "DefineText Render" msgstr "" #: ../parsing/tags.cpp:1730 msgid "DefineVideoStreamTag" msgstr "" #: ../parsing/tags.cpp:1741 msgid "DefineVideoStreamTag Render" msgstr "" #: ../scripting/actions.cpp:433 msgid "Defining function " msgstr "" #: ../scripting/actions.cpp:538 msgid "Defining function2 " msgstr "" #: ../scripting/flashutils.cpp:326 msgid "Definition for '" msgstr "" #: ../plugin/plugin.cpp:436 msgid "DestroyStream on main stream?" msgstr "" #: ../scripting/abc.cpp:59 msgid "DoABCTag Name: " msgstr "" #: ../scripting/actions.cpp:54 msgid "DoActionTag" msgstr "" #: ../scripting/actions.cpp:121 msgid "DoInitActionTag" msgstr "" #: ../backends/netutils.cpp:123 msgid "Downloaded file bigger than buffer: " msgstr "" #: ../scripting/abc.cpp:1206 msgid "Empty stack" msgstr "" #: ../parsing/tags.cpp:1845 msgid "EnableDebugger2Tag Tag" msgstr "" #: ../parsing/tags.cpp:1836 msgid "EnableDebuggerTag Tag" msgstr "" #: ../scripting/abc.cpp:1475 ../scripting/abc.cpp:1617 msgid "End Getter trait: " msgstr "" #: ../scripting/abc.cpp:1444 ../scripting/abc.cpp:1698 msgid "End Method trait: " msgstr "" #: ../scripting/abc.cpp:1506 ../scripting/abc.cpp:1657 msgid "End Setter trait: " msgstr "" #: ../scripting/actions.cpp:447 ../scripting/actions.cpp:563 msgid "End action in function" msgstr "" #: ../scripting/abc_opcodes.cpp:2297 msgid "End of Class init " msgstr "" #: ../scripting/abc.cpp:1299 msgid "End of Entry Point" msgstr "" #: ../scripting/abc.cpp:1039 msgid "End of binding of " msgstr "" #: ../scripting/abc_opcodes.cpp:2378 msgid "End of call " msgstr "" #: ../scripting/abc_opcodes.cpp:1638 msgid "End of callSuper " msgstr "" #: ../scripting/abc_opcodes.cpp:1712 msgid "End of callSuperVoid " msgstr "" #: ../scripting/abc_opcodes.cpp:343 ../scripting/abc_opcodes.cpp:353 #: ../scripting/abc_opcodes.cpp:817 ../scripting/abc_opcodes.cpp:835 msgid "End of calling " msgstr "" #: ../scripting/abc_opcodes.cpp:706 msgid "End of constructing" msgstr "" #: ../scripting/abc_opcodes.cpp:674 ../scripting/abc_opcodes.cpp:2030 msgid "End of constructing " msgstr "" #: ../scripting/abc_opcodes.cpp:1391 ../scripting/abc_opcodes.cpp:1982 msgid "End of deferred definition of property " msgstr "" #: ../scripting/abc.cpp:1140 ../scripting/abc_opcodes.cpp:2280 msgid "End of deferred init of class " msgstr "" #: ../asobject.cpp:603 ../asobject.cpp:643 ../asobject.cpp:869 msgid "End of getter" msgstr "" #: ../swf.cpp:828 msgid "End of parsing @ " msgstr "" #: ../asobject.cpp:363 ../asobject.cpp:392 msgid "End of setter" msgstr "" #: ../scripting/abc_opcodes.cpp:1420 msgid "End super construct " msgstr "" #: ../parsing/tags.cpp:392 msgid "EndDefineSprite ID: " msgstr "" #: ../parsing/tags.cpp:56 msgid "EndTag at position " msgstr "" #: ../asobject.cpp:165 msgid "Equal comparison between type " msgstr "" #: ../scripting/abc.cpp:1369 msgid "Error in VM " msgstr "" #: ../parsing/tags.cpp:224 ../parsing/tags.cpp:229 msgid "Error while reading tag " msgstr "" #: ../scripting/toplevel.cpp:2266 msgid "Error.getStackTrace not yet implemented." msgstr "" #: ../scripting/flashevents.cpp:323 msgid "Event not found" msgstr "" #: ../swf.cpp:870 msgid "Exception in ParseThread " msgstr "" #: ../backends/rendering.cpp:402 ../backends/rendering.cpp:894 msgid "Exception in RenderThread " msgstr "" #: ../swf.cpp:1102 msgid "Exception in RootMovieClip::tick " msgstr "" #: ../thread_pool.cpp:108 msgid "Exception in ThreadPool " msgstr "" #: ../scripting/flashnet.cpp:766 msgid "Exception in reading: " msgstr "" #: ../scripting/actions.cpp:701 msgid "Exec: ActionBitAnd" msgstr "" #: ../scripting/actions.cpp:716 msgid "Exec: ActionBitLShift" msgstr "" #: ../scripting/actions.cpp:706 msgid "Exec: ActionBitOr" msgstr "" #: ../scripting/actions.cpp:721 msgid "Exec: ActionBitRShift" msgstr "" #: ../scripting/actions.cpp:711 msgid "Exec: ActionBitXor" msgstr "" #: ../scripting/actions.cpp:741 msgid "Exec: ActionCastOp" msgstr "" #: ../scripting/actions.cpp:797 msgid "Exec: ActionCloneSprite" msgstr "" #: ../scripting/actions.cpp:654 msgid "Exec: ActionDecrement" msgstr "" #: ../scripting/actions.cpp:1005 msgid "Exec: ActionDelete" msgstr "" #: ../scripting/actions.cpp:681 msgid "Exec: ActionEnumerate" msgstr "" #: ../scripting/actions.cpp:726 msgid "Exec: ActionEnumerate2" msgstr "" #: ../scripting/actions.cpp:686 msgid "Exec: ActionGetTime" msgstr "" #: ../scripting/actions.cpp:696 msgid "Exec: ActionImplementsOp" msgstr "" #: ../scripting/actions.cpp:1086 msgid "Exec: ActionInitArray" msgstr "" #: ../scripting/actions.cpp:1091 msgid "Exec: ActionInitObject" msgstr "" #: ../scripting/actions.cpp:691 msgid "Exec: ActionInstanceOf" msgstr "" #: ../scripting/actions.cpp:1010 msgid "Exec: ActionNewMethod" msgstr "" #: ../scripting/actions.cpp:586 msgid "Exec: ActionPushDuplicate" msgstr "" #: ../scripting/actions.cpp:1015 ../scripting/actions.cpp:1020 msgid "Exec: ActionStringAdd" msgstr "" #: ../scripting/actions.cpp:1096 msgid "Exec: ActionStringEquals" msgstr "" #: ../scripting/actions.cpp:1025 msgid "Exec: ActionStringExtract" msgstr "" #: ../scripting/actions.cpp:772 msgid "Exec: ActionStringGreater" msgstr "" #: ../scripting/actions.cpp:736 msgid "Exec: ActionToNumber" msgstr "" #: ../scripting/actions.cpp:731 msgid "Exec: ActionToString" msgstr "" #: ../scripting/actions.cpp:1147 msgid "Exec: ActionToggleQuality" msgstr "" #: ../scripting/actions.cpp:802 msgid "Exec: ActionTrace" msgstr "" #: ../scripting/actions.cpp:676 msgid "Exec: ActionTypeOf" msgstr "" #: ../scripting/actions.cpp:1319 msgid "Exec: ActionWith" msgstr "" #: ../swf.cpp:561 msgid "Execve failed, content will not be rendered" msgstr "" #: ../scripting/actions.cpp:37 msgid "ExportAssetsTag Tag" msgstr "" #: ../parsing/flv.cpp:38 msgid "FLV file: Version " msgstr "" #: ../backends/rendering.cpp:909 msgid "FPS: " msgstr "" #: ../scripting/toplevel.cpp:2680 msgid "Failure in reference counting" msgstr "" #: ../backends/rendering.cpp:285 ../backends/rendering.cpp:760 msgid "Faking " msgstr "" #: ../backends/rendering.cpp:199 msgid "Falling back to no double buffering" msgstr "" #: ../parsing/tags.cpp:168 msgid "FileAttributes tag not in the beginning" msgstr "" #: ../parsing/tags.cpp:1768 msgid "FileAttributesTag Tag" msgstr "" #: ../swftypes.cpp:288 ../swftypes.cpp:304 msgid "Fill array extended not supported" msgstr "" #: ../swftypes.h:603 msgid "Fixed point bit field wider than 32 bit not supported" msgstr "" #: ../scripting/abc.cpp:909 msgid "Flags:" msgstr "" #: ../backends/rendering.cpp:85 msgid "Font File is " msgstr "" #: ../scripting/flashsystem.cpp:105 msgid "Found definition for " msgstr "" #: ../backends/rendering.cpp:442 msgid "Fragment shader compilation " msgstr "" #: ../swf.cpp:809 msgid "FrameRate " msgstr "" #: ../scripting/abc_opcodes.cpp:2375 msgid "Function not good " msgstr "" #: ../scripting/abc.cpp:2199 msgid "Function not implemented" msgstr "" #: ../backends/graphics.cpp:45 msgid "GL error " msgstr "" #: ../backends/rendering.cpp:584 msgid "GL errors during initialization: " msgstr "" #: ../backends/graphics.cpp:132 ../backends/graphics.cpp:174 #: ../backends/graphics.cpp:199 msgid "GL_INVALID_VALUE after glTexImage2D, width=" msgstr "" #: ../scripting/actions.cpp:1367 msgid "GetURL2" msgstr "" #: ../scripting/actions.cpp:1378 msgid "GetURL2: exec" msgstr "" #: ../scripting/actions.cpp:1373 msgid "GetURL: exec" msgstr "" #: ../scripting/abc.cpp:1472 msgid "Getter not linkable" msgstr "" #: ../scripting/abc.cpp:1449 ../scripting/abc.cpp:1583 msgid "Getter trait: " msgstr "" #: ../scripting/flashsystem.cpp:138 ../scripting/flashutils.cpp:341 msgid "Getting definition for " msgstr "" #: ../scripting/abc.cpp:961 msgid "Global is " msgstr "" #: ../scripting/flashevents.cpp:372 msgid "Handling event " msgstr "" #: ../backends/graphics.cpp:53 msgid "Ignoring " msgstr "" #: ../scripting/abc_codesynt.cpp:685 ../scripting/abc_codesynt.cpp:1596 msgid "Ignoring at " msgstr "" #: ../scripting/abc.cpp:922 msgid "Implements" msgstr "" #: ../backends/rendering.cpp:581 msgid "Incomplete FBO status " msgstr "" #: ../parsing/tags.cpp:388 msgid "Inconsistent frame count " msgstr "" #: ../scripting/toplevel.cpp:3070 msgid "Integer to bool" msgstr "" #: ../swf.cpp:511 msgid "Invoking gnash!" msgstr "" #: ../threading.cpp:51 msgid "Job terminated" msgstr "" #: ../scripting/toplevel.cpp:1779 msgid "LOG10E" msgstr "" #: ../scripting/toplevel.cpp:1780 msgid "LOG2E" msgstr "" #: ../scripting/abc_codesynt.cpp:1569 msgid "Last instruction before a new block was not a branch." msgstr "" #: ../scripting/abc.cpp:1277 msgid "Last script (Entry Point)" msgstr "" #: ../asobject.cpp:82 msgid "Less than comparison between type " msgstr "" #: ../swftypes.cpp:238 ../swftypes.cpp:265 msgid "Line array extended not supported" msgstr "" #: ../scripting/abc_opcodes.cpp:2193 msgid "Linking with interface " msgstr "" #: ../scripting/flashdisplay.cpp:196 msgid "Loader async execution " msgstr "" #: ../backends/netutils.cpp:394 msgid "LocalDownloader::execute: could not open local file: " msgstr "" #: ../backends/netutils.cpp:386 msgid "LocalDownloader::execute: reading from local file failed: " msgstr "" #: ../backends/netutils.cpp:359 msgid "LocalDownloader::execute: reading local file: " msgstr "" #: ../scripting/flashsystem.cpp:86 ../scripting/flashsystem.cpp:121 #: ../scripting/flashutils.cpp:319 msgid "Looking for definition of " msgstr "" #: ../parsing/tags.cpp:1815 msgid "MaxRecusionDepth: " msgstr "" #: ../parsing/tags.cpp:1858 msgid "MetaData: " msgstr "" #: ../parsing/tags.cpp:1856 msgid "MetadataTag Tag" msgstr "" #: ../scripting/abc_codesynt.cpp:1482 msgid "Method " msgstr "" #: ../scripting/abc.cpp:1441 msgid "Method not linkable" msgstr "" #: ../scripting/abc.cpp:1418 ../scripting/abc.cpp:1662 msgid "Method trait: " msgstr "" #: ../parsing/tags.cpp:1333 ../parsing/tags.cpp:1500 msgid "Moving of registered objects not really supported" msgstr "" #: ../scripting/abc.cpp:1933 msgid "Multibyte not handled" msgstr "" #: ../scripting/abc.cpp:339 ../scripting/abc.cpp:356 ../scripting/abc.cpp:488 #: ../scripting/abc.cpp:584 ../scripting/abc.cpp:619 ../scripting/abc.cpp:636 #: ../scripting/abc.cpp:782 msgid "Multiname to String not yet implemented for this kind " msgstr "" #: ../scripting/abc.cpp:1122 msgid "Multiple binding on " msgstr "" #: ../threading.cpp:74 msgid "Mutex " msgstr "" #: ../scripting/abc_opcodes.cpp:1332 ../scripting/abc_opcodes.cpp:1373 msgid "NOT found " msgstr "" #: ../scripting/abc_opcodes.cpp:1498 msgid "NOT found, pushing Undefined" msgstr "" #: ../scripting/abc_opcodes.cpp:1455 msgid "NOT found, pushing global" msgstr "" #: ../scripting/abc_opcodes.cpp:1369 ../scripting/abc_opcodes.cpp:1491 msgid "NOT found, trying Global" msgstr "" #: ../scripting/flashnet.cpp:439 msgid "NetStream constructor" msgstr "" #: ../scripting/flashnet.cpp:516 msgid "NetStream::close called" msgstr "" #: ../scripting/abc_codesynt.cpp:676 ../scripting/abc_codesynt.cpp:731 msgid "New block at " msgstr "" #: ../plugin/plugin.cpp:365 msgid "Newstream for " msgstr "" #: ../scripting/abc.cpp:1412 ../scripting/abc.cpp:1558 msgid "Next slot has flags " msgstr "" #: ../parsing/flv.cpp:43 msgid "No FLV file signature found" msgstr "" #: ../swf.cpp:73 msgid "No SWF file signature found" msgstr "" #: ../backends/geometry.cpp:46 msgid "No edges in this shape" msgstr "" #: ../main.cpp:196 ../tightspark.cpp:94 msgid "No execution model enabled" msgstr "" #: ../plugin/plugin.cpp:266 msgid "No size in SetWindow" msgstr "" #: ../swf.cpp:1063 msgid "No such Id on dictionary " msgstr "" #: ../backends/rendering.cpp:217 msgid "No suitable graphics configuration available" msgstr "" #: ../backends/rendering.cpp:573 msgid "Non enough color attachments available, input disabled" msgstr "" #: ../scripting/flashdisplay.cpp:492 msgid "Not a function" msgstr "" #: ../scripting/flashdisplay.cpp:601 msgid "Not enough frames loaded" msgstr "" #: ../scripting/flashevents.cpp:368 msgid "Not handled event " msgstr "" #: ../scripting/actions.h:640 msgid "Not implemented action" msgstr "" #: ../scripting/abc_codesynt.cpp:1356 ../scripting/abc_codesynt.cpp:3928 msgid "Not implemented instruction @" msgstr "" #: ../scripting/flashevents.cpp:281 msgid "Not implemented mode for addEventListener" msgstr "" #: ../scripting/abc_interpreter.cpp:1261 msgid "Not intepreted instruction @" msgstr "" #: ../scripting/actions.cpp:68 ../scripting/actions.cpp:135 #: ../scripting/actions.cpp:453 ../scripting/actions.cpp:569 msgid "Not supported action opcode" msgstr "" #: ../swftypes.cpp:667 ../swftypes.cpp:699 msgid "Not supported fill style " msgstr "" #: ../scripting/toplevel.cpp:3056 msgid "Null to bool" msgstr "" #: ../scripting/toplevel.cpp:3061 msgid "Number to bool" msgstr "" #: ../scripting/abc_opcodes.cpp:1740 ../scripting/abc_opcodes.cpp:1794 #: ../scripting/abc_opcodes.cpp:1855 msgid "Numeric type is " msgstr "" #: ../scripting/abc_opcodes.cpp:303 msgid "Object" msgstr "" #: ../scripting/toplevel.cpp:3036 msgid "Object to bool" msgstr "" #: ../scripting/abc_opcodes.cpp:667 msgid "Object type " msgstr "" #: ../asobject.cpp:139 ../asobject.cpp:161 msgid "Overloaded isEqual" msgstr "" #: ../asobject.cpp:78 msgid "Overloaded isLess" msgstr "" #: ../swf.cpp:266 msgid "Parameters file not found" msgstr "" #: ../asobject.cpp:503 msgid "Passthorugh of " msgstr "" #: ../parsing/tags.cpp:1373 msgid "PlaceObject2" msgstr "" #: ../parsing/tags.cpp:1540 msgid "PlaceObject3" msgstr "" #: ../parsing/tags.cpp:1271 ../parsing/tags.cpp:1438 msgid "Placing ID " msgstr "" #: ../parsing/tags.cpp:1602 msgid "ProductInfoTag Tag" msgstr "" #: ../scripting/abc_opcodes.cpp:388 ../scripting/abc_opcodes.cpp:392 msgid "Property not found " msgstr "" #: ../parsing/tags_stub.cpp:34 msgid "Protect Tag" msgstr "" #: ../scripting/abc_opcodes.cpp:338 ../scripting/abc_opcodes.cpp:811 msgid "Proxy::callProperty" msgstr "" #: ../scripting/flashutils.cpp:628 msgid "Proxy::getProperty" msgstr "" #: ../scripting/flashutils.cpp:638 msgid "Proxy::hasNext" msgstr "" #: ../scripting/flashutils.cpp:656 msgid "Proxy::nextName" msgstr "" #: ../scripting/flashutils.cpp:601 msgid "Proxy::setProperty" msgstr "" #: ../scripting/actions.cpp:1304 msgid "Push type: " msgstr "" #: ../scripting/actions.cpp:1262 msgid "Push: Read bool " msgstr "" #: ../scripting/actions.cpp:1290 msgid "Push: Read constant index " msgstr "" #: ../scripting/actions.cpp:1271 msgid "Push: Read double " msgstr "" #: ../scripting/actions.cpp:1231 msgid "Push: Read float " msgstr "" #: ../scripting/actions.cpp:1280 msgid "Push: Read integer " msgstr "" #: ../scripting/actions.cpp:1300 msgid "Push: Read long constant index " msgstr "" #: ../scripting/actions.cpp:1253 msgid "Push: Read reg number " msgstr "" #: ../scripting/actions.cpp:1222 msgid "Push: Read string " msgstr "" #: ../scripting/actions.cpp:1237 msgid "Push: null" msgstr "" #: ../scripting/actions.cpp:1243 msgid "Push: undefined" msgstr "" #: ../parsing/tags.cpp:52 msgid "Reading tag type: " msgstr "" #: ../backends/graphics.cpp:192 msgid "Reallocating texture to size " msgstr "" #: ../parsing/tags.cpp:1325 ../parsing/tags.cpp:1492 msgid "Registering ID " msgstr "" #: ../parsing/tags.cpp:239 msgid "RemoveObject2 Depth: " msgstr "" #: ../backends/rendering.cpp:57 msgid "RenderThread this=" msgstr "" #: ../scripting/abc.cpp:1177 msgid "Requested invalid method" msgstr "" #: ../swftypes.cpp:395 msgid "Reserved bits not so reserved" msgstr "" #: ../swftypes.cpp:538 msgid "Reverting to fixed function" msgstr "" #: ../main.cpp:218 msgid "Running in local-with-filesystem sandbox" msgstr "" #: ../main.cpp:214 msgid "Running in remote sandbox" msgstr "" #: ../parsing/tags.cpp:1611 msgid "SWF Info:" msgstr "" #: ../scripting/abc.cpp:1256 msgid "Script N: " msgstr "" #: ../parsing/tags.cpp:1813 msgid "ScriptLimitsTag Tag" msgstr "" #: ../scripting/flashsystem.cpp:199 msgid "Security::allowDomain" msgstr "" #: ../scripting/flashsystem.cpp:205 msgid "Security::allowInsecureDomain" msgstr "" #: ../scripting/flashsystem.cpp:211 msgid "Security::loadPolicyFile" msgstr "" #: ../scripting/flashsystem.cpp:217 msgid "Security::showSettings" msgstr "" #: ../scripting/abc.cpp:1503 msgid "Setter not linkable" msgstr "" #: ../scripting/abc.cpp:1480 ../scripting/abc.cpp:1622 msgid "Setter trait: " msgstr "" #: ../scripting/abc.cpp:1126 msgid "Setting class name to " msgstr "" #: ../backends/rendering.cpp:428 msgid "Shader lightspark.frag not found" msgstr "" #: ../backends/rendering.cpp:465 msgid "Shader lightspark.vert not found" msgstr "" #: ../parsing/tags.cpp:768 msgid "Should be a FontTag" msgstr "" #: ../parsing/tags.cpp:1224 msgid "ShowFrame" msgstr "" #: ../swftypes.h:665 msgid "Signed bit field wider than 32 bit not supported" msgstr "" #: ../swftypes.cpp:1087 msgid "Skipping " msgstr "" #: ../scripting/abc.cpp:1749 ../scripting/abc.cpp:1755 msgid "Slot " msgstr "" #: ../parsing/tags_stub.cpp:88 msgid "SoundStreamBlockTag" msgstr "" #: ../parsing/tags_stub.cpp:52 msgid "SoundStreamHead Tag" msgstr "" #: ../parsing/tags_stub.cpp:58 msgid "SoundStreamHead2 Tag" msgstr "" #: ../scripting/flashmedia.cpp:45 msgid "SoundTransform constructor" msgstr "" #: ../scripting/abc.cpp:1230 msgid "Stack not clean at the end of function" msgstr "" #: ../parsing/tags_stub.cpp:46 msgid "StartSound Tag" msgstr "" #: ../scripting/abc_codesynt.cpp:1574 msgid "Starting block at " msgstr "" #: ../scripting/toplevel.cpp:3021 msgid "String to bool" msgstr "" #: ../swftypes.cpp:621 msgid "Style not implemented" msgstr "" #: ../scripting/abc.cpp:919 msgid "Super " msgstr "" #: ../scripting/abc_opcodes.cpp:1416 msgid "Super prototype name " msgstr "" #: ../scripting/abc_interpreter.cpp:397 msgid "Switch default dest " msgstr "" #: ../scripting/abc_interpreter.cpp:404 msgid "Switch dest " msgstr "" #: ../scripting/abc.cpp:93 msgid "SymbolClassTag" msgstr "" #: ../scripting/abc.cpp:105 msgid "SymbolClassTag Exec" msgstr "" #: ../parsing/tags.cpp:300 msgid "Sync to variable name " msgstr "" #: ../scripting/flashevents.cpp:119 msgid "Target for event " msgstr "" #: ../scripting/flashtext.cpp:100 msgid "TextField::Render" msgstr "" #: ../scripting/abc.cpp:1513 ../scripting/abc.cpp:1786 msgid "Trait not supported " msgstr "" #: ../asobject.cpp:84 ../asobject.cpp:167 ../scripting/abc_opcodes.cpp:1774 #: ../scripting/abc_opcodes.cpp:1837 ../scripting/abc_opcodes.cpp:1888 msgid "Type " msgstr "" #: ../backends/rendering.cpp:78 msgid "Unable to find suitable Serif font" msgstr "" #: ../backends/rendering.cpp:238 msgid "Unable to load serif font" msgstr "" #: ../parsing/tags.cpp:375 msgid "Unclassified tag inside Sprite?" msgstr "" #: ../swf.cpp:65 msgid "Uncompressed SWF file: Version " msgstr "" #: ../scripting/toplevel.cpp:1180 msgid "Undefined function" msgstr "" #: ../scripting/toplevel.cpp:3051 msgid "Undefined to bool" msgstr "" #: ../timer.cpp:164 msgid "Unexpected failure of sem_timedwait.. Trying to go on. errno=" msgstr "" #: ../scripting/abc.cpp:2113 msgid "Unexpected kind " msgstr "" #: ../scripting/abc.cpp:2021 msgid "Unexpected multiname kind " msgstr "" #: ../scripting/abc.cpp:2045 msgid "Unexpected options type" msgstr "" #: ../scripting/flashnet.cpp:726 msgid "Unexpected tag type " msgstr "" #: ../scripting/toplevel.cpp:2162 msgid "Unicode not supported in String::fromCharCode" msgstr "" #: ../parsing/tags_stub.cpp:106 msgid "Unimplemented Tag " msgstr "" #: ../swftypes.h:647 msgid "Unsigned bit field wider than 32 bit not supported" msgstr "" #: ../scripting/actions.cpp:405 msgid "Unsupported ActionCode " msgstr "" #: ../swftypes.cpp:907 msgid "Unsupported Filter Id " msgstr "" #: ../parsing/tags.cpp:209 msgid "Unsupported tag type " msgstr "" #: ../backends/rendering.cpp:473 msgid "Vertex shader compilation " msgstr "" #: ../backends/rendering.cpp:519 msgid "Video card does not support OpenGL 2.0... Aborting" msgstr "" #: ../backends/decoder.cpp:40 msgid "Video frame size " msgstr "" #: ../scripting/abc_opcodes.cpp:1596 ../scripting/abc_opcodes.cpp:1680 msgid "We got a Undefined function" msgstr "" #: ../scripting/abc_opcodes.cpp:825 ../scripting/abc_opcodes.cpp:829 msgid "We got a Undefined function " msgstr "" #: ../scripting/abc_opcodes.cpp:303 msgid "We got a Undefined function on obj " msgstr "" #: ../scripting/abc_opcodes.cpp:285 msgid "We got a function not yet valid" msgstr "" #: ../scripting/abc_opcodes.cpp:1322 ../scripting/flashsystem.cpp:96 #: ../scripting/flashutils.cpp:333 msgid "We got an object not yet valid" msgstr "" #: ../backends/input.cpp:190 ../backends/input.cpp:266 msgid "We still miss " msgstr "" #: ../scripting/flashevents.cpp:292 msgid "Weird event reregistration" msgstr "" #: ../backends/rendering.cpp:259 msgid "Window resize not supported in plugin" msgstr "" #: ../asobject.cpp:704 msgid "[" msgstr "" #: ../scripting/abc_opcodes.cpp:169 ../scripting/abc_opcodes.cpp:174 msgid "]" msgstr "" #: ../asobject.cpp:704 ../scripting/abc_opcodes.cpp:921 #: ../scripting/abc_opcodes.cpp:927 ../scripting/abc_opcodes.cpp:933 msgid "] " msgstr "" #: ../scripting/abc_opcodes.cpp:164 msgid "] (" msgstr "" #: ../scripting/abc_opcodes.cpp:159 ../scripting/abc_opcodes.cpp:179 msgid "] (int)= " msgstr "" #: ../scripting/abc_opcodes.cpp:184 msgid "] = " msgstr "" #: ../scripting/abc_opcodes.cpp:948 ../scripting/abc_opcodes.cpp:964 #: ../scripting/abc_opcodes.cpp:973 ../scripting/abc_opcodes.cpp:995 #: ../scripting/abc_opcodes.cpp:1003 ../scripting/abc_opcodes.cpp:1012 #: ../scripting/abc_opcodes.cpp:1039 ../scripting/abc_opcodes.cpp:1047 #: ../scripting/abc_opcodes.cpp:1055 msgid "add " msgstr "" #: ../scripting/abc_opcodes.cpp:1846 msgid "asTypelate" msgstr "" #: ../scripting/abc_opcodes.cpp:44 msgid "bitAnd_oi " msgstr "" #: ../scripting/abc_opcodes.cpp:35 msgid "bitAnd_oo " msgstr "" #: ../scripting/abc_opcodes.cpp:223 msgid "bitNot " msgstr "" #: ../scripting/abc_opcodes.cpp:242 ../scripting/abc_opcodes.cpp:252 msgid "bitOr " msgstr "" #: ../scripting/abc_opcodes.cpp:233 msgid "bitXor " msgstr "" #: ../scripting/abc_codesynt.cpp:751 msgid "block analysis: branches" msgstr "" #: ../scripting/abc_codesynt.cpp:713 msgid "block analysis: kill" msgstr "" #: ../scripting/abc_opcodes.cpp:2351 msgid "call " msgstr "" #: ../scripting/abc_opcodes.cpp:748 msgid "callPropVoid " msgstr "" #: ../scripting/abc_opcodes.cpp:263 msgid "callProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:1568 msgid "callSuper " msgstr "" #: ../scripting/abc_opcodes.cpp:1651 msgid "callSuperVoid " msgstr "" #: ../scripting/toplevel.cpp:2028 msgid "capturing groups " msgstr "" #: ../scripting/abc_opcodes.cpp:149 msgid "coerce " msgstr "" #: ../scripting/abc_opcodes.cpp:133 msgid "coerce_a" msgstr "" #: ../scripting/abc_opcodes.cpp:143 msgid "coerce_s" msgstr "" #: ../scripting/abc_opcodes.cpp:593 msgid "construct " msgstr "" #: ../scripting/abc_opcodes.cpp:682 msgid "constructGenericType " msgstr "" #: ../scripting/abc_opcodes.cpp:1957 msgid "constructProp " msgstr "" #: ../scripting/abc_opcodes.cpp:1399 msgid "constructSuper " msgstr "" #: ../scripting/abc_opcodes.cpp:87 msgid "convert_b" msgstr "" #: ../scripting/abc_opcodes.cpp:74 msgid "convert_d" msgstr "" #: ../scripting/abc_opcodes.cpp:103 msgid "convert_i" msgstr "" #: ../scripting/abc_opcodes.cpp:95 msgid "convert_u" msgstr "" #: ../scripting/abc_codesynt.cpp:784 ../scripting/abc_codesynt.cpp:2248 msgid "count " msgstr "" #: ../scripting/flashdisplay.cpp:505 msgid "createEmptyMovieClip" msgstr "" #: ../scripting/abc.cpp:876 msgid "dMultiname to String not yet implemented for this kind " msgstr "" #: ../scripting/abc_interpreter.cpp:1233 msgid "debug" msgstr "" #: ../scripting/abc_codesynt.cpp:37 msgid "debug_d " msgstr "" #: ../scripting/abc_codesynt.cpp:42 msgid "debug_i " msgstr "" #: ../scripting/abc_interpreter.cpp:1255 msgid "debugfile" msgstr "" #: ../scripting/abc_interpreter.cpp:1247 msgid "debugline" msgstr "" #: ../scripting/abc_opcodes.cpp:465 msgid "decrement" msgstr "" #: ../scripting/abc_opcodes.cpp:474 msgid "decrement_i" msgstr "" #: ../scripting/abc_codesynt.cpp:781 ../scripting/abc_codesynt.cpp:2245 msgid "default " msgstr "" #: ../scripting/abc_opcodes.cpp:2386 msgid "deleteProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:437 msgid "divide " msgstr "" #: ../scripting/abc_opcodes.cpp:429 msgid "divide: HACK" msgstr "" #: ../scripting/abc_codesynt.cpp:1359 ../scripting/abc_codesynt.cpp:3931 #: ../scripting/abc_interpreter.cpp:1262 msgid "dump " msgstr "" #: ../scripting/abc_opcodes.cpp:1183 msgid "dup: DONE" msgstr "" #: ../scripting/abc_opcodes.cpp:1137 msgid "equals " msgstr "" #: ../scripting/abc_opcodes.cpp:1467 msgid "findPropStrict " msgstr "" #: ../scripting/abc_opcodes.cpp:1430 msgid "findProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:458 msgid "getGlobalScope: " msgstr "" #: ../scripting/abc_opcodes.cpp:1342 msgid "getLex: " msgstr "" #: ../scripting/abc_interpreter.cpp:773 ../scripting/abc_interpreter.cpp:1210 msgid "getLocal " msgstr "" #: ../scripting/abc_opcodes.cpp:159 ../scripting/abc_opcodes.cpp:164 #: ../scripting/abc_opcodes.cpp:169 msgid "getLocal[" msgstr "" #: ../scripting/abc.cpp:306 msgid "getMultinameRTData not yet implemented for this kind " msgstr "" #: ../scripting/abc_opcodes.cpp:372 msgid "getProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:361 msgid "getProperty_i " msgstr "" #: ../scripting/abc_opcodes.cpp:2415 msgid "getScopeObject: " msgstr "" #: ../scripting/abc_opcodes.cpp:204 msgid "getSlot " msgstr "" #: ../scripting/abc_opcodes.cpp:1298 msgid "getSuper " msgstr "" #: ../scripting/toplevel.cpp:1463 msgid "getTimezoneOffset" msgstr "" #: ../backends/rendering.cpp:190 msgid "glX not present" msgstr "" #: ../scripting/abc_opcodes.cpp:1521 msgid "greaterEquals" msgstr "" #: ../scripting/abc_opcodes.cpp:1510 msgid "greaterThan" msgstr "" #: ../scripting/abc_opcodes.cpp:2035 msgid "hasNext2 " msgstr "" #: ../scripting/abc_opcodes.cpp:1903 msgid "ifEq (" msgstr "" #: ../scripting/abc_opcodes.cpp:1943 msgid "ifFalse (" msgstr "" #: ../scripting/abc_opcodes.cpp:1252 msgid "ifGE (" msgstr "" #: ../scripting/abc_opcodes.cpp:1209 msgid "ifGT (" msgstr "" #: ../scripting/abc_opcodes.cpp:1232 msgid "ifLE (" msgstr "" #: ../scripting/abc_opcodes.cpp:496 msgid "ifLT (" msgstr "" #: ../scripting/abc_opcodes.cpp:520 msgid "ifLT_io " msgstr "" #: ../scripting/abc_opcodes.cpp:505 msgid "ifLT_oi" msgstr "" #: ../scripting/abc_opcodes.cpp:532 ../scripting/abc_opcodes.cpp:545 msgid "ifNE (" msgstr "" #: ../scripting/abc_opcodes.cpp:1262 msgid "ifNGE (" msgstr "" #: ../scripting/abc_opcodes.cpp:1221 msgid "ifNGT (" msgstr "" #: ../scripting/abc_opcodes.cpp:1242 msgid "ifNLE (" msgstr "" #: ../scripting/abc_opcodes.cpp:485 msgid "ifNLT (" msgstr "" #: ../scripting/abc_opcodes.cpp:1921 msgid "ifStrictEq " msgstr "" #: ../scripting/abc_opcodes.cpp:1927 msgid "ifStrictNE" msgstr "" #: ../scripting/abc_opcodes.cpp:846 msgid "ifTrue (" msgstr "" #: ../scripting/abc_opcodes.cpp:1933 msgid "in" msgstr "" #: ../scripting/abc_opcodes.cpp:578 msgid "incLocal_i " msgstr "" #: ../scripting/abc_opcodes.cpp:2130 msgid "increment_i" msgstr "" #: ../scripting/abc_opcodes.cpp:1547 msgid "initProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:1720 msgid "isType " msgstr "" #: ../scripting/abc_opcodes.cpp:1768 msgid "isType on non classed object " msgstr "" #: ../scripting/abc_opcodes.cpp:1782 msgid "isTypelate" msgstr "" #: ../scripting/abc_opcodes.cpp:1830 msgid "isTypelate on non classed object " msgstr "" #: ../scripting/abc_opcodes.cpp:840 msgid "jump " msgstr "" #: ../scripting/abc_opcodes.cpp:938 msgid "kill " msgstr "" #: ../scripting/abc_opcodes.cpp:1080 ../scripting/abc_opcodes.cpp:1091 msgid "lShift " msgstr "" #: ../scripting/abc_opcodes.cpp:111 msgid "label" msgstr "" #: ../scripting/abc_opcodes.cpp:1532 msgid "lessEquals" msgstr "" #: ../scripting/abc_opcodes.cpp:2334 msgid "lessThan" msgstr "" #: ../scripting/abc_opcodes.cpp:116 msgid "lookupswitch" msgstr "" #: ../scripting/abc_opcodes.cpp:859 msgid "modulo " msgstr "" #: ../scripting/abc_opcodes.cpp:572 msgid "multiply " msgstr "" #: ../scripting/abc_opcodes.cpp:562 msgid "multiply_oi " msgstr "" #: ../scripting/abc_opcodes.cpp:213 msgid "negate" msgstr "" #: ../scripting/abc_opcodes.cpp:2309 msgid "newActivation" msgstr "" #: ../scripting/abc_opcodes.cpp:2434 msgid "newArray " msgstr "" #: ../scripting/abc_opcodes.cpp:2428 msgid "newCatch " msgstr "" #: ../scripting/abc_opcodes.cpp:2200 msgid "newClass " msgstr "" #: ../scripting/abc_opcodes.cpp:2398 msgid "newFunction " msgstr "" #: ../scripting/abc_opcodes.cpp:2090 msgid "newObject " msgstr "" #: ../scripting/abc_opcodes.cpp:2164 msgid "nextName" msgstr "" #: ../scripting/abc_opcodes.cpp:2139 msgid "nextValue" msgstr "" #: ../parsing/tags.cpp:1364 ../parsing/tags.cpp:1531 msgid "no char to move at depth " msgstr "" #: ../scripting/abc_opcodes.cpp:1128 msgid "not" msgstr "" #: ../scripting/abc_opcodes.cpp:1888 msgid "not " msgstr "" #: ../scripting/abc.cpp:1184 msgid "not implement opcode 0x" msgstr "" #: ../scripting/abc_opcodes.cpp:1943 msgid "not taken" msgstr "" #: ../scripting/abc_opcodes.cpp:485 ../scripting/abc_opcodes.cpp:496 #: ../scripting/abc_opcodes.cpp:532 ../scripting/abc_opcodes.cpp:545 #: ../scripting/abc_opcodes.cpp:846 ../scripting/abc_opcodes.cpp:1209 #: ../scripting/abc_opcodes.cpp:1221 ../scripting/abc_opcodes.cpp:1232 #: ../scripting/abc_opcodes.cpp:1242 ../scripting/abc_opcodes.cpp:1252 #: ../scripting/abc_opcodes.cpp:1262 ../scripting/abc_opcodes.cpp:1903 msgid "not taken)" msgstr "" #: ../scripting/abc.cpp:1839 msgid "parsing s32" msgstr "" #: ../scripting/abc.cpp:1889 ../scripting/abc.cpp:1893 msgid "parsing u30" msgstr "" #: ../scripting/abc.cpp:1814 msgid "parsing u32 " msgstr "" #: ../scripting/abc_opcodes.cpp:154 msgid "pop: DONE" msgstr "" #: ../scripting/abc_opcodes.cpp:2327 msgid "popScope" msgstr "" #: ../thread_pool.cpp:68 msgid "pthread_join failed in ~ThreadPool" msgstr "" #: ../scripting/abc.cpp:989 msgid "pthread_join in ABCVm failed" msgstr "" #: ../scripting/abc_opcodes.cpp:553 msgid "pushByte " msgstr "" #: ../scripting/abc_opcodes.cpp:933 msgid "pushDouble [" msgstr "" #: ../scripting/abc_opcodes.cpp:1194 msgid "pushFalse" msgstr "" #: ../scripting/abc_opcodes.cpp:927 msgid "pushInt [" msgstr "" #: ../scripting/abc_opcodes.cpp:1200 msgid "pushNaN" msgstr "" #: ../scripting/abc_opcodes.cpp:127 msgid "pushNull" msgstr "" #: ../scripting/abc_opcodes.cpp:451 msgid "pushScope " msgstr "" #: ../scripting/abc_opcodes.cpp:189 msgid "pushShort " msgstr "" #: ../scripting/abc_opcodes.cpp:2422 msgid "pushString " msgstr "" #: ../scripting/abc_opcodes.cpp:1188 msgid "pushTrue" msgstr "" #: ../scripting/abc_opcodes.cpp:921 msgid "pushUInt [" msgstr "" #: ../scripting/abc_opcodes.cpp:121 msgid "pushUndefined" msgstr "" #: ../scripting/abc_opcodes.cpp:444 msgid "pushWith " msgstr "" #: ../scripting/abc_opcodes.cpp:1103 msgid "rShift " msgstr "" #: ../scripting/toplevel.cpp:2026 msgid "re: " msgstr "" #: ../scripting/abc_interpreter.cpp:636 msgid "returnValue " msgstr "" #: ../scripting/abc_interpreter.cpp:629 msgid "returnVoid" msgstr "" #: ../scripting/abc_interpreter.cpp:782 ../scripting/abc_interpreter.cpp:1222 msgid "setLocal " msgstr "" #: ../scripting/abc_opcodes.cpp:174 ../scripting/abc_opcodes.cpp:179 #: ../scripting/abc_opcodes.cpp:184 msgid "setLocal[" msgstr "" #: ../scripting/abc_opcodes.cpp:50 msgid "setProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:66 msgid "setProperty_i " msgstr "" #: ../scripting/abc_opcodes.cpp:195 msgid "setSlot " msgstr "" #: ../scripting/abc_opcodes.cpp:1277 msgid "setSuper " msgstr "" #: ../scripting/abc_opcodes.cpp:1174 msgid "strictEquals" msgstr "" #: ../scripting/abc_opcodes.cpp:914 msgid "subtract " msgstr "" #: ../scripting/abc_opcodes.cpp:889 ../scripting/abc_opcodes.cpp:906 msgid "subtract: HACK" msgstr "" #: ../scripting/abc_opcodes.cpp:880 msgid "subtract_do " msgstr "" #: ../scripting/abc_opcodes.cpp:896 msgid "subtract_io " msgstr "" #: ../scripting/abc_opcodes.cpp:869 msgid "subtract_oi " msgstr "" #: ../scripting/abc_opcodes.cpp:2304 msgid "swap" msgstr "" #: ../scripting/abc_codesynt.cpp:3287 msgid "synt add" msgstr "" #: ../scripting/abc_codesynt.cpp:3184 msgid "synt astypelate" msgstr "" #: ../scripting/abc_codesynt.cpp:3594 msgid "synt bitand" msgstr "" #: ../scripting/abc_codesynt.cpp:3270 msgid "synt bitnot" msgstr "" #: ../scripting/abc_codesynt.cpp:3627 msgid "synt bitor" msgstr "" #: ../scripting/abc_codesynt.cpp:3649 msgid "synt bitxor" msgstr "" #: ../scripting/abc_codesynt.cpp:2542 msgid "synt call" msgstr "" #: ../scripting/abc_codesynt.cpp:2578 msgid "synt callproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:2692 msgid "synt callpropvoid" msgstr "" #: ../scripting/abc_codesynt.cpp:2564 msgid "synt callsuper" msgstr "" #: ../scripting/abc_codesynt.cpp:2679 msgid "synt callsupervoid" msgstr "" #: ../scripting/abc_codesynt.cpp:3139 msgid "synt checkfilter" msgstr "" #: ../scripting/abc_codesynt.cpp:3149 msgid "synt coerce" msgstr "" #: ../scripting/abc_codesynt.cpp:3160 msgid "synt coerce_a" msgstr "" #: ../scripting/abc_codesynt.cpp:3174 msgid "synt coerce_s" msgstr "" #: ../scripting/abc_codesynt.cpp:2553 msgid "synt construct" msgstr "" #: ../scripting/abc_codesynt.cpp:2705 msgid "synt constructgenerictype" msgstr "" #: ../scripting/abc_codesynt.cpp:2666 msgid "synt constructprop" msgstr "" #: ../scripting/abc_codesynt.cpp:2655 msgid "synt constructsuper" msgstr "" #: ../scripting/abc_codesynt.cpp:3125 msgid "synt convert_b" msgstr "" #: ../scripting/abc_codesynt.cpp:3110 msgid "synt convert_d" msgstr "" #: ../scripting/abc_codesynt.cpp:3080 msgid "synt convert_i" msgstr "" #: ../scripting/abc_codesynt.cpp:3074 msgid "synt convert_s" msgstr "" #: ../scripting/abc_codesynt.cpp:3095 msgid "synt convert_u" msgstr "" #: ../scripting/abc_codesynt.cpp:3900 msgid "synt debug" msgstr "" #: ../scripting/abc_codesynt.cpp:3922 msgid "synt debugfile" msgstr "" #: ../scripting/abc_codesynt.cpp:3914 msgid "synt debugline" msgstr "" #: ../scripting/abc_codesynt.cpp:3228 msgid "synt decrement" msgstr "" #: ../scripting/abc_codesynt.cpp:3791 msgid "synt decrement_i" msgstr "" #: ../scripting/abc_codesynt.cpp:3025 msgid "synt deleteproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:3444 msgid "synt divide" msgstr "" #: ../scripting/abc_codesynt.cpp:2404 msgid "synt dup" msgstr "" #: ../scripting/abc_codesynt.cpp:3672 msgid "synt equals" msgstr "" #: ../scripting/abc_codesynt.cpp:2812 msgid "synt findproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:2779 msgid "synt findpropstrict" msgstr "" #: ../scripting/abc_codesynt.cpp:2757 msgid "synt getdescendants" msgstr "" #: ../scripting/abc_codesynt.cpp:2949 msgid "synt getglobalscope" msgstr "" #: ../scripting/abc_codesynt.cpp:2824 msgid "synt getlex" msgstr "" #: ../scripting/abc_codesynt.cpp:2882 msgid "synt getlocal" msgstr "" #: ../scripting/abc_codesynt.cpp:3833 msgid "synt getlocal_n " msgstr "" #: ../scripting/abc_codesynt.cpp:2968 msgid "synt getproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:2957 msgid "synt getscopeobject" msgstr "" #: ../scripting/abc_codesynt.cpp:3036 msgid "synt getslot" msgstr "" #: ../scripting/abc_codesynt.cpp:1630 msgid "synt getsuper" msgstr "" #: ../scripting/abc_codesynt.cpp:3738 msgid "synt greaterequals" msgstr "" #: ../scripting/abc_codesynt.cpp:3725 msgid "synt greaterthan" msgstr "" #: ../scripting/abc_codesynt.cpp:2497 msgid "synt hasnext2" msgstr "" #: ../scripting/abc_codesynt.cpp:1908 msgid "synt ifeq" msgstr "" #: ../scripting/abc_codesynt.cpp:1876 msgid "synt iffalse " msgstr "" #: ../scripting/abc_codesynt.cpp:2127 msgid "synt ifge" msgstr "" #: ../scripting/abc_codesynt.cpp:2093 msgid "synt ifgt" msgstr "" #: ../scripting/abc_codesynt.cpp:2055 msgid "synt ifle" msgstr "" #: ../scripting/abc_codesynt.cpp:2015 msgid "synt iflt " msgstr "" #: ../scripting/abc_codesynt.cpp:1965 msgid "synt ifne " msgstr "" #: ../scripting/abc_codesynt.cpp:1784 msgid "synt ifnge" msgstr "" #: ../scripting/abc_codesynt.cpp:1751 msgid "synt ifngt" msgstr "" #: ../scripting/abc_codesynt.cpp:1719 msgid "synt ifnle" msgstr "" #: ../scripting/abc_codesynt.cpp:1680 msgid "synt ifnlt" msgstr "" #: ../scripting/abc_codesynt.cpp:2161 msgid "synt ifstricteq" msgstr "" #: ../scripting/abc_codesynt.cpp:2193 msgid "synt ifstrictne" msgstr "" #: ../scripting/abc_codesynt.cpp:1837 msgid "synt iftrue" msgstr "" #: ../scripting/abc_codesynt.cpp:3762 msgid "synt in" msgstr "" #: ../scripting/abc_codesynt.cpp:3808 msgid "synt inclocal_i" msgstr "" #: ../scripting/abc_codesynt.cpp:3205 msgid "synt increment" msgstr "" #: ../scripting/abc_codesynt.cpp:3774 msgid "synt increment_i" msgstr "" #: ../scripting/abc_codesynt.cpp:3014 msgid "synt initproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:3751 msgid "synt istypelate" msgstr "" #: ../scripting/abc_codesynt.cpp:1821 msgid "synt jump " msgstr "" #: ../scripting/abc_codesynt.cpp:1654 msgid "synt kill " msgstr "" #: ../scripting/abc_codesynt.cpp:1672 msgid "synt label" msgstr "" #: ../scripting/abc_codesynt.cpp:3712 msgid "synt lessequals" msgstr "" #: ../scripting/abc_codesynt.cpp:3699 msgid "synt lessthan" msgstr "" #: ../scripting/abc_codesynt.cpp:774 ../scripting/abc_codesynt.cpp:2236 msgid "synt lookupswitch" msgstr "" #: ../scripting/abc_codesynt.cpp:3514 msgid "synt lshift" msgstr "" #: ../scripting/abc_codesynt.cpp:3474 msgid "synt modulo" msgstr "" #: ../scripting/abc_codesynt.cpp:3401 msgid "synt multiply" msgstr "" #: ../scripting/abc_codesynt.cpp:3195 msgid "synt negate" msgstr "" #: ../scripting/abc_codesynt.cpp:2738 msgid "synt newactivation" msgstr "" #: ../scripting/abc_codesynt.cpp:2727 msgid "synt newarray" msgstr "" #: ../scripting/abc_codesynt.cpp:2768 msgid "synt newcatch" msgstr "" #: ../scripting/abc_codesynt.cpp:2746 msgid "synt newclass" msgstr "" #: ../scripting/abc_codesynt.cpp:2531 msgid "synt newfunction" msgstr "" #: ../scripting/abc_codesynt.cpp:2716 msgid "synt newobject" msgstr "" #: ../scripting/abc_codesynt.cpp:2303 msgid "synt nextname" msgstr "" #: ../scripting/abc_codesynt.cpp:2332 msgid "synt nextvalue" msgstr "" #: ../scripting/abc_codesynt.cpp:3256 msgid "synt not" msgstr "" #: ../scripting/abc_codesynt.cpp:2393 msgid "synt pop" msgstr "" #: ../scripting/abc_codesynt.cpp:2295 msgid "synt popscope" msgstr "" #: ../scripting/abc_codesynt.cpp:2345 msgid "synt pushbyte" msgstr "" #: ../scripting/abc_codesynt.cpp:2472 msgid "synt pushdouble" msgstr "" #: ../scripting/abc_codesynt.cpp:2377 msgid "synt pushfalse" msgstr "" #: ../scripting/abc_codesynt.cpp:2440 msgid "synt pushint" msgstr "" #: ../scripting/abc_codesynt.cpp:2385 msgid "synt pushnan" msgstr "" #: ../scripting/abc_codesynt.cpp:2316 msgid "synt pushnull" msgstr "" #: ../scripting/abc_codesynt.cpp:2489 msgid "synt pushscope" msgstr "" #: ../scripting/abc_codesynt.cpp:2357 msgid "synt pushshort" msgstr "" #: ../scripting/abc_codesynt.cpp:2429 msgid "synt pushstring" msgstr "" #: ../scripting/abc_codesynt.cpp:2369 msgid "synt pushtrue" msgstr "" #: ../scripting/abc_codesynt.cpp:2456 msgid "synt pushuint" msgstr "" #: ../scripting/abc_codesynt.cpp:2324 msgid "synt pushundefined" msgstr "" #: ../scripting/abc_codesynt.cpp:2287 msgid "synt pushwith" msgstr "" #: ../scripting/abc_codesynt.cpp:2626 msgid "synt returnvalue" msgstr "" #: ../scripting/abc_codesynt.cpp:2604 msgid "synt returnvoid" msgstr "" #: ../scripting/abc_codesynt.cpp:3538 msgid "synt rshift" msgstr "" #: ../scripting/abc_codesynt.cpp:2928 msgid "synt setlocal " msgstr "" #: ../scripting/abc_codesynt.cpp:3878 msgid "synt setlocal_n " msgstr "" #: ../scripting/abc_codesynt.cpp:2835 msgid "synt setproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:3049 msgid "synt setslot" msgstr "" #: ../scripting/abc_codesynt.cpp:1641 msgid "synt setsuper" msgstr "" #: ../scripting/abc_codesynt.cpp:3689 msgid "synt strictequals" msgstr "" #: ../scripting/abc_codesynt.cpp:3348 msgid "synt subtract" msgstr "" #: ../scripting/abc_codesynt.cpp:2417 msgid "synt swap" msgstr "" #: ../scripting/abc_codesynt.cpp:1605 msgid "synt throw" msgstr "" #: ../scripting/abc_codesynt.cpp:3246 msgid "synt typeof" msgstr "" #: ../scripting/abc_codesynt.cpp:3559 msgid "synt urshift" msgstr "" #: ../scripting/abc_opcodes.cpp:1943 msgid "taken" msgstr "" #: ../scripting/abc_opcodes.cpp:485 ../scripting/abc_opcodes.cpp:496 #: ../scripting/abc_opcodes.cpp:532 ../scripting/abc_opcodes.cpp:545 #: ../scripting/abc_opcodes.cpp:846 ../scripting/abc_opcodes.cpp:1209 #: ../scripting/abc_opcodes.cpp:1221 ../scripting/abc_opcodes.cpp:1232 #: ../scripting/abc_opcodes.cpp:1242 ../scripting/abc_opcodes.cpp:1252 #: ../scripting/abc_opcodes.cpp:1262 ../scripting/abc_opcodes.cpp:1903 msgid "taken)" msgstr "" #: ../scripting/abc_opcodes.cpp:713 msgid "typeOf" msgstr "" #: ../scripting/abc_opcodes.cpp:1113 ../scripting/abc_opcodes.cpp:1122 msgid "urShift " msgstr "" #: ../backends/rendering.cpp:106 msgid "~RenderThread this=" msgstr "" lightspark-0.7.2/i18n/pl.po000066400000000000000000001620761212105246600154350ustar00rootroot00000000000000# Polish translations for PACKAGE package # Polskie tumaczenia dla pakietu PACKAGE. # Copyright (C) 2010 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # , 2010. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2010-08-24 23:48-0500\n" "PO-Revision-Date: 2010-08-20 23:03-0500\n" "Last-Translator: \n" "Language-Team: Polish\n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: teplain; charset=ISO-8859-2\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2);\n" #: ../scripting/abc.cpp:925 msgid "\t" msgstr "" #: ../scripting/abc.cpp:913 msgid "\tFinal" msgstr "" #: ../scripting/abc.cpp:915 msgid "\tInterface" msgstr "" #: ../scripting/abc.cpp:917 msgid "\tProtectedNS " msgstr "" #: ../scripting/abc.cpp:911 msgid "\tSealed" msgstr "" #: ../asobject.cpp:704 ../scripting/abc_codesynt.cpp:789 #: ../scripting/abc_codesynt.cpp:2253 ../scripting/abc.cpp:1513 #: ../scripting/abc.cpp:1786 ../scripting/abc_opcodes.cpp:1888 msgid " " msgstr "" #: ../scripting/abc.cpp:1418 ../scripting/abc.cpp:1480 #: ../scripting/abc.cpp:1583 ../scripting/abc.cpp:1622 #: ../scripting/abc.cpp:1662 msgid " #" msgstr "" #: ../swf.cpp:65 ../swf.cpp:69 msgid " Length " msgstr "" #: ../asobject.cpp:82 ../asobject.cpp:165 msgid " and type " msgstr "" #: ../parsing/tags.cpp:52 msgid " at byte " msgstr "" #: ../parsing/tags.cpp:52 ../scripting/actions.cpp:405 msgid " bytes" msgstr "" #: ../scripting/actions.cpp:1175 msgid " constants" msgstr "" #: ../backends/input.cpp:190 ../backends/input.cpp:266 msgid " events" msgstr "" #: ../scripting/abc.cpp:1355 msgid " events missing before exit" msgstr "" #: ../parsing/tags.cpp:224 ../parsing/tags.cpp:229 msgid " expected: " msgstr "" #: ../backends/graphics.cpp:132 ../backends/graphics.cpp:174 #: ../backends/graphics.cpp:199 msgid " height=" msgstr "" #: ../scripting/abc.cpp:1576 msgid " id " msgstr "" #: ../scripting/flashnet.cpp:726 msgid " in FLV" msgstr "" #: ../scripting/abc_opcodes.cpp:1774 ../scripting/abc_opcodes.cpp:1837 #: ../scripting/abc_opcodes.cpp:1888 msgid " is " msgstr "" #: ../scripting/abc.cpp:1137 msgid " is not yet valid" msgstr "" #: ../scripting/abc_opcodes.cpp:2277 msgid " is not yet valid (as interface)" msgstr "" #: ../parsing/tags.cpp:1364 ../parsing/tags.cpp:1531 msgid " name " msgstr "" #: ../scripting/abc.cpp:1131 msgid " not found in global" msgstr "" #: ../scripting/abc_opcodes.cpp:667 msgid " not supported in construct" msgstr "" #: ../swftypes.cpp:1087 msgid " of action data" msgstr "" #: ../scripting/abc_opcodes.cpp:349 ../scripting/abc_opcodes.cpp:783 msgid " on obj " msgstr "" #: ../scripting/abc_opcodes.cpp:825 msgid " on obj type " msgstr "" #: ../scripting/abc_opcodes.cpp:388 msgid " on type " msgstr "" #: ../backends/graphics.cpp:53 msgid " openGL errors" msgstr "" #: ../backends/rendering.cpp:285 ../backends/rendering.cpp:760 msgid " renderings" msgstr "" #: ../scripting/abc_codesynt.cpp:1482 msgid " should be intrinsic" msgstr "" #: ../threading.cpp:74 msgid " times" msgstr "" #: ../asobject.cpp:185 msgid " to float" msgstr "" #: ../asobject.cpp:178 msgid " to int" msgstr "" #: ../scripting/abc.cpp:1729 ../scripting/abc.cpp:1749 #: ../scripting/abc.cpp:1755 msgid " type " msgstr "" #: ../scripting/abc.cpp:1576 msgid " type Class name " msgstr "" #: ../scripting/abc.cpp:1755 msgid " vindex 0 " msgstr "" #: ../threading.cpp:74 msgid " waited " msgstr "" #: ../parsing/tags.cpp:52 ../scripting/actions.cpp:405 msgid " with length " msgstr "" #: ../parsing/tags.cpp:1325 ../parsing/tags.cpp:1492 msgid " with name " msgstr "" #: ../scripting/flashutils.cpp:326 msgid "' not found." msgstr "" #: ../scripting/abc_opcodes.cpp:164 msgid ") " msgstr "" #: ../parsing/tags.cpp:1815 msgid ", ScriptTimeoutSeconds: " msgstr "" #: ../parsing/tags.cpp:1851 msgid ", password: " msgstr "" #: ../scripting/abc_opcodes.cpp:1332 ../scripting/abc_opcodes.cpp:1373 msgid ", pushing Undefined" msgstr "" #: ../scripting/abc.cpp:1122 msgid ". Not binding" msgstr "" #: ../parsing/tags.cpp:224 ../parsing/tags.cpp:229 msgid ". Size=" msgstr "" #: ../swftypes.cpp:667 ../swftypes.cpp:699 ../backends/rendering.cpp:581 msgid "... Aborting" msgstr "" #: ../scripting/abc.cpp:1976 msgid "0 not allowed" msgstr "" #: ../scripting/abc_interpreter.cpp:773 ../scripting/abc_interpreter.cpp:1210 msgid ": " msgstr "" #: ../scripting/abc.cpp:1418 ../scripting/abc.cpp:1444 #: ../scripting/abc.cpp:1449 ../scripting/abc.cpp:1475 #: ../scripting/abc.cpp:1480 ../scripting/abc.cpp:1506 #: ../scripting/abc.cpp:1576 ../scripting/abc.cpp:1583 #: ../scripting/abc.cpp:1617 ../scripting/abc.cpp:1622 #: ../scripting/abc.cpp:1657 ../scripting/abc.cpp:1662 #: ../scripting/abc.cpp:1698 msgid "::" msgstr "" #: ../scripting/abc_opcodes.cpp:1080 ../scripting/abc_opcodes.cpp:1091 msgid "<<" msgstr "" #: ../scripting/abc_opcodes.cpp:1103 ../scripting/abc_opcodes.cpp:1113 #: ../scripting/abc_opcodes.cpp:1122 msgid ">>" msgstr "" #: ../scripting/abc.cpp:78 msgid "ABC Exec " msgstr "" #: ../scripting/abc.cpp:887 msgid "ABCVm version " msgstr "" #: ../scripting/toplevel.cpp:2099 msgid "ASString::charCodeAt not really implemented" msgstr "" #: ../scripting/actions.cpp:83 ../scripting/actions.cpp:150 msgid "AVM1 not supported" msgstr "" #: ../scripting/actions.h:311 msgid "ActionAdd2" msgstr "" #: ../scripting/actions.h:598 msgid "ActionAsciiToChar" msgstr "" #: ../scripting/actions.h:535 msgid "ActionBitAnd" msgstr "" #: ../scripting/actions.h:556 msgid "ActionBitLShift" msgstr "" #: ../scripting/actions.h:542 msgid "ActionBitOr" msgstr "" #: ../scripting/actions.h:563 msgid "ActionBitRShift" msgstr "" #: ../scripting/actions.h:549 msgid "ActionBitXor" msgstr "" #: ../scripting/actions.h:402 msgid "ActionCallFunction" msgstr "" #: ../scripting/actions.h:395 msgid "ActionCallMethod" msgstr "" #: ../scripting/actions.h:528 msgid "ActionCastOp" msgstr "" #: ../scripting/actions.h:409 msgid "ActionCloneSprite" msgstr "" #: ../scripting/actions.cpp:1397 ../scripting/actions.h:263 msgid "ActionConstantPool" msgstr "" #: ../scripting/actions.h:437 msgid "ActionDecrement" msgstr "" #: ../scripting/actions.h:146 msgid "ActionDefineFunction" msgstr "" #: ../scripting/actions.h:184 msgid "ActionDefineFunction2" msgstr "" #: ../scripting/actions.h:353 msgid "ActionDefineLocal" msgstr "" #: ../scripting/actions.h:458 msgid "ActionDelete" msgstr "" #: ../scripting/actions.h:325 msgid "ActionDivide" msgstr "" #: ../scripting/actions.h:479 msgid "ActionEnumerate" msgstr "" #: ../scripting/actions.h:507 msgid "ActionEnumerate2" msgstr "" #: ../scripting/actions.h:612 msgid "ActionEquals2" msgstr "" #: ../scripting/actions.h:430 msgid "ActionExtends" msgstr "" #: ../scripting/actions.h:110 msgid "ActionGetMember" msgstr "" #: ../scripting/actions.h:339 msgid "ActionGetProperty" msgstr "" #: ../scripting/actions.h:486 msgid "ActionGetTime" msgstr "" #: ../scripting/actions.h:252 msgid "ActionGetURL" msgstr "" #: ../scripting/actions.h:241 msgid "ActionGetURL2" msgstr "" #: ../scripting/actions.h:647 msgid "ActionGetVariable" msgstr "" #: ../scripting/actions.cpp:1408 ../scripting/actions.h:283 msgid "ActionGoToLabel" msgstr "" #: ../scripting/actions.h:231 msgid "ActionGotoFrame" msgstr "" #: ../scripting/actions.h:577 msgid "ActionGreater" msgstr "" #: ../scripting/actions.h:221 msgid "ActionIf" msgstr "" #: ../scripting/actions.h:423 msgid "ActionImplementsOp" msgstr "" #: ../scripting/actions.h:570 msgid "ActionIncrement" msgstr "" #: ../scripting/actions.h:465 msgid "ActionInitArray" msgstr "" #: ../scripting/actions.h:444 msgid "ActionInitObject" msgstr "" #: ../scripting/actions.h:493 msgid "ActionInstanceOf" msgstr "" #: ../scripting/actions.h:201 msgid "ActionJump" msgstr "" #: ../scripting/actions.cpp:999 msgid "ActionJump: " msgstr "" #: ../scripting/actions.h:591 msgid "ActionLess2" msgstr "" #: ../scripting/actions.h:318 msgid "ActionModulo" msgstr "" #: ../scripting/actions.h:360 msgid "ActionMultiply" msgstr "" #: ../scripting/actions.h:451 msgid "ActionNewMethod" msgstr "" #: ../scripting/actions.h:304 msgid "ActionNewObject" msgstr "" #: ../scripting/actions.h:388 msgid "ActionNot" msgstr "" #: ../scripting/actions.h:124 msgid "ActionPlay" msgstr "" #: ../scripting/actions.h:374 msgid "ActionPop" msgstr "" #: ../scripting/actions.cpp:1314 msgid "ActionPush" msgstr "" #: ../scripting/actions.h:332 msgid "ActionPushDuplicate" msgstr "" #: ../scripting/actions.h:346 msgid "ActionReturn" msgstr "" #: ../scripting/actions.h:117 msgid "ActionSetMember" msgstr "" #: ../scripting/actions.h:500 msgid "ActionSetProperty" msgstr "" #: ../scripting/actions.h:273 msgid "ActionSetTarget" msgstr "" #: ../scripting/actions.h:633 msgid "ActionSetTarget2" msgstr "" #: ../scripting/actions.h:626 msgid "ActionSetVariable" msgstr "" #: ../scripting/actions.h:131 msgid "ActionStop" msgstr "" #: ../scripting/actions.h:663 msgid "ActionStoreRegister" msgstr "" #: ../scripting/actions.h:605 msgid "ActionStrictEquals" msgstr "" #: ../scripting/actions.h:290 msgid "ActionStringAdd" msgstr "" #: ../scripting/actions.h:619 msgid "ActionStringEquals" msgstr "" #: ../scripting/actions.h:297 msgid "ActionStringExtract" msgstr "" #: ../scripting/actions.h:584 msgid "ActionStringGreater" msgstr "" #: ../scripting/actions.h:367 msgid "ActionSubtract" msgstr "" #: ../scripting/actions.cpp:859 ../scripting/actions.h:381 msgid "ActionToInteger" msgstr "" #: ../scripting/actions.h:521 msgid "ActionToNumber" msgstr "" #: ../scripting/actions.h:514 msgid "ActionToString" msgstr "" #: ../scripting/actions.h:416 msgid "ActionTrace" msgstr "" #: ../scripting/actions.h:472 msgid "ActionTypeOf" msgstr "" #: ../scripting/actions.h:211 msgid "ActionWith" msgstr "" #: ../scripting/abc_opcodes.cpp:1025 msgid "Add between integer and " msgstr "" #: ../scripting/abc_opcodes.cpp:980 msgid "Add between types " msgstr "" #: ../scripting/abc_opcodes.cpp:1068 msgid "Add between types number and " msgstr "" #: ../asobject.cpp:114 msgid "Add buildTraits for class " msgstr "" #: ../scripting/toplevel.cpp:3046 msgid "Array to bool" msgstr "" #: ../scripting/toplevel.cpp:179 msgid "Array::filter STUB" msgstr "" #: ../scripting/abc_opcodes.cpp:402 ../scripting/abc_opcodes.cpp:1381 msgid "Attaching this to function " msgstr "" #: ../backends/decoder.cpp:446 msgid "Audio channels " msgstr "" #: ../backends/decoder.cpp:438 msgid "Audio sample rate " msgstr "" #: ../scripting/abc.cpp:109 msgid "Binding " msgstr "" #: ../scripting/abc.cpp:1037 msgid "Binding of " msgstr "" #: ../scripting/toplevel.cpp:3079 msgid "Boolean conversion for type " msgstr "" #: ../scripting/toplevel.cpp:3031 msgid "Boolean to bool " msgstr "" #: ../scripting/abc_opcodes.cpp:2232 msgid "Building class traits" msgstr "" #: ../scripting/abc.cpp:1286 msgid "Building entry script traits: " msgstr "" #: ../scripting/abc.cpp:1067 ../scripting/toplevel.cpp:2725 msgid "Building instance traits" msgstr "" #: ../scripting/abc_opcodes.cpp:641 ../scripting/abc_opcodes.cpp:2002 msgid "Building method traits" msgstr "" #: ../scripting/abc.cpp:1264 msgid "Building script traits: " msgstr "" #: ../scripting/toplevel.cpp:2616 msgid "Building traits for " msgstr "" #: ../parsing/tags_stub.cpp:100 msgid "CSMTextSettingsTag" msgstr "" #: ../backends/netutils.cpp:278 msgid "CURL not enabled in this build. Downloader will always fail." msgstr "" #: ../scripting/toplevel.cpp:459 msgid "Called ASXML::load " msgstr "" #: ../scripting/toplevel.cpp:134 msgid "Called Array constructor" msgstr "" #: ../scripting/toplevel.cpp:426 msgid "Called MovieClipLoader constructor" msgstr "" #: ../scripting/toplevel.cpp:432 msgid "Called MovieClipLoader::addListener" msgstr "" #: ../scripting/toplevel.cpp:444 msgid "Called XML constructor" msgstr "" #: ../scripting/flashdisplay.cpp:524 msgid "Called swapDepths" msgstr "" #: ../scripting/abc_opcodes.cpp:2292 msgid "Calling Class init " msgstr "" #: ../scripting/toplevel.cpp:2660 msgid "Calling Instance init " msgstr "" #: ../scripting/abc_opcodes.cpp:1710 msgid "Calling an undefined function" msgstr "" #: ../scripting/abc_opcodes.cpp:349 ../scripting/abc_opcodes.cpp:783 #: ../scripting/abc_opcodes.cpp:1635 msgid "Calling an undefined function " msgstr "" #: ../scripting/toplevel.cpp:2818 msgid "Calling interface init for " msgstr "" #: ../asobject.cpp:596 ../asobject.cpp:639 ../asobject.cpp:864 msgid "Calling the getter" msgstr "" #: ../asobject.cpp:592 msgid "Calling the getter on type " msgstr "" #: ../asobject.cpp:352 ../asobject.cpp:385 msgid "Calling the setter" msgstr "" #: ../scripting/toplevel.cpp:1674 ../scripting/toplevel.cpp:1760 msgid "Calling with closure " msgstr "" #: ../asobject.cpp:178 ../asobject.cpp:185 msgid "Cannot convert object of type " msgstr "" #: ../plugin/plugin.cpp:351 msgid "Cannot handle UTF8 URLs" msgstr "" #: ../scripting/abc_opcodes.cpp:586 msgid "Cannot increment type " msgstr "" #: ../backends/rendering.cpp:514 msgid "Cannot initialize GLEW: cause " msgstr "" #: ../scripting/abc_opcodes.cpp:1726 msgid "Cannot retrieve type" msgstr "" #: ../scripting/abc_codesynt.cpp:789 ../scripting/abc_codesynt.cpp:2253 msgid "Case " msgstr "" #: ../scripting/abc_opcodes.cpp:691 msgid "Check" msgstr "" #: ../swf.cpp:528 msgid "Child process creation failed, lightspark continues" msgstr "" #: ../scripting/abc.cpp:908 ../scripting/abc.cpp:1131 #: ../scripting/abc.cpp:1137 ../scripting/abc_opcodes.cpp:2277 msgid "Class " msgstr "" #: ../scripting/abc.cpp:1576 msgid "Class slot " msgstr "" #: ../scripting/toplevel.cpp:3041 msgid "Class to bool" msgstr "" #: ../scripting/actions.cpp:461 msgid "CodeSize not consistent" msgstr "" #: ../scripting/actions.cpp:578 msgid "CodeSize not consistent with file offset " msgstr "" #: ../swf.cpp:69 msgid "Compressed SWF file: Version " msgstr "" #: ../backends/sound.cpp:258 msgid "Connection to PulseAudio server failed" msgstr "" #: ../scripting/abc.cpp:1729 msgid "Const " msgstr "" #: ../scripting/abc.cpp:1542 msgid "Constant kind " msgstr "" #: ../scripting/actions.cpp:1175 msgid "ConstantPool: Reading " msgstr "" #: ../scripting/abc_opcodes.cpp:610 ../scripting/abc_opcodes.cpp:700 #: ../scripting/abc_opcodes.cpp:1985 msgid "Constructing" msgstr "" #: ../scripting/abc.cpp:66 msgid "Corrupted ABC data: missing " msgstr "" #: ../backends/rendering.cpp:203 msgid "Could not find any GLX configuration" msgstr "" #: ../swf.cpp:607 msgid "Creating VM" msgstr "" #: ../scripting/toplevel.cpp:129 msgid "Creating array of length " msgstr "" #: ../backends/input.cpp:39 msgid "Creating input thread" msgstr "" #: ../scripting/abc_opcodes.cpp:1413 msgid "Cur prototype name " msgstr "" #: ../parsing/tags.cpp:1820 msgid "DebugIDTag Tag" msgstr "" #: ../parsing/tags.cpp:1825 msgid "DebugId " msgstr "" #: ../parsing/tags.cpp:1840 msgid "Debugger enabled, password: " msgstr "" #: ../parsing/tags.cpp:1851 msgid "Debugger enabled, reserved: " msgstr "" #: ../scripting/abc_opcodes.cpp:1387 ../scripting/abc_opcodes.cpp:1978 msgid "Deferred definition of property " msgstr "" #: ../parsing/tags.cpp:1757 msgid "DefineBinaryDataTag" msgstr "" #: ../parsing/tags_stub.cpp:76 msgid "DefineBitsJPEG2Tag Tag" msgstr "" #: ../parsing/tags.cpp:670 msgid "DefineBitsLossless2Tag::Render" msgstr "" #: ../parsing/tags.cpp:1672 msgid "DefineButton2Tag::Render" msgstr "" #: ../parsing/tags.cpp:266 msgid "DefineEditTextTag ID " msgstr "" #: ../parsing/tags.cpp:307 msgid "DefineEditTextTag: Render" msgstr "" #: ../parsing/tags.cpp:440 msgid "DefineFont" msgstr "" #: ../parsing/tags.cpp:465 msgid "DefineFont2" msgstr "" #: ../parsing/tags.cpp:554 msgid "DefineFont3" msgstr "" #: ../parsing/tags_stub.cpp:70 msgid "DefineFontAlignZonesTag Tag" msgstr "" #: ../parsing/tags_stub.cpp:40 msgid "DefineFontInfo Tag" msgstr "" #: ../parsing/tags_stub.cpp:64 msgid "DefineFontNameTag Tag" msgstr "" #: ../parsing/tags_stub.cpp:83 msgid "DefineScalingGridTag Tag on ID " msgstr "" #: ../parsing/tags_stub.cpp:94 msgid "DefineSceneAndFrameLabelDataTag" msgstr "" #: ../parsing/tags.cpp:867 msgid "DefineShape2Tag" msgstr "" #: ../parsing/tags.cpp:874 msgid "DefineShape3Tag" msgstr "" #: ../parsing/tags.cpp:881 msgid "DefineShape4Tag" msgstr "" #: ../parsing/tags.cpp:860 msgid "DefineShapeTag" msgstr "" #: ../parsing/tags.cpp:1785 msgid "DefineSound Tag" msgstr "" #: ../parsing/tags.cpp:343 msgid "DefineSprite ID: " msgstr "" #: ../parsing/tags.cpp:676 msgid "DefineText ID " msgstr "" #: ../parsing/tags.cpp:750 msgid "DefineText Render" msgstr "" #: ../parsing/tags.cpp:1730 msgid "DefineVideoStreamTag" msgstr "" #: ../parsing/tags.cpp:1741 msgid "DefineVideoStreamTag Render" msgstr "" #: ../scripting/actions.cpp:433 msgid "Defining function " msgstr "" #: ../scripting/actions.cpp:538 msgid "Defining function2 " msgstr "" #: ../scripting/flashutils.cpp:326 msgid "Definition for '" msgstr "" #: ../plugin/plugin.cpp:436 msgid "DestroyStream on main stream?" msgstr "" #: ../scripting/abc.cpp:59 msgid "DoABCTag Name: " msgstr "" #: ../scripting/actions.cpp:54 msgid "DoActionTag" msgstr "" #: ../scripting/actions.cpp:121 msgid "DoInitActionTag" msgstr "" #: ../backends/netutils.cpp:123 msgid "Downloaded file bigger than buffer: " msgstr "" #: ../scripting/abc.cpp:1206 msgid "Empty stack" msgstr "" #: ../parsing/tags.cpp:1845 msgid "EnableDebugger2Tag Tag" msgstr "" #: ../parsing/tags.cpp:1836 msgid "EnableDebuggerTag Tag" msgstr "" #: ../scripting/abc.cpp:1475 ../scripting/abc.cpp:1617 msgid "End Getter trait: " msgstr "" #: ../scripting/abc.cpp:1444 ../scripting/abc.cpp:1698 msgid "End Method trait: " msgstr "" #: ../scripting/abc.cpp:1506 ../scripting/abc.cpp:1657 msgid "End Setter trait: " msgstr "" #: ../scripting/actions.cpp:447 ../scripting/actions.cpp:563 msgid "End action in function" msgstr "" #: ../scripting/abc_opcodes.cpp:2297 msgid "End of Class init " msgstr "" #: ../scripting/abc.cpp:1299 msgid "End of Entry Point" msgstr "" #: ../scripting/abc.cpp:1039 msgid "End of binding of " msgstr "" #: ../scripting/abc_opcodes.cpp:2378 msgid "End of call " msgstr "" #: ../scripting/abc_opcodes.cpp:1638 msgid "End of callSuper " msgstr "" #: ../scripting/abc_opcodes.cpp:1712 msgid "End of callSuperVoid " msgstr "" #: ../scripting/abc_opcodes.cpp:343 ../scripting/abc_opcodes.cpp:353 #: ../scripting/abc_opcodes.cpp:817 ../scripting/abc_opcodes.cpp:835 msgid "End of calling " msgstr "" #: ../scripting/abc_opcodes.cpp:706 msgid "End of constructing" msgstr "" #: ../scripting/abc_opcodes.cpp:674 ../scripting/abc_opcodes.cpp:2030 msgid "End of constructing " msgstr "" #: ../scripting/abc_opcodes.cpp:1391 ../scripting/abc_opcodes.cpp:1982 msgid "End of deferred definition of property " msgstr "" #: ../scripting/abc.cpp:1140 ../scripting/abc_opcodes.cpp:2280 msgid "End of deferred init of class " msgstr "" #: ../asobject.cpp:603 ../asobject.cpp:643 ../asobject.cpp:869 msgid "End of getter" msgstr "" #: ../swf.cpp:828 msgid "End of parsing @ " msgstr "" #: ../asobject.cpp:363 ../asobject.cpp:392 msgid "End of setter" msgstr "" #: ../scripting/abc_opcodes.cpp:1420 msgid "End super construct " msgstr "" #: ../parsing/tags.cpp:392 msgid "EndDefineSprite ID: " msgstr "" #: ../parsing/tags.cpp:56 msgid "EndTag at position " msgstr "" #: ../asobject.cpp:165 msgid "Equal comparison between type " msgstr "" #: ../scripting/abc.cpp:1369 msgid "Error in VM " msgstr "" #: ../parsing/tags.cpp:224 ../parsing/tags.cpp:229 msgid "Error while reading tag " msgstr "" #: ../scripting/toplevel.cpp:2266 msgid "Error.getStackTrace not yet implemented." msgstr "" #: ../scripting/flashevents.cpp:323 msgid "Event not found" msgstr "" #: ../swf.cpp:870 msgid "Exception in ParseThread " msgstr "" #: ../backends/rendering.cpp:402 ../backends/rendering.cpp:894 msgid "Exception in RenderThread " msgstr "" #: ../swf.cpp:1102 msgid "Exception in RootMovieClip::tick " msgstr "" #: ../thread_pool.cpp:108 msgid "Exception in ThreadPool " msgstr "" #: ../scripting/flashnet.cpp:766 msgid "Exception in reading: " msgstr "" #: ../scripting/actions.cpp:701 msgid "Exec: ActionBitAnd" msgstr "" #: ../scripting/actions.cpp:716 msgid "Exec: ActionBitLShift" msgstr "" #: ../scripting/actions.cpp:706 msgid "Exec: ActionBitOr" msgstr "" #: ../scripting/actions.cpp:721 msgid "Exec: ActionBitRShift" msgstr "" #: ../scripting/actions.cpp:711 msgid "Exec: ActionBitXor" msgstr "" #: ../scripting/actions.cpp:741 msgid "Exec: ActionCastOp" msgstr "" #: ../scripting/actions.cpp:797 msgid "Exec: ActionCloneSprite" msgstr "" #: ../scripting/actions.cpp:654 msgid "Exec: ActionDecrement" msgstr "" #: ../scripting/actions.cpp:1005 msgid "Exec: ActionDelete" msgstr "" #: ../scripting/actions.cpp:681 msgid "Exec: ActionEnumerate" msgstr "" #: ../scripting/actions.cpp:726 msgid "Exec: ActionEnumerate2" msgstr "" #: ../scripting/actions.cpp:686 msgid "Exec: ActionGetTime" msgstr "" #: ../scripting/actions.cpp:696 msgid "Exec: ActionImplementsOp" msgstr "" #: ../scripting/actions.cpp:1086 msgid "Exec: ActionInitArray" msgstr "" #: ../scripting/actions.cpp:1091 msgid "Exec: ActionInitObject" msgstr "" #: ../scripting/actions.cpp:691 msgid "Exec: ActionInstanceOf" msgstr "" #: ../scripting/actions.cpp:1010 msgid "Exec: ActionNewMethod" msgstr "" #: ../scripting/actions.cpp:586 msgid "Exec: ActionPushDuplicate" msgstr "" #: ../scripting/actions.cpp:1015 ../scripting/actions.cpp:1020 msgid "Exec: ActionStringAdd" msgstr "" #: ../scripting/actions.cpp:1096 msgid "Exec: ActionStringEquals" msgstr "" #: ../scripting/actions.cpp:1025 msgid "Exec: ActionStringExtract" msgstr "" #: ../scripting/actions.cpp:772 msgid "Exec: ActionStringGreater" msgstr "" #: ../scripting/actions.cpp:736 msgid "Exec: ActionToNumber" msgstr "" #: ../scripting/actions.cpp:731 msgid "Exec: ActionToString" msgstr "" #: ../scripting/actions.cpp:1147 msgid "Exec: ActionToggleQuality" msgstr "" #: ../scripting/actions.cpp:802 msgid "Exec: ActionTrace" msgstr "" #: ../scripting/actions.cpp:676 msgid "Exec: ActionTypeOf" msgstr "" #: ../scripting/actions.cpp:1319 msgid "Exec: ActionWith" msgstr "" #: ../swf.cpp:561 msgid "Execve failed, content will not be rendered" msgstr "" #: ../scripting/actions.cpp:37 msgid "ExportAssetsTag Tag" msgstr "" #: ../parsing/flv.cpp:38 msgid "FLV file: Version " msgstr "" #: ../backends/rendering.cpp:909 msgid "FPS: " msgstr "" #: ../scripting/toplevel.cpp:2680 msgid "Failure in reference counting" msgstr "" #: ../backends/rendering.cpp:285 ../backends/rendering.cpp:760 msgid "Faking " msgstr "" #: ../backends/rendering.cpp:199 msgid "Falling back to no double buffering" msgstr "" #: ../parsing/tags.cpp:168 msgid "FileAttributes tag not in the beginning" msgstr "" #: ../parsing/tags.cpp:1768 msgid "FileAttributesTag Tag" msgstr "" #: ../swftypes.cpp:288 ../swftypes.cpp:304 msgid "Fill array extended not supported" msgstr "" #: ../swftypes.h:603 msgid "Fixed point bit field wider than 32 bit not supported" msgstr "" #: ../scripting/abc.cpp:909 msgid "Flags:" msgstr "" #: ../backends/rendering.cpp:85 msgid "Font File is " msgstr "" #: ../scripting/flashsystem.cpp:105 msgid "Found definition for " msgstr "" #: ../backends/rendering.cpp:442 msgid "Fragment shader compilation " msgstr "" #: ../swf.cpp:809 msgid "FrameRate " msgstr "" #: ../scripting/abc_opcodes.cpp:2375 msgid "Function not good " msgstr "" #: ../scripting/abc.cpp:2199 msgid "Function not implemented" msgstr "" #: ../backends/graphics.cpp:45 msgid "GL error " msgstr "" #: ../backends/rendering.cpp:584 msgid "GL errors during initialization: " msgstr "" #: ../backends/graphics.cpp:132 ../backends/graphics.cpp:174 #: ../backends/graphics.cpp:199 msgid "GL_INVALID_VALUE after glTexImage2D, width=" msgstr "" #: ../scripting/actions.cpp:1367 msgid "GetURL2" msgstr "" #: ../scripting/actions.cpp:1378 msgid "GetURL2: exec" msgstr "" #: ../scripting/actions.cpp:1373 msgid "GetURL: exec" msgstr "" #: ../scripting/abc.cpp:1472 msgid "Getter not linkable" msgstr "" #: ../scripting/abc.cpp:1449 ../scripting/abc.cpp:1583 msgid "Getter trait: " msgstr "" #: ../scripting/flashsystem.cpp:138 ../scripting/flashutils.cpp:341 msgid "Getting definition for " msgstr "" #: ../scripting/abc.cpp:961 msgid "Global is " msgstr "" #: ../scripting/flashevents.cpp:372 msgid "Handling event " msgstr "" #: ../backends/graphics.cpp:53 msgid "Ignoring " msgstr "" #: ../scripting/abc_codesynt.cpp:685 ../scripting/abc_codesynt.cpp:1596 msgid "Ignoring at " msgstr "" #: ../scripting/abc.cpp:922 msgid "Implements" msgstr "" #: ../backends/rendering.cpp:581 msgid "Incomplete FBO status " msgstr "" #: ../parsing/tags.cpp:388 msgid "Inconsistent frame count " msgstr "" #: ../scripting/toplevel.cpp:3070 msgid "Integer to bool" msgstr "" #: ../swf.cpp:511 msgid "Invoking gnash!" msgstr "" #: ../threading.cpp:51 msgid "Job terminated" msgstr "" #: ../scripting/toplevel.cpp:1779 msgid "LOG10E" msgstr "" #: ../scripting/toplevel.cpp:1780 msgid "LOG2E" msgstr "" #: ../scripting/abc_codesynt.cpp:1569 msgid "Last instruction before a new block was not a branch." msgstr "" #: ../scripting/abc.cpp:1277 msgid "Last script (Entry Point)" msgstr "" #: ../asobject.cpp:82 msgid "Less than comparison between type " msgstr "" #: ../swftypes.cpp:238 ../swftypes.cpp:265 msgid "Line array extended not supported" msgstr "" #: ../scripting/abc_opcodes.cpp:2193 msgid "Linking with interface " msgstr "" #: ../scripting/flashdisplay.cpp:196 msgid "Loader async execution " msgstr "" #: ../backends/netutils.cpp:394 msgid "LocalDownloader::execute: could not open local file: " msgstr "" #: ../backends/netutils.cpp:386 msgid "LocalDownloader::execute: reading from local file failed: " msgstr "" #: ../backends/netutils.cpp:359 msgid "LocalDownloader::execute: reading local file: " msgstr "" #: ../scripting/flashsystem.cpp:86 ../scripting/flashsystem.cpp:121 #: ../scripting/flashutils.cpp:319 msgid "Looking for definition of " msgstr "" #: ../parsing/tags.cpp:1815 msgid "MaxRecusionDepth: " msgstr "" #: ../parsing/tags.cpp:1858 msgid "MetaData: " msgstr "" #: ../parsing/tags.cpp:1856 msgid "MetadataTag Tag" msgstr "" #: ../scripting/abc_codesynt.cpp:1482 msgid "Method " msgstr "" #: ../scripting/abc.cpp:1441 msgid "Method not linkable" msgstr "" #: ../scripting/abc.cpp:1418 ../scripting/abc.cpp:1662 msgid "Method trait: " msgstr "" #: ../parsing/tags.cpp:1333 ../parsing/tags.cpp:1500 msgid "Moving of registered objects not really supported" msgstr "" #: ../scripting/abc.cpp:1933 msgid "Multibyte not handled" msgstr "" #: ../scripting/abc.cpp:339 ../scripting/abc.cpp:356 ../scripting/abc.cpp:488 #: ../scripting/abc.cpp:584 ../scripting/abc.cpp:619 ../scripting/abc.cpp:636 #: ../scripting/abc.cpp:782 msgid "Multiname to String not yet implemented for this kind " msgstr "" #: ../scripting/abc.cpp:1122 msgid "Multiple binding on " msgstr "" #: ../threading.cpp:74 msgid "Mutex " msgstr "" #: ../scripting/abc_opcodes.cpp:1332 ../scripting/abc_opcodes.cpp:1373 msgid "NOT found " msgstr "" #: ../scripting/abc_opcodes.cpp:1498 msgid "NOT found, pushing Undefined" msgstr "" #: ../scripting/abc_opcodes.cpp:1455 msgid "NOT found, pushing global" msgstr "" #: ../scripting/abc_opcodes.cpp:1369 ../scripting/abc_opcodes.cpp:1491 msgid "NOT found, trying Global" msgstr "" #: ../scripting/flashnet.cpp:439 msgid "NetStream constructor" msgstr "" #: ../scripting/flashnet.cpp:516 msgid "NetStream::close called" msgstr "" #: ../scripting/abc_codesynt.cpp:676 ../scripting/abc_codesynt.cpp:731 msgid "New block at " msgstr "" #: ../plugin/plugin.cpp:365 msgid "Newstream for " msgstr "" #: ../scripting/abc.cpp:1412 ../scripting/abc.cpp:1558 msgid "Next slot has flags " msgstr "" #: ../parsing/flv.cpp:43 msgid "No FLV file signature found" msgstr "" #: ../swf.cpp:73 msgid "No SWF file signature found" msgstr "" #: ../backends/geometry.cpp:46 msgid "No edges in this shape" msgstr "" #: ../main.cpp:196 ../tightspark.cpp:94 msgid "No execution model enabled" msgstr "" #: ../plugin/plugin.cpp:266 msgid "No size in SetWindow" msgstr "" #: ../swf.cpp:1063 msgid "No such Id on dictionary " msgstr "" #: ../backends/rendering.cpp:217 msgid "No suitable graphics configuration available" msgstr "" #: ../backends/rendering.cpp:573 msgid "Non enough color attachments available, input disabled" msgstr "" #: ../scripting/flashdisplay.cpp:492 msgid "Not a function" msgstr "" #: ../scripting/flashdisplay.cpp:601 msgid "Not enough frames loaded" msgstr "" #: ../scripting/flashevents.cpp:368 msgid "Not handled event " msgstr "" #: ../scripting/actions.h:640 msgid "Not implemented action" msgstr "" #: ../scripting/abc_codesynt.cpp:1356 ../scripting/abc_codesynt.cpp:3928 msgid "Not implemented instruction @" msgstr "" #: ../scripting/flashevents.cpp:281 msgid "Not implemented mode for addEventListener" msgstr "" #: ../scripting/abc_interpreter.cpp:1261 msgid "Not intepreted instruction @" msgstr "" #: ../scripting/actions.cpp:68 ../scripting/actions.cpp:135 #: ../scripting/actions.cpp:453 ../scripting/actions.cpp:569 msgid "Not supported action opcode" msgstr "" #: ../swftypes.cpp:667 ../swftypes.cpp:699 msgid "Not supported fill style " msgstr "" #: ../scripting/toplevel.cpp:3056 msgid "Null to bool" msgstr "" #: ../scripting/toplevel.cpp:3061 msgid "Number to bool" msgstr "" #: ../scripting/abc_opcodes.cpp:1740 ../scripting/abc_opcodes.cpp:1794 #: ../scripting/abc_opcodes.cpp:1855 msgid "Numeric type is " msgstr "" #: ../scripting/abc_opcodes.cpp:303 msgid "Object" msgstr "" #: ../scripting/toplevel.cpp:3036 msgid "Object to bool" msgstr "" #: ../scripting/abc_opcodes.cpp:667 msgid "Object type " msgstr "" #: ../asobject.cpp:139 ../asobject.cpp:161 msgid "Overloaded isEqual" msgstr "" #: ../asobject.cpp:78 msgid "Overloaded isLess" msgstr "" #: ../swf.cpp:266 msgid "Parameters file not found" msgstr "" #: ../asobject.cpp:503 msgid "Passthorugh of " msgstr "" #: ../parsing/tags.cpp:1373 msgid "PlaceObject2" msgstr "" #: ../parsing/tags.cpp:1540 msgid "PlaceObject3" msgstr "" #: ../parsing/tags.cpp:1271 ../parsing/tags.cpp:1438 msgid "Placing ID " msgstr "" #: ../parsing/tags.cpp:1602 msgid "ProductInfoTag Tag" msgstr "" #: ../scripting/abc_opcodes.cpp:388 ../scripting/abc_opcodes.cpp:392 msgid "Property not found " msgstr "" #: ../parsing/tags_stub.cpp:34 msgid "Protect Tag" msgstr "" #: ../scripting/abc_opcodes.cpp:338 ../scripting/abc_opcodes.cpp:811 msgid "Proxy::callProperty" msgstr "" #: ../scripting/flashutils.cpp:628 msgid "Proxy::getProperty" msgstr "" #: ../scripting/flashutils.cpp:638 msgid "Proxy::hasNext" msgstr "" #: ../scripting/flashutils.cpp:656 msgid "Proxy::nextName" msgstr "" #: ../scripting/flashutils.cpp:601 msgid "Proxy::setProperty" msgstr "" #: ../scripting/actions.cpp:1304 msgid "Push type: " msgstr "" #: ../scripting/actions.cpp:1262 msgid "Push: Read bool " msgstr "" #: ../scripting/actions.cpp:1290 msgid "Push: Read constant index " msgstr "" #: ../scripting/actions.cpp:1271 msgid "Push: Read double " msgstr "" #: ../scripting/actions.cpp:1231 msgid "Push: Read float " msgstr "" #: ../scripting/actions.cpp:1280 msgid "Push: Read integer " msgstr "" #: ../scripting/actions.cpp:1300 msgid "Push: Read long constant index " msgstr "" #: ../scripting/actions.cpp:1253 msgid "Push: Read reg number " msgstr "" #: ../scripting/actions.cpp:1222 msgid "Push: Read string " msgstr "" #: ../scripting/actions.cpp:1237 msgid "Push: null" msgstr "" #: ../scripting/actions.cpp:1243 msgid "Push: undefined" msgstr "" #: ../parsing/tags.cpp:52 msgid "Reading tag type: " msgstr "" #: ../backends/graphics.cpp:192 msgid "Reallocating texture to size " msgstr "" #: ../parsing/tags.cpp:1325 ../parsing/tags.cpp:1492 msgid "Registering ID " msgstr "" #: ../parsing/tags.cpp:239 msgid "RemoveObject2 Depth: " msgstr "" #: ../backends/rendering.cpp:57 msgid "RenderThread this=" msgstr "" #: ../scripting/abc.cpp:1177 msgid "Requested invalid method" msgstr "" #: ../swftypes.cpp:395 msgid "Reserved bits not so reserved" msgstr "" #: ../swftypes.cpp:538 msgid "Reverting to fixed function" msgstr "" #: ../main.cpp:218 msgid "Running in local-with-filesystem sandbox" msgstr "" #: ../main.cpp:214 msgid "Running in remote sandbox" msgstr "" #: ../parsing/tags.cpp:1611 msgid "SWF Info:" msgstr "" #: ../scripting/abc.cpp:1256 msgid "Script N: " msgstr "" #: ../parsing/tags.cpp:1813 msgid "ScriptLimitsTag Tag" msgstr "" #: ../scripting/flashsystem.cpp:199 msgid "Security::allowDomain" msgstr "" #: ../scripting/flashsystem.cpp:205 msgid "Security::allowInsecureDomain" msgstr "" #: ../scripting/flashsystem.cpp:211 msgid "Security::loadPolicyFile" msgstr "" #: ../scripting/flashsystem.cpp:217 msgid "Security::showSettings" msgstr "" #: ../scripting/abc.cpp:1503 msgid "Setter not linkable" msgstr "" #: ../scripting/abc.cpp:1480 ../scripting/abc.cpp:1622 msgid "Setter trait: " msgstr "" #: ../scripting/abc.cpp:1126 msgid "Setting class name to " msgstr "" #: ../backends/rendering.cpp:428 msgid "Shader lightspark.frag not found" msgstr "" #: ../backends/rendering.cpp:465 msgid "Shader lightspark.vert not found" msgstr "" #: ../parsing/tags.cpp:768 msgid "Should be a FontTag" msgstr "" #: ../parsing/tags.cpp:1224 msgid "ShowFrame" msgstr "" #: ../swftypes.h:665 msgid "Signed bit field wider than 32 bit not supported" msgstr "" #: ../swftypes.cpp:1087 msgid "Skipping " msgstr "" #: ../scripting/abc.cpp:1749 ../scripting/abc.cpp:1755 msgid "Slot " msgstr "" #: ../parsing/tags_stub.cpp:88 msgid "SoundStreamBlockTag" msgstr "" #: ../parsing/tags_stub.cpp:52 msgid "SoundStreamHead Tag" msgstr "" #: ../parsing/tags_stub.cpp:58 msgid "SoundStreamHead2 Tag" msgstr "" #: ../scripting/flashmedia.cpp:45 msgid "SoundTransform constructor" msgstr "" #: ../scripting/abc.cpp:1230 msgid "Stack not clean at the end of function" msgstr "" #: ../parsing/tags_stub.cpp:46 msgid "StartSound Tag" msgstr "" #: ../scripting/abc_codesynt.cpp:1574 msgid "Starting block at " msgstr "" #: ../scripting/toplevel.cpp:3021 msgid "String to bool" msgstr "" #: ../swftypes.cpp:621 msgid "Style not implemented" msgstr "" #: ../scripting/abc.cpp:919 msgid "Super " msgstr "" #: ../scripting/abc_opcodes.cpp:1416 msgid "Super prototype name " msgstr "" #: ../scripting/abc_interpreter.cpp:397 msgid "Switch default dest " msgstr "" #: ../scripting/abc_interpreter.cpp:404 msgid "Switch dest " msgstr "" #: ../scripting/abc.cpp:93 msgid "SymbolClassTag" msgstr "" #: ../scripting/abc.cpp:105 msgid "SymbolClassTag Exec" msgstr "" #: ../parsing/tags.cpp:300 msgid "Sync to variable name " msgstr "" #: ../scripting/flashevents.cpp:119 msgid "Target for event " msgstr "" #: ../scripting/flashtext.cpp:100 msgid "TextField::Render" msgstr "" #: ../scripting/abc.cpp:1513 ../scripting/abc.cpp:1786 msgid "Trait not supported " msgstr "" #: ../asobject.cpp:84 ../asobject.cpp:167 ../scripting/abc_opcodes.cpp:1774 #: ../scripting/abc_opcodes.cpp:1837 ../scripting/abc_opcodes.cpp:1888 msgid "Type " msgstr "" #: ../backends/rendering.cpp:78 msgid "Unable to find suitable Serif font" msgstr "" #: ../backends/rendering.cpp:238 msgid "Unable to load serif font" msgstr "" #: ../parsing/tags.cpp:375 msgid "Unclassified tag inside Sprite?" msgstr "" #: ../swf.cpp:65 msgid "Uncompressed SWF file: Version " msgstr "" #: ../scripting/toplevel.cpp:1180 msgid "Undefined function" msgstr "" #: ../scripting/toplevel.cpp:3051 msgid "Undefined to bool" msgstr "" #: ../timer.cpp:164 msgid "Unexpected failure of sem_timedwait.. Trying to go on. errno=" msgstr "" #: ../scripting/abc.cpp:2113 msgid "Unexpected kind " msgstr "" #: ../scripting/abc.cpp:2021 msgid "Unexpected multiname kind " msgstr "" #: ../scripting/abc.cpp:2045 msgid "Unexpected options type" msgstr "" #: ../scripting/flashnet.cpp:726 msgid "Unexpected tag type " msgstr "" #: ../scripting/toplevel.cpp:2162 msgid "Unicode not supported in String::fromCharCode" msgstr "" #: ../parsing/tags_stub.cpp:106 msgid "Unimplemented Tag " msgstr "" #: ../swftypes.h:647 msgid "Unsigned bit field wider than 32 bit not supported" msgstr "" #: ../scripting/actions.cpp:405 msgid "Unsupported ActionCode " msgstr "" #: ../swftypes.cpp:907 msgid "Unsupported Filter Id " msgstr "" #: ../parsing/tags.cpp:209 msgid "Unsupported tag type " msgstr "" #: ../backends/rendering.cpp:473 msgid "Vertex shader compilation " msgstr "" #: ../backends/rendering.cpp:519 msgid "Video card does not support OpenGL 2.0... Aborting" msgstr "" #: ../backends/decoder.cpp:40 msgid "Video frame size " msgstr "" #: ../scripting/abc_opcodes.cpp:1596 ../scripting/abc_opcodes.cpp:1680 msgid "We got a Undefined function" msgstr "" #: ../scripting/abc_opcodes.cpp:825 ../scripting/abc_opcodes.cpp:829 msgid "We got a Undefined function " msgstr "" #: ../scripting/abc_opcodes.cpp:303 msgid "We got a Undefined function on obj " msgstr "" #: ../scripting/abc_opcodes.cpp:285 msgid "We got a function not yet valid" msgstr "" #: ../scripting/abc_opcodes.cpp:1322 ../scripting/flashsystem.cpp:96 #: ../scripting/flashutils.cpp:333 msgid "We got an object not yet valid" msgstr "" #: ../backends/input.cpp:190 ../backends/input.cpp:266 msgid "We still miss " msgstr "" #: ../scripting/flashevents.cpp:292 msgid "Weird event reregistration" msgstr "" #: ../backends/rendering.cpp:259 msgid "Window resize not supported in plugin" msgstr "" #: ../asobject.cpp:704 msgid "[" msgstr "" #: ../scripting/abc_opcodes.cpp:169 ../scripting/abc_opcodes.cpp:174 msgid "]" msgstr "" #: ../asobject.cpp:704 ../scripting/abc_opcodes.cpp:921 #: ../scripting/abc_opcodes.cpp:927 ../scripting/abc_opcodes.cpp:933 msgid "] " msgstr "" #: ../scripting/abc_opcodes.cpp:164 msgid "] (" msgstr "" #: ../scripting/abc_opcodes.cpp:159 ../scripting/abc_opcodes.cpp:179 msgid "] (int)= " msgstr "" #: ../scripting/abc_opcodes.cpp:184 msgid "] = " msgstr "" #: ../scripting/abc_opcodes.cpp:948 ../scripting/abc_opcodes.cpp:964 #: ../scripting/abc_opcodes.cpp:973 ../scripting/abc_opcodes.cpp:995 #: ../scripting/abc_opcodes.cpp:1003 ../scripting/abc_opcodes.cpp:1012 #: ../scripting/abc_opcodes.cpp:1039 ../scripting/abc_opcodes.cpp:1047 #: ../scripting/abc_opcodes.cpp:1055 msgid "add " msgstr "" #: ../scripting/abc_opcodes.cpp:1846 msgid "asTypelate" msgstr "" #: ../scripting/abc_opcodes.cpp:44 msgid "bitAnd_oi " msgstr "" #: ../scripting/abc_opcodes.cpp:35 msgid "bitAnd_oo " msgstr "" #: ../scripting/abc_opcodes.cpp:223 msgid "bitNot " msgstr "" #: ../scripting/abc_opcodes.cpp:242 ../scripting/abc_opcodes.cpp:252 msgid "bitOr " msgstr "" #: ../scripting/abc_opcodes.cpp:233 msgid "bitXor " msgstr "" #: ../scripting/abc_codesynt.cpp:751 msgid "block analysis: branches" msgstr "" #: ../scripting/abc_codesynt.cpp:713 msgid "block analysis: kill" msgstr "" #: ../scripting/abc_opcodes.cpp:2351 msgid "call " msgstr "" #: ../scripting/abc_opcodes.cpp:748 msgid "callPropVoid " msgstr "" #: ../scripting/abc_opcodes.cpp:263 msgid "callProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:1568 msgid "callSuper " msgstr "" #: ../scripting/abc_opcodes.cpp:1651 msgid "callSuperVoid " msgstr "" #: ../scripting/toplevel.cpp:2028 msgid "capturing groups " msgstr "" #: ../scripting/abc_opcodes.cpp:149 msgid "coerce " msgstr "" #: ../scripting/abc_opcodes.cpp:133 msgid "coerce_a" msgstr "" #: ../scripting/abc_opcodes.cpp:143 msgid "coerce_s" msgstr "" #: ../scripting/abc_opcodes.cpp:593 msgid "construct " msgstr "" #: ../scripting/abc_opcodes.cpp:682 msgid "constructGenericType " msgstr "" #: ../scripting/abc_opcodes.cpp:1957 msgid "constructProp " msgstr "" #: ../scripting/abc_opcodes.cpp:1399 msgid "constructSuper " msgstr "" #: ../scripting/abc_opcodes.cpp:87 msgid "convert_b" msgstr "" #: ../scripting/abc_opcodes.cpp:74 msgid "convert_d" msgstr "" #: ../scripting/abc_opcodes.cpp:103 msgid "convert_i" msgstr "" #: ../scripting/abc_opcodes.cpp:95 msgid "convert_u" msgstr "" #: ../scripting/abc_codesynt.cpp:784 ../scripting/abc_codesynt.cpp:2248 msgid "count " msgstr "" #: ../scripting/flashdisplay.cpp:505 msgid "createEmptyMovieClip" msgstr "" #: ../scripting/abc.cpp:876 msgid "dMultiname to String not yet implemented for this kind " msgstr "" #: ../scripting/abc_interpreter.cpp:1233 msgid "debug" msgstr "" #: ../scripting/abc_codesynt.cpp:37 msgid "debug_d " msgstr "" #: ../scripting/abc_codesynt.cpp:42 msgid "debug_i " msgstr "" #: ../scripting/abc_interpreter.cpp:1255 msgid "debugfile" msgstr "" #: ../scripting/abc_interpreter.cpp:1247 msgid "debugline" msgstr "" #: ../scripting/abc_opcodes.cpp:465 msgid "decrement" msgstr "" #: ../scripting/abc_opcodes.cpp:474 msgid "decrement_i" msgstr "" #: ../scripting/abc_codesynt.cpp:781 ../scripting/abc_codesynt.cpp:2245 msgid "default " msgstr "" #: ../scripting/abc_opcodes.cpp:2386 msgid "deleteProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:437 msgid "divide " msgstr "" #: ../scripting/abc_opcodes.cpp:429 msgid "divide: HACK" msgstr "" #: ../scripting/abc_codesynt.cpp:1359 ../scripting/abc_codesynt.cpp:3931 #: ../scripting/abc_interpreter.cpp:1262 msgid "dump " msgstr "" #: ../scripting/abc_opcodes.cpp:1183 msgid "dup: DONE" msgstr "" #: ../scripting/abc_opcodes.cpp:1137 msgid "equals " msgstr "" #: ../scripting/abc_opcodes.cpp:1467 msgid "findPropStrict " msgstr "" #: ../scripting/abc_opcodes.cpp:1430 msgid "findProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:458 msgid "getGlobalScope: " msgstr "" #: ../scripting/abc_opcodes.cpp:1342 msgid "getLex: " msgstr "" #: ../scripting/abc_interpreter.cpp:773 ../scripting/abc_interpreter.cpp:1210 msgid "getLocal " msgstr "" #: ../scripting/abc_opcodes.cpp:159 ../scripting/abc_opcodes.cpp:164 #: ../scripting/abc_opcodes.cpp:169 msgid "getLocal[" msgstr "" #: ../scripting/abc.cpp:306 msgid "getMultinameRTData not yet implemented for this kind " msgstr "" #: ../scripting/abc_opcodes.cpp:372 msgid "getProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:361 msgid "getProperty_i " msgstr "" #: ../scripting/abc_opcodes.cpp:2415 msgid "getScopeObject: " msgstr "" #: ../scripting/abc_opcodes.cpp:204 msgid "getSlot " msgstr "" #: ../scripting/abc_opcodes.cpp:1298 msgid "getSuper " msgstr "" #: ../scripting/toplevel.cpp:1463 msgid "getTimezoneOffset" msgstr "" #: ../backends/rendering.cpp:190 msgid "glX not present" msgstr "" #: ../scripting/abc_opcodes.cpp:1521 msgid "greaterEquals" msgstr "" #: ../scripting/abc_opcodes.cpp:1510 msgid "greaterThan" msgstr "" #: ../scripting/abc_opcodes.cpp:2035 msgid "hasNext2 " msgstr "" #: ../scripting/abc_opcodes.cpp:1903 msgid "ifEq (" msgstr "" #: ../scripting/abc_opcodes.cpp:1943 msgid "ifFalse (" msgstr "" #: ../scripting/abc_opcodes.cpp:1252 msgid "ifGE (" msgstr "" #: ../scripting/abc_opcodes.cpp:1209 msgid "ifGT (" msgstr "" #: ../scripting/abc_opcodes.cpp:1232 msgid "ifLE (" msgstr "" #: ../scripting/abc_opcodes.cpp:496 msgid "ifLT (" msgstr "" #: ../scripting/abc_opcodes.cpp:520 msgid "ifLT_io " msgstr "" #: ../scripting/abc_opcodes.cpp:505 msgid "ifLT_oi" msgstr "" #: ../scripting/abc_opcodes.cpp:532 ../scripting/abc_opcodes.cpp:545 msgid "ifNE (" msgstr "" #: ../scripting/abc_opcodes.cpp:1262 msgid "ifNGE (" msgstr "" #: ../scripting/abc_opcodes.cpp:1221 msgid "ifNGT (" msgstr "" #: ../scripting/abc_opcodes.cpp:1242 msgid "ifNLE (" msgstr "" #: ../scripting/abc_opcodes.cpp:485 msgid "ifNLT (" msgstr "" #: ../scripting/abc_opcodes.cpp:1921 msgid "ifStrictEq " msgstr "" #: ../scripting/abc_opcodes.cpp:1927 msgid "ifStrictNE" msgstr "" #: ../scripting/abc_opcodes.cpp:846 msgid "ifTrue (" msgstr "" #: ../scripting/abc_opcodes.cpp:1933 msgid "in" msgstr "" #: ../scripting/abc_opcodes.cpp:578 msgid "incLocal_i " msgstr "" #: ../scripting/abc_opcodes.cpp:2130 msgid "increment_i" msgstr "" #: ../scripting/abc_opcodes.cpp:1547 msgid "initProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:1720 msgid "isType " msgstr "" #: ../scripting/abc_opcodes.cpp:1768 msgid "isType on non classed object " msgstr "" #: ../scripting/abc_opcodes.cpp:1782 msgid "isTypelate" msgstr "" #: ../scripting/abc_opcodes.cpp:1830 msgid "isTypelate on non classed object " msgstr "" #: ../scripting/abc_opcodes.cpp:840 msgid "jump " msgstr "" #: ../scripting/abc_opcodes.cpp:938 msgid "kill " msgstr "" #: ../scripting/abc_opcodes.cpp:1080 ../scripting/abc_opcodes.cpp:1091 msgid "lShift " msgstr "" #: ../scripting/abc_opcodes.cpp:111 msgid "label" msgstr "" #: ../scripting/abc_opcodes.cpp:1532 msgid "lessEquals" msgstr "" #: ../scripting/abc_opcodes.cpp:2334 msgid "lessThan" msgstr "" #: ../scripting/abc_opcodes.cpp:116 msgid "lookupswitch" msgstr "" #: ../scripting/abc_opcodes.cpp:859 msgid "modulo " msgstr "" #: ../scripting/abc_opcodes.cpp:572 msgid "multiply " msgstr "" #: ../scripting/abc_opcodes.cpp:562 msgid "multiply_oi " msgstr "" #: ../scripting/abc_opcodes.cpp:213 msgid "negate" msgstr "" #: ../scripting/abc_opcodes.cpp:2309 msgid "newActivation" msgstr "" #: ../scripting/abc_opcodes.cpp:2434 msgid "newArray " msgstr "" #: ../scripting/abc_opcodes.cpp:2428 msgid "newCatch " msgstr "" #: ../scripting/abc_opcodes.cpp:2200 msgid "newClass " msgstr "" #: ../scripting/abc_opcodes.cpp:2398 msgid "newFunction " msgstr "" #: ../scripting/abc_opcodes.cpp:2090 msgid "newObject " msgstr "" #: ../scripting/abc_opcodes.cpp:2164 msgid "nextName" msgstr "" #: ../scripting/abc_opcodes.cpp:2139 msgid "nextValue" msgstr "" #: ../parsing/tags.cpp:1364 ../parsing/tags.cpp:1531 msgid "no char to move at depth " msgstr "" #: ../scripting/abc_opcodes.cpp:1128 msgid "not" msgstr "" #: ../scripting/abc_opcodes.cpp:1888 msgid "not " msgstr "" #: ../scripting/abc.cpp:1184 msgid "not implement opcode 0x" msgstr "" #: ../scripting/abc_opcodes.cpp:1943 msgid "not taken" msgstr "" #: ../scripting/abc_opcodes.cpp:485 ../scripting/abc_opcodes.cpp:496 #: ../scripting/abc_opcodes.cpp:532 ../scripting/abc_opcodes.cpp:545 #: ../scripting/abc_opcodes.cpp:846 ../scripting/abc_opcodes.cpp:1209 #: ../scripting/abc_opcodes.cpp:1221 ../scripting/abc_opcodes.cpp:1232 #: ../scripting/abc_opcodes.cpp:1242 ../scripting/abc_opcodes.cpp:1252 #: ../scripting/abc_opcodes.cpp:1262 ../scripting/abc_opcodes.cpp:1903 msgid "not taken)" msgstr "" #: ../scripting/abc.cpp:1839 msgid "parsing s32" msgstr "" #: ../scripting/abc.cpp:1889 ../scripting/abc.cpp:1893 msgid "parsing u30" msgstr "" #: ../scripting/abc.cpp:1814 msgid "parsing u32 " msgstr "" #: ../scripting/abc_opcodes.cpp:154 msgid "pop: DONE" msgstr "" #: ../scripting/abc_opcodes.cpp:2327 msgid "popScope" msgstr "" #: ../thread_pool.cpp:68 msgid "pthread_join failed in ~ThreadPool" msgstr "" #: ../scripting/abc.cpp:989 msgid "pthread_join in ABCVm failed" msgstr "" #: ../scripting/abc_opcodes.cpp:553 msgid "pushByte " msgstr "" #: ../scripting/abc_opcodes.cpp:933 msgid "pushDouble [" msgstr "" #: ../scripting/abc_opcodes.cpp:1194 msgid "pushFalse" msgstr "" #: ../scripting/abc_opcodes.cpp:927 msgid "pushInt [" msgstr "" #: ../scripting/abc_opcodes.cpp:1200 msgid "pushNaN" msgstr "" #: ../scripting/abc_opcodes.cpp:127 msgid "pushNull" msgstr "" #: ../scripting/abc_opcodes.cpp:451 msgid "pushScope " msgstr "" #: ../scripting/abc_opcodes.cpp:189 msgid "pushShort " msgstr "" #: ../scripting/abc_opcodes.cpp:2422 msgid "pushString " msgstr "" #: ../scripting/abc_opcodes.cpp:1188 msgid "pushTrue" msgstr "" #: ../scripting/abc_opcodes.cpp:921 msgid "pushUInt [" msgstr "" #: ../scripting/abc_opcodes.cpp:121 msgid "pushUndefined" msgstr "" #: ../scripting/abc_opcodes.cpp:444 msgid "pushWith " msgstr "" #: ../scripting/abc_opcodes.cpp:1103 msgid "rShift " msgstr "" #: ../scripting/toplevel.cpp:2026 msgid "re: " msgstr "" #: ../scripting/abc_interpreter.cpp:636 msgid "returnValue " msgstr "" #: ../scripting/abc_interpreter.cpp:629 msgid "returnVoid" msgstr "" #: ../scripting/abc_interpreter.cpp:782 ../scripting/abc_interpreter.cpp:1222 msgid "setLocal " msgstr "" #: ../scripting/abc_opcodes.cpp:174 ../scripting/abc_opcodes.cpp:179 #: ../scripting/abc_opcodes.cpp:184 msgid "setLocal[" msgstr "" #: ../scripting/abc_opcodes.cpp:50 msgid "setProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:66 msgid "setProperty_i " msgstr "" #: ../scripting/abc_opcodes.cpp:195 msgid "setSlot " msgstr "" #: ../scripting/abc_opcodes.cpp:1277 msgid "setSuper " msgstr "" #: ../scripting/abc_opcodes.cpp:1174 msgid "strictEquals" msgstr "" #: ../scripting/abc_opcodes.cpp:914 msgid "subtract " msgstr "" #: ../scripting/abc_opcodes.cpp:889 ../scripting/abc_opcodes.cpp:906 msgid "subtract: HACK" msgstr "" #: ../scripting/abc_opcodes.cpp:880 msgid "subtract_do " msgstr "" #: ../scripting/abc_opcodes.cpp:896 msgid "subtract_io " msgstr "" #: ../scripting/abc_opcodes.cpp:869 msgid "subtract_oi " msgstr "" #: ../scripting/abc_opcodes.cpp:2304 msgid "swap" msgstr "" #: ../scripting/abc_codesynt.cpp:3287 msgid "synt add" msgstr "" #: ../scripting/abc_codesynt.cpp:3184 msgid "synt astypelate" msgstr "" #: ../scripting/abc_codesynt.cpp:3594 msgid "synt bitand" msgstr "" #: ../scripting/abc_codesynt.cpp:3270 msgid "synt bitnot" msgstr "" #: ../scripting/abc_codesynt.cpp:3627 msgid "synt bitor" msgstr "" #: ../scripting/abc_codesynt.cpp:3649 msgid "synt bitxor" msgstr "" #: ../scripting/abc_codesynt.cpp:2542 msgid "synt call" msgstr "" #: ../scripting/abc_codesynt.cpp:2578 msgid "synt callproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:2692 msgid "synt callpropvoid" msgstr "" #: ../scripting/abc_codesynt.cpp:2564 msgid "synt callsuper" msgstr "" #: ../scripting/abc_codesynt.cpp:2679 msgid "synt callsupervoid" msgstr "" #: ../scripting/abc_codesynt.cpp:3139 msgid "synt checkfilter" msgstr "" #: ../scripting/abc_codesynt.cpp:3149 msgid "synt coerce" msgstr "" #: ../scripting/abc_codesynt.cpp:3160 msgid "synt coerce_a" msgstr "" #: ../scripting/abc_codesynt.cpp:3174 msgid "synt coerce_s" msgstr "" #: ../scripting/abc_codesynt.cpp:2553 msgid "synt construct" msgstr "" #: ../scripting/abc_codesynt.cpp:2705 msgid "synt constructgenerictype" msgstr "" #: ../scripting/abc_codesynt.cpp:2666 msgid "synt constructprop" msgstr "" #: ../scripting/abc_codesynt.cpp:2655 msgid "synt constructsuper" msgstr "" #: ../scripting/abc_codesynt.cpp:3125 msgid "synt convert_b" msgstr "" #: ../scripting/abc_codesynt.cpp:3110 msgid "synt convert_d" msgstr "" #: ../scripting/abc_codesynt.cpp:3080 msgid "synt convert_i" msgstr "" #: ../scripting/abc_codesynt.cpp:3074 msgid "synt convert_s" msgstr "" #: ../scripting/abc_codesynt.cpp:3095 msgid "synt convert_u" msgstr "" #: ../scripting/abc_codesynt.cpp:3900 msgid "synt debug" msgstr "" #: ../scripting/abc_codesynt.cpp:3922 msgid "synt debugfile" msgstr "" #: ../scripting/abc_codesynt.cpp:3914 msgid "synt debugline" msgstr "" #: ../scripting/abc_codesynt.cpp:3228 msgid "synt decrement" msgstr "" #: ../scripting/abc_codesynt.cpp:3791 msgid "synt decrement_i" msgstr "" #: ../scripting/abc_codesynt.cpp:3025 msgid "synt deleteproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:3444 msgid "synt divide" msgstr "" #: ../scripting/abc_codesynt.cpp:2404 msgid "synt dup" msgstr "" #: ../scripting/abc_codesynt.cpp:3672 msgid "synt equals" msgstr "" #: ../scripting/abc_codesynt.cpp:2812 msgid "synt findproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:2779 msgid "synt findpropstrict" msgstr "" #: ../scripting/abc_codesynt.cpp:2757 msgid "synt getdescendants" msgstr "" #: ../scripting/abc_codesynt.cpp:2949 msgid "synt getglobalscope" msgstr "" #: ../scripting/abc_codesynt.cpp:2824 msgid "synt getlex" msgstr "" #: ../scripting/abc_codesynt.cpp:2882 msgid "synt getlocal" msgstr "" #: ../scripting/abc_codesynt.cpp:3833 msgid "synt getlocal_n " msgstr "" #: ../scripting/abc_codesynt.cpp:2968 msgid "synt getproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:2957 msgid "synt getscopeobject" msgstr "" #: ../scripting/abc_codesynt.cpp:3036 msgid "synt getslot" msgstr "" #: ../scripting/abc_codesynt.cpp:1630 msgid "synt getsuper" msgstr "" #: ../scripting/abc_codesynt.cpp:3738 msgid "synt greaterequals" msgstr "" #: ../scripting/abc_codesynt.cpp:3725 msgid "synt greaterthan" msgstr "" #: ../scripting/abc_codesynt.cpp:2497 msgid "synt hasnext2" msgstr "" #: ../scripting/abc_codesynt.cpp:1908 msgid "synt ifeq" msgstr "" #: ../scripting/abc_codesynt.cpp:1876 msgid "synt iffalse " msgstr "" #: ../scripting/abc_codesynt.cpp:2127 msgid "synt ifge" msgstr "" #: ../scripting/abc_codesynt.cpp:2093 msgid "synt ifgt" msgstr "" #: ../scripting/abc_codesynt.cpp:2055 msgid "synt ifle" msgstr "" #: ../scripting/abc_codesynt.cpp:2015 msgid "synt iflt " msgstr "" #: ../scripting/abc_codesynt.cpp:1965 msgid "synt ifne " msgstr "" #: ../scripting/abc_codesynt.cpp:1784 msgid "synt ifnge" msgstr "" #: ../scripting/abc_codesynt.cpp:1751 msgid "synt ifngt" msgstr "" #: ../scripting/abc_codesynt.cpp:1719 msgid "synt ifnle" msgstr "" #: ../scripting/abc_codesynt.cpp:1680 msgid "synt ifnlt" msgstr "" #: ../scripting/abc_codesynt.cpp:2161 msgid "synt ifstricteq" msgstr "" #: ../scripting/abc_codesynt.cpp:2193 msgid "synt ifstrictne" msgstr "" #: ../scripting/abc_codesynt.cpp:1837 msgid "synt iftrue" msgstr "" #: ../scripting/abc_codesynt.cpp:3762 msgid "synt in" msgstr "" #: ../scripting/abc_codesynt.cpp:3808 msgid "synt inclocal_i" msgstr "" #: ../scripting/abc_codesynt.cpp:3205 msgid "synt increment" msgstr "" #: ../scripting/abc_codesynt.cpp:3774 msgid "synt increment_i" msgstr "" #: ../scripting/abc_codesynt.cpp:3014 msgid "synt initproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:3751 msgid "synt istypelate" msgstr "" #: ../scripting/abc_codesynt.cpp:1821 msgid "synt jump " msgstr "" #: ../scripting/abc_codesynt.cpp:1654 msgid "synt kill " msgstr "" #: ../scripting/abc_codesynt.cpp:1672 msgid "synt label" msgstr "" #: ../scripting/abc_codesynt.cpp:3712 msgid "synt lessequals" msgstr "" #: ../scripting/abc_codesynt.cpp:3699 msgid "synt lessthan" msgstr "" #: ../scripting/abc_codesynt.cpp:774 ../scripting/abc_codesynt.cpp:2236 msgid "synt lookupswitch" msgstr "" #: ../scripting/abc_codesynt.cpp:3514 msgid "synt lshift" msgstr "" #: ../scripting/abc_codesynt.cpp:3474 msgid "synt modulo" msgstr "" #: ../scripting/abc_codesynt.cpp:3401 msgid "synt multiply" msgstr "" #: ../scripting/abc_codesynt.cpp:3195 msgid "synt negate" msgstr "" #: ../scripting/abc_codesynt.cpp:2738 msgid "synt newactivation" msgstr "" #: ../scripting/abc_codesynt.cpp:2727 msgid "synt newarray" msgstr "" #: ../scripting/abc_codesynt.cpp:2768 msgid "synt newcatch" msgstr "" #: ../scripting/abc_codesynt.cpp:2746 msgid "synt newclass" msgstr "" #: ../scripting/abc_codesynt.cpp:2531 msgid "synt newfunction" msgstr "" #: ../scripting/abc_codesynt.cpp:2716 msgid "synt newobject" msgstr "" #: ../scripting/abc_codesynt.cpp:2303 msgid "synt nextname" msgstr "" #: ../scripting/abc_codesynt.cpp:2332 msgid "synt nextvalue" msgstr "" #: ../scripting/abc_codesynt.cpp:3256 msgid "synt not" msgstr "" #: ../scripting/abc_codesynt.cpp:2393 msgid "synt pop" msgstr "" #: ../scripting/abc_codesynt.cpp:2295 msgid "synt popscope" msgstr "" #: ../scripting/abc_codesynt.cpp:2345 msgid "synt pushbyte" msgstr "" #: ../scripting/abc_codesynt.cpp:2472 msgid "synt pushdouble" msgstr "" #: ../scripting/abc_codesynt.cpp:2377 msgid "synt pushfalse" msgstr "" #: ../scripting/abc_codesynt.cpp:2440 msgid "synt pushint" msgstr "" #: ../scripting/abc_codesynt.cpp:2385 msgid "synt pushnan" msgstr "" #: ../scripting/abc_codesynt.cpp:2316 msgid "synt pushnull" msgstr "" #: ../scripting/abc_codesynt.cpp:2489 msgid "synt pushscope" msgstr "" #: ../scripting/abc_codesynt.cpp:2357 msgid "synt pushshort" msgstr "" #: ../scripting/abc_codesynt.cpp:2429 msgid "synt pushstring" msgstr "" #: ../scripting/abc_codesynt.cpp:2369 msgid "synt pushtrue" msgstr "" #: ../scripting/abc_codesynt.cpp:2456 msgid "synt pushuint" msgstr "" #: ../scripting/abc_codesynt.cpp:2324 msgid "synt pushundefined" msgstr "" #: ../scripting/abc_codesynt.cpp:2287 msgid "synt pushwith" msgstr "" #: ../scripting/abc_codesynt.cpp:2626 msgid "synt returnvalue" msgstr "" #: ../scripting/abc_codesynt.cpp:2604 msgid "synt returnvoid" msgstr "" #: ../scripting/abc_codesynt.cpp:3538 msgid "synt rshift" msgstr "" #: ../scripting/abc_codesynt.cpp:2928 msgid "synt setlocal " msgstr "" #: ../scripting/abc_codesynt.cpp:3878 msgid "synt setlocal_n " msgstr "" #: ../scripting/abc_codesynt.cpp:2835 msgid "synt setproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:3049 msgid "synt setslot" msgstr "" #: ../scripting/abc_codesynt.cpp:1641 msgid "synt setsuper" msgstr "" #: ../scripting/abc_codesynt.cpp:3689 msgid "synt strictequals" msgstr "" #: ../scripting/abc_codesynt.cpp:3348 msgid "synt subtract" msgstr "" #: ../scripting/abc_codesynt.cpp:2417 msgid "synt swap" msgstr "" #: ../scripting/abc_codesynt.cpp:1605 msgid "synt throw" msgstr "" #: ../scripting/abc_codesynt.cpp:3246 msgid "synt typeof" msgstr "" #: ../scripting/abc_codesynt.cpp:3559 msgid "synt urshift" msgstr "" #: ../scripting/abc_opcodes.cpp:1943 msgid "taken" msgstr "" #: ../scripting/abc_opcodes.cpp:485 ../scripting/abc_opcodes.cpp:496 #: ../scripting/abc_opcodes.cpp:532 ../scripting/abc_opcodes.cpp:545 #: ../scripting/abc_opcodes.cpp:846 ../scripting/abc_opcodes.cpp:1209 #: ../scripting/abc_opcodes.cpp:1221 ../scripting/abc_opcodes.cpp:1232 #: ../scripting/abc_opcodes.cpp:1242 ../scripting/abc_opcodes.cpp:1252 #: ../scripting/abc_opcodes.cpp:1262 ../scripting/abc_opcodes.cpp:1903 msgid "taken)" msgstr "" #: ../scripting/abc_opcodes.cpp:713 msgid "typeOf" msgstr "" #: ../scripting/abc_opcodes.cpp:1113 ../scripting/abc_opcodes.cpp:1122 msgid "urShift " msgstr "" #: ../backends/rendering.cpp:106 msgid "~RenderThread this=" msgstr "" lightspark-0.7.2/i18n/zh_CN.po000066400000000000000000001766261212105246600160310ustar00rootroot00000000000000# Polish translations for lightspark package # Polskie t³umaczenia dla pakietu lightspark. # Copyright (C) 2010 THE lightspark'S COPYRIGHT HOLDER # This file is distributed under the same license as the lightspark package. # , 2010. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2010-08-24 23:48-0500\n" "PO-Revision-Date: 2010-08-20 23:03-0500\n" "Last-Translator: \n" "Language-Team: zh_CN\n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: ../scripting/abc.cpp:925 msgid "\t" msgstr "" #: ../scripting/abc.cpp:913 msgid "\tFinal" msgstr "\t最终" #: ../scripting/abc.cpp:915 msgid "\tInterface" msgstr "\t界面" #: ../scripting/abc.cpp:917 msgid "\tProtectedNS " msgstr "\t已保护" #: ../scripting/abc.cpp:911 msgid "\tSealed" msgstr "\t已封装" #: ../asobject.cpp:704 ../scripting/abc_codesynt.cpp:789 #: ../scripting/abc_codesynt.cpp:2253 ../scripting/abc.cpp:1513 #: ../scripting/abc.cpp:1786 ../scripting/abc_opcodes.cpp:1888 msgid " " msgstr "" #: ../scripting/abc.cpp:1418 ../scripting/abc.cpp:1480 #: ../scripting/abc.cpp:1583 ../scripting/abc.cpp:1622 #: ../scripting/abc.cpp:1662 msgid " #" msgstr " #" #: ../swf.cpp:65 ../swf.cpp:69 msgid " Length " msgstr "长度" #: ../asobject.cpp:82 ../asobject.cpp:165 msgid " and type " msgstr "和类型" #: ../parsing/tags.cpp:52 msgid " at byte " msgstr "于字节" #: ../parsing/tags.cpp:52 ../scripting/actions.cpp:405 msgid " bytes" msgstr "字节" #: ../scripting/actions.cpp:1175 msgid " constants" msgstr "常数" #: ../backends/input.cpp:190 ../backends/input.cpp:266 msgid " events" msgstr "信号" #: ../scripting/abc.cpp:1355 msgid " events missing before exit" msgstr "退出前信号丢失" #: ../parsing/tags.cpp:224 ../parsing/tags.cpp:229 msgid " expected: " msgstr "预期:" #: ../backends/graphics.cpp:132 ../backends/graphics.cpp:174 #: ../backends/graphics.cpp:199 msgid " height=" msgstr "高度=" #: ../scripting/abc.cpp:1576 msgid " id " msgstr "代号" #: ../scripting/flashnet.cpp:726 msgid " in FLV" msgstr "于FLV" #: ../scripting/abc_opcodes.cpp:1774 ../scripting/abc_opcodes.cpp:1837 #: ../scripting/abc_opcodes.cpp:1888 msgid " is " msgstr "是" #: ../scripting/abc.cpp:1137 msgid " is not yet valid" msgstr "暂不支持" #: ../scripting/abc_opcodes.cpp:2277 msgid " is not yet valid (as interface)" msgstr "暂不支持(该界面)" #: ../parsing/tags.cpp:1364 ../parsing/tags.cpp:1531 msgid " name " msgstr "名称" #: ../scripting/abc.cpp:1131 msgid " not found in global" msgstr "未在全局类型中发现" #: ../scripting/abc_opcodes.cpp:667 msgid " not supported in construct" msgstr "在创建中不支持" #: ../swftypes.cpp:1087 msgid " of action data" msgstr "操作数据" #: ../scripting/abc_opcodes.cpp:349 ../scripting/abc_opcodes.cpp:783 msgid " on obj " msgstr "于对象" #: ../scripting/abc_opcodes.cpp:825 msgid " on obj type " msgstr "于对象类型" #: ../scripting/abc_opcodes.cpp:388 msgid " on type " msgstr "于类型" #: ../backends/graphics.cpp:53 msgid " openGL errors" msgstr "openGL错误" #: ../backends/rendering.cpp:285 ../backends/rendering.cpp:760 msgid " renderings" msgstr "绘图" #: ../scripting/abc_codesynt.cpp:1482 msgid " should be intrinsic" msgstr "应该是内含函数" #: ../threading.cpp:74 msgid " times" msgstr "编" #: ../asobject.cpp:185 msgid " to float" msgstr "为浮点数" #: ../asobject.cpp:178 msgid " to int" msgstr "为整数" #: ../scripting/abc.cpp:1729 ../scripting/abc.cpp:1749 #: ../scripting/abc.cpp:1755 msgid " type " msgstr "类型" #: ../scripting/abc.cpp:1576 msgid " type Class name " msgstr "类名" #: ../scripting/abc.cpp:1755 msgid " vindex 0 " msgstr "vindex 0" #: ../threading.cpp:74 msgid " waited " msgstr "已等待" #: ../parsing/tags.cpp:52 ../scripting/actions.cpp:405 msgid " with length " msgstr "长" #: ../parsing/tags.cpp:1325 ../parsing/tags.cpp:1492 msgid " with name " msgstr "名称" #: ../scripting/flashutils.cpp:326 msgid "' not found." msgstr "未发现" #: ../scripting/abc_opcodes.cpp:164 msgid ") " msgstr ")" #: ../parsing/tags.cpp:1815 msgid ", ScriptTimeoutSeconds: " msgstr "" #: ../parsing/tags.cpp:1851 msgid ", password: " msgstr ",口令: " #: ../scripting/abc_opcodes.cpp:1332 ../scripting/abc_opcodes.cpp:1373 msgid ", pushing Undefined" msgstr "" #: ../scripting/abc.cpp:1122 msgid ". Not binding" msgstr "" #: ../parsing/tags.cpp:224 ../parsing/tags.cpp:229 msgid ". Size=" msgstr "。大小=" #: ../swftypes.cpp:667 ../swftypes.cpp:699 ../backends/rendering.cpp:581 msgid "... Aborting" msgstr "…… 放弃" #: ../scripting/abc.cpp:1976 msgid "0 not allowed" msgstr "不接受为0" #: ../scripting/abc_interpreter.cpp:773 ../scripting/abc_interpreter.cpp:1210 msgid ": " msgstr ":" #: ../scripting/abc.cpp:1418 ../scripting/abc.cpp:1444 #: ../scripting/abc.cpp:1449 ../scripting/abc.cpp:1475 #: ../scripting/abc.cpp:1480 ../scripting/abc.cpp:1506 #: ../scripting/abc.cpp:1576 ../scripting/abc.cpp:1583 #: ../scripting/abc.cpp:1617 ../scripting/abc.cpp:1622 #: ../scripting/abc.cpp:1657 ../scripting/abc.cpp:1662 #: ../scripting/abc.cpp:1698 msgid "::" msgstr "" #: ../scripting/abc_opcodes.cpp:1080 ../scripting/abc_opcodes.cpp:1091 msgid "<<" msgstr "" #: ../scripting/abc_opcodes.cpp:1103 ../scripting/abc_opcodes.cpp:1113 #: ../scripting/abc_opcodes.cpp:1122 msgid ">>" msgstr "" #: ../scripting/abc.cpp:78 msgid "ABC Exec " msgstr "ABC执行文件" #: ../scripting/abc.cpp:887 msgid "ABCVm version " msgstr "ABCVm 版本" #: ../scripting/toplevel.cpp:2099 msgid "ASString::charCodeAt not really implemented" msgstr "ASString::charCodeAt 支持并未实现" #: ../scripting/actions.cpp:83 ../scripting/actions.cpp:150 msgid "AVM1 not supported" msgstr "不支持AVM1" #: ../scripting/actions.h:311 msgid "ActionAdd2" msgstr "" #: ../scripting/actions.h:598 msgid "ActionAsciiToChar" msgstr "" #: ../scripting/actions.h:535 msgid "ActionBitAnd" msgstr "" #: ../scripting/actions.h:556 msgid "ActionBitLShift" msgstr "" #: ../scripting/actions.h:542 msgid "ActionBitOr" msgstr "" #: ../scripting/actions.h:563 msgid "ActionBitRShift" msgstr "" #: ../scripting/actions.h:549 msgid "ActionBitXor" msgstr "" #: ../scripting/actions.h:402 msgid "ActionCallFunction" msgstr "" #: ../scripting/actions.h:395 msgid "ActionCallMethod" msgstr "" #: ../scripting/actions.h:528 msgid "ActionCastOp" msgstr "" #: ../scripting/actions.h:409 msgid "ActionCloneSprite" msgstr "" #: ../scripting/actions.cpp:1397 ../scripting/actions.h:263 msgid "ActionConstantPool" msgstr "" #: ../scripting/actions.h:437 msgid "ActionDecrement" msgstr "" #: ../scripting/actions.h:146 msgid "ActionDefineFunction" msgstr "" #: ../scripting/actions.h:184 msgid "ActionDefineFunction2" msgstr "" #: ../scripting/actions.h:353 msgid "ActionDefineLocal" msgstr "" #: ../scripting/actions.h:458 msgid "ActionDelete" msgstr "" #: ../scripting/actions.h:325 msgid "ActionDivide" msgstr "" #: ../scripting/actions.h:479 msgid "ActionEnumerate" msgstr "" #: ../scripting/actions.h:507 msgid "ActionEnumerate2" msgstr "" #: ../scripting/actions.h:612 msgid "ActionEquals2" msgstr "" #: ../scripting/actions.h:430 msgid "ActionExtends" msgstr "" #: ../scripting/actions.h:110 msgid "ActionGetMember" msgstr "" #: ../scripting/actions.h:339 msgid "ActionGetProperty" msgstr "" #: ../scripting/actions.h:486 msgid "ActionGetTime" msgstr "" #: ../scripting/actions.h:252 msgid "ActionGetURL" msgstr "" #: ../scripting/actions.h:241 msgid "ActionGetURL2" msgstr "" #: ../scripting/actions.h:647 msgid "ActionGetVariable" msgstr "" #: ../scripting/actions.cpp:1408 ../scripting/actions.h:283 msgid "ActionGoToLabel" msgstr "" #: ../scripting/actions.h:231 msgid "ActionGotoFrame" msgstr "" #: ../scripting/actions.h:577 msgid "ActionGreater" msgstr "" #: ../scripting/actions.h:221 msgid "ActionIf" msgstr "" #: ../scripting/actions.h:423 msgid "ActionImplementsOp" msgstr "" #: ../scripting/actions.h:570 msgid "ActionIncrement" msgstr "" #: ../scripting/actions.h:465 msgid "ActionInitArray" msgstr "" #: ../scripting/actions.h:444 msgid "ActionInitObject" msgstr "" #: ../scripting/actions.h:493 msgid "ActionInstanceOf" msgstr "" #: ../scripting/actions.h:201 msgid "ActionJump" msgstr "" #: ../scripting/actions.cpp:999 msgid "ActionJump: " msgstr "" #: ../scripting/actions.h:591 msgid "ActionLess2" msgstr "" #: ../scripting/actions.h:318 msgid "ActionModulo" msgstr "" #: ../scripting/actions.h:360 msgid "ActionMultiply" msgstr "" #: ../scripting/actions.h:451 msgid "ActionNewMethod" msgstr "" #: ../scripting/actions.h:304 msgid "ActionNewObject" msgstr "" #: ../scripting/actions.h:388 msgid "ActionNot" msgstr "" #: ../scripting/actions.h:124 msgid "ActionPlay" msgstr "" #: ../scripting/actions.h:374 msgid "ActionPop" msgstr "" #: ../scripting/actions.cpp:1314 msgid "ActionPush" msgstr "" #: ../scripting/actions.h:332 msgid "ActionPushDuplicate" msgstr "" #: ../scripting/actions.h:346 msgid "ActionReturn" msgstr "" #: ../scripting/actions.h:117 msgid "ActionSetMember" msgstr "" #: ../scripting/actions.h:500 msgid "ActionSetProperty" msgstr "" #: ../scripting/actions.h:273 msgid "ActionSetTarget" msgstr "" #: ../scripting/actions.h:633 msgid "ActionSetTarget2" msgstr "" #: ../scripting/actions.h:626 msgid "ActionSetVariable" msgstr "" #: ../scripting/actions.h:131 msgid "ActionStop" msgstr "" #: ../scripting/actions.h:663 msgid "ActionStoreRegister" msgstr "" #: ../scripting/actions.h:605 msgid "ActionStrictEquals" msgstr "" #: ../scripting/actions.h:290 msgid "ActionStringAdd" msgstr "" #: ../scripting/actions.h:619 msgid "ActionStringEquals" msgstr "" #: ../scripting/actions.h:297 msgid "ActionStringExtract" msgstr "" #: ../scripting/actions.h:584 msgid "ActionStringGreater" msgstr "" #: ../scripting/actions.h:367 msgid "ActionSubtract" msgstr "" #: ../scripting/actions.cpp:859 ../scripting/actions.h:381 msgid "ActionToInteger" msgstr "" #: ../scripting/actions.h:521 msgid "ActionToNumber" msgstr "" #: ../scripting/actions.h:514 msgid "ActionToString" msgstr "" #: ../scripting/actions.h:416 msgid "ActionTrace" msgstr "" #: ../scripting/actions.h:472 msgid "ActionTypeOf" msgstr "" #: ../scripting/actions.h:211 msgid "ActionWith" msgstr "" #: ../scripting/abc_opcodes.cpp:1025 msgid "Add between integer and " msgstr "加法对于整数和" #: ../scripting/abc_opcodes.cpp:980 msgid "Add between types " msgstr "加法对于类型" #: ../scripting/abc_opcodes.cpp:1068 msgid "Add between types number and " msgstr "加法对于数和" #: ../asobject.cpp:114 msgid "Add buildTraits for class " msgstr "添加buildTraits到类" #: ../scripting/toplevel.cpp:3046 msgid "Array to bool" msgstr "组到逻辑" #: ../scripting/toplevel.cpp:179 msgid "Array::filter STUB" msgstr "" #: ../scripting/abc_opcodes.cpp:402 ../scripting/abc_opcodes.cpp:1381 msgid "Attaching this to function " msgstr "附加到函数" #: ../backends/decoder.cpp:446 msgid "Audio channels " msgstr "音频声道" #: ../backends/decoder.cpp:438 msgid "Audio sample rate " msgstr "音频采样率" #: ../scripting/abc.cpp:109 msgid "Binding " msgstr "限定" #: ../scripting/abc.cpp:1037 msgid "Binding of " msgstr "限定于" #: ../scripting/toplevel.cpp:3079 msgid "Boolean conversion for type " msgstr "逻辑转换类型" #: ../scripting/toplevel.cpp:3031 msgid "Boolean to bool " msgstr "Boolean到bool" #: ../scripting/abc_opcodes.cpp:2232 msgid "Building class traits" msgstr "创建类属性" #: ../scripting/abc.cpp:1286 msgid "Building entry script traits: " msgstr "创建入口脚本属性" #: ../scripting/abc.cpp:1067 ../scripting/toplevel.cpp:2725 msgid "Building instance traits" msgstr "创建例程属性" #: ../scripting/abc_opcodes.cpp:641 ../scripting/abc_opcodes.cpp:2002 msgid "Building method traits" msgstr "创建步骤属性" #: ../scripting/abc.cpp:1264 msgid "Building script traits: " msgstr "创建脚本属性:" #: ../scripting/toplevel.cpp:2616 msgid "Building traits for " msgstr "创建属性给" #: ../parsing/tags_stub.cpp:100 msgid "CSMTextSettingsTag" msgstr "" #: ../backends/netutils.cpp:278 msgid "CURL not enabled in this build. Downloader will always fail." msgstr "本编译不含CURL支持,下载器将全部失败。" #: ../scripting/toplevel.cpp:459 msgid "Called ASXML::load " msgstr "完成调用ASXML::load " #: ../scripting/toplevel.cpp:134 msgid "Called Array constructor" msgstr "完成调用Array创建" #: ../scripting/toplevel.cpp:426 msgid "Called MovieClipLoader constructor" msgstr "完成调用MovieClipLoader创建" #: ../scripting/toplevel.cpp:432 msgid "Called MovieClipLoader::addListener" msgstr "完成调用MovieClipLoader::addListener" #: ../scripting/toplevel.cpp:444 msgid "Called XML constructor" msgstr "完成调用XML创建" #: ../scripting/flashdisplay.cpp:524 msgid "Called swapDepths" msgstr "完成调用swapDepths" #: ../scripting/abc_opcodes.cpp:2292 msgid "Calling Class init " msgstr "调用类 初始化" #: ../scripting/toplevel.cpp:2660 msgid "Calling Instance init " msgstr "调用类体初始化" #: ../scripting/abc_opcodes.cpp:1710 msgid "Calling an undefined function" msgstr "调用未定义函数" #: ../scripting/abc_opcodes.cpp:349 ../scripting/abc_opcodes.cpp:783 #: ../scripting/abc_opcodes.cpp:1635 msgid "Calling an undefined function " msgstr "调用未定义函数" #: ../scripting/toplevel.cpp:2818 msgid "Calling interface init for " msgstr "调用界面初始化for " #: ../asobject.cpp:596 ../asobject.cpp:639 ../asobject.cpp:864 msgid "Calling the getter" msgstr "调用获取器" #: ../asobject.cpp:592 msgid "Calling the getter on type " msgstr "调用the getter on type " #: ../asobject.cpp:352 ../asobject.cpp:385 msgid "Calling the setter" msgstr "调用设置器" #: ../scripting/toplevel.cpp:1674 ../scripting/toplevel.cpp:1760 msgid "Calling with closure " msgstr "调用with closure " #: ../asobject.cpp:178 ../asobject.cpp:185 msgid "Cannot convert object of type " msgstr "不能转换对象类型" #: ../plugin/plugin.cpp:351 msgid "Cannot handle UTF8 URLs" msgstr "不能处理UTF-8链接" #: ../scripting/abc_opcodes.cpp:586 msgid "Cannot increment type " msgstr "不能递增类型" #: ../backends/rendering.cpp:514 #, fuzzy msgid "Cannot initialize GLEW: cause " msgstr "不能初始化GLEW" #: ../scripting/abc_opcodes.cpp:1726 msgid "Cannot retrieve type" msgstr "不能找到类型" #: ../scripting/abc_codesynt.cpp:789 ../scripting/abc_codesynt.cpp:2253 msgid "Case " msgstr "大小字母" #: ../scripting/abc_opcodes.cpp:691 msgid "Check" msgstr "检查" #: ../swf.cpp:528 msgid "Child process creation failed, lightspark continues" msgstr "创建子进程失败,lightspark继续运行" #: ../scripting/abc.cpp:908 ../scripting/abc.cpp:1131 #: ../scripting/abc.cpp:1137 ../scripting/abc_opcodes.cpp:2277 msgid "Class " msgstr "类" #: ../scripting/abc.cpp:1576 msgid "Class slot " msgstr "类slot " #: ../scripting/toplevel.cpp:3041 msgid "Class to bool" msgstr "类到bool" #: ../scripting/actions.cpp:461 msgid "CodeSize not consistent" msgstr "CodeSize不一致" #: ../scripting/actions.cpp:578 msgid "CodeSize not consistent with file offset " msgstr "CodeSize和文件便宜不一致" #: ../swf.cpp:69 msgid "Compressed SWF file: Version " msgstr "压缩SWF文件:版本" #: ../backends/sound.cpp:258 msgid "Connection to PulseAudio server failed" msgstr "连接到PulseAudio服务器失败" #: ../scripting/abc.cpp:1729 msgid "Const " msgstr "" #: ../scripting/abc.cpp:1542 msgid "Constant kind " msgstr "" #: ../scripting/actions.cpp:1175 msgid "ConstantPool: Reading " msgstr "ConstantPool:读取" #: ../scripting/abc_opcodes.cpp:610 ../scripting/abc_opcodes.cpp:700 #: ../scripting/abc_opcodes.cpp:1985 msgid "Constructing" msgstr "创建" #: ../scripting/abc.cpp:66 msgid "Corrupted ABC data: missing " msgstr "损坏的ABC数据:缺失" #: ../backends/rendering.cpp:203 msgid "Could not find any GLX configuration" msgstr "不能找到GLX配置" #: ../swf.cpp:607 msgid "Creating VM" msgstr "创建VM" #: ../scripting/toplevel.cpp:129 msgid "Creating array of length " msgstr "创建组长度为" #: ../backends/input.cpp:39 msgid "Creating input thread" msgstr "创建输入线程" #: ../scripting/abc_opcodes.cpp:1413 msgid "Cur prototype name " msgstr "Cur原型名称" #: ../parsing/tags.cpp:1820 msgid "DebugIDTag Tag" msgstr "DebugIDTag标识" #: ../parsing/tags.cpp:1825 msgid "DebugId " msgstr "" #: ../parsing/tags.cpp:1840 msgid "Debugger enabled, password: " msgstr "启用调试器,密码:" #: ../parsing/tags.cpp:1851 msgid "Debugger enabled, reserved: " msgstr "启用调试器,保留:" #: ../scripting/abc_opcodes.cpp:1387 ../scripting/abc_opcodes.cpp:1978 msgid "Deferred definition of property " msgstr "延迟定义属性" #: ../parsing/tags.cpp:1757 msgid "DefineBinaryDataTag" msgstr "" #: ../parsing/tags_stub.cpp:76 msgid "DefineBitsJPEG2Tag Tag" msgstr "DefineBitsJPEG2Tag标识" #: ../parsing/tags.cpp:670 msgid "DefineBitsLossless2Tag::Render" msgstr "" #: ../parsing/tags.cpp:1672 msgid "DefineButton2Tag::Render" msgstr "" #: ../parsing/tags.cpp:266 msgid "DefineEditTextTag ID " msgstr "" #: ../parsing/tags.cpp:307 msgid "DefineEditTextTag: Render" msgstr "" #: ../parsing/tags.cpp:440 msgid "DefineFont" msgstr "" #: ../parsing/tags.cpp:465 msgid "DefineFont2" msgstr "" #: ../parsing/tags.cpp:554 msgid "DefineFont3" msgstr "" #: ../parsing/tags_stub.cpp:70 msgid "DefineFontAlignZonesTag Tag" msgstr "DefineFontAlignZonesTag标识" #: ../parsing/tags_stub.cpp:40 msgid "DefineFontInfo Tag" msgstr "DefineFontInfo标识" #: ../parsing/tags_stub.cpp:64 msgid "DefineFontNameTag Tag" msgstr "DefineFontNameTag标识" #: ../parsing/tags_stub.cpp:83 msgid "DefineScalingGridTag Tag on ID " msgstr "DefineScalingGridTag标识于ID " #: ../parsing/tags_stub.cpp:94 msgid "DefineSceneAndFrameLabelDataTag" msgstr "" #: ../parsing/tags.cpp:867 msgid "DefineShape2Tag" msgstr "" #: ../parsing/tags.cpp:874 msgid "DefineShape3Tag" msgstr "" #: ../parsing/tags.cpp:881 msgid "DefineShape4Tag" msgstr "" #: ../parsing/tags.cpp:860 msgid "DefineShapeTag" msgstr "" #: ../parsing/tags.cpp:1785 msgid "DefineSound Tag" msgstr "DefineSound标识" #: ../parsing/tags.cpp:343 msgid "DefineSprite ID: " msgstr "" #: ../parsing/tags.cpp:676 msgid "DefineText ID " msgstr "" #: ../parsing/tags.cpp:750 msgid "DefineText Render" msgstr "" #: ../parsing/tags.cpp:1730 msgid "DefineVideoStreamTag" msgstr "" #: ../parsing/tags.cpp:1741 msgid "DefineVideoStreamTag Render" msgstr "DefineVideoStreamTag绘图器" #: ../scripting/actions.cpp:433 msgid "Defining function " msgstr "定义函数" #: ../scripting/actions.cpp:538 msgid "Defining function2 " msgstr "定义函数2" #: ../scripting/flashutils.cpp:326 msgid "Definition for '" msgstr "定义" #: ../plugin/plugin.cpp:436 msgid "DestroyStream on main stream?" msgstr "DestroyStream于主流" #: ../scripting/abc.cpp:59 msgid "DoABCTag Name: " msgstr "DoABCTag名称: " #: ../scripting/actions.cpp:54 msgid "DoActionTag" msgstr "" #: ../scripting/actions.cpp:121 msgid "DoInitActionTag" msgstr "" #: ../backends/netutils.cpp:123 msgid "Downloaded file bigger than buffer: " msgstr "下载文件大过缓冲:" #: ../scripting/abc.cpp:1206 msgid "Empty stack" msgstr "空栈" #: ../parsing/tags.cpp:1845 msgid "EnableDebugger2Tag Tag" msgstr "EnableDebugger2Tag标识" #: ../parsing/tags.cpp:1836 msgid "EnableDebuggerTag Tag" msgstr "EnableDebuggerTag标识" #: ../scripting/abc.cpp:1475 ../scripting/abc.cpp:1617 msgid "End Getter trait: " msgstr "尾Getter 属性: " #: ../scripting/abc.cpp:1444 ../scripting/abc.cpp:1698 msgid "End Method trait: " msgstr "尾Method 属性: " #: ../scripting/abc.cpp:1506 ../scripting/abc.cpp:1657 msgid "End Setter trait: " msgstr "尾Setter 属性: " #: ../scripting/actions.cpp:447 ../scripting/actions.cpp:563 msgid "End action in function" msgstr "尾函数动作" #: ../scripting/abc_opcodes.cpp:2297 msgid "End of Class init " msgstr "结束类 初始化" #: ../scripting/abc.cpp:1299 msgid "End of Entry Point" msgstr "结束Entry Point" #: ../scripting/abc.cpp:1039 msgid "End of binding of " msgstr "结束固定化" #: ../scripting/abc_opcodes.cpp:2378 msgid "End of call " msgstr "结束调用" #: ../scripting/abc_opcodes.cpp:1638 msgid "End of callSuper " msgstr "结束callSuper " #: ../scripting/abc_opcodes.cpp:1712 msgid "End of callSuperVoid " msgstr "结束callSuperVoid " #: ../scripting/abc_opcodes.cpp:343 ../scripting/abc_opcodes.cpp:353 #: ../scripting/abc_opcodes.cpp:817 ../scripting/abc_opcodes.cpp:835 msgid "End of calling " msgstr "结束调用" #: ../scripting/abc_opcodes.cpp:706 msgid "End of constructing" msgstr "结束创建" #: ../scripting/abc_opcodes.cpp:674 ../scripting/abc_opcodes.cpp:2030 msgid "End of constructing " msgstr "结束创建" #: ../scripting/abc_opcodes.cpp:1391 ../scripting/abc_opcodes.cpp:1982 msgid "End of deferred definition of property " msgstr "结束延迟定义属性" #: ../scripting/abc.cpp:1140 ../scripting/abc_opcodes.cpp:2280 msgid "End of deferred init of class " msgstr "结束延迟初始化类" #: ../asobject.cpp:603 ../asobject.cpp:643 ../asobject.cpp:869 msgid "End of getter" msgstr "结束获取器" #: ../swf.cpp:828 msgid "End of parsing @ " msgstr "结束解释@ " #: ../asobject.cpp:363 ../asobject.cpp:392 msgid "End of setter" msgstr "结束设置器" #: ../scripting/abc_opcodes.cpp:1420 msgid "End super construct " msgstr "尾super construct " #: ../parsing/tags.cpp:392 msgid "EndDefineSprite ID: " msgstr "" #: ../parsing/tags.cpp:56 msgid "EndTag at position " msgstr "EndTag于位置" #: ../asobject.cpp:165 msgid "Equal comparison between type " msgstr "Equal comparison于类型" #: ../scripting/abc.cpp:1369 msgid "Error in VM " msgstr "VM 错误" #: ../parsing/tags.cpp:224 ../parsing/tags.cpp:229 msgid "Error while reading tag " msgstr "读取标识错误" #: ../scripting/toplevel.cpp:2266 msgid "Error.getStackTrace not yet implemented." msgstr "Error.getStackTrace尚未实现" #: ../scripting/flashevents.cpp:323 msgid "Event not found" msgstr "" #: ../swf.cpp:870 msgid "Exception in ParseThread " msgstr "ParseThread 异常" #: ../backends/rendering.cpp:402 ../backends/rendering.cpp:894 msgid "Exception in RenderThread " msgstr "RenderThread 异常" #: ../swf.cpp:1102 msgid "Exception in RootMovieClip::tick " msgstr "RootMovieClip::tick 异常" #: ../thread_pool.cpp:108 msgid "Exception in ThreadPool " msgstr "ThreadPool 异常" #: ../scripting/flashnet.cpp:766 msgid "Exception in reading: " msgstr "reading: 异常" #: ../scripting/actions.cpp:701 msgid "Exec: ActionBitAnd" msgstr "" #: ../scripting/actions.cpp:716 msgid "Exec: ActionBitLShift" msgstr "" #: ../scripting/actions.cpp:706 msgid "Exec: ActionBitOr" msgstr "" #: ../scripting/actions.cpp:721 msgid "Exec: ActionBitRShift" msgstr "" #: ../scripting/actions.cpp:711 msgid "Exec: ActionBitXor" msgstr "" #: ../scripting/actions.cpp:741 msgid "Exec: ActionCastOp" msgstr "" #: ../scripting/actions.cpp:797 msgid "Exec: ActionCloneSprite" msgstr "" #: ../scripting/actions.cpp:654 msgid "Exec: ActionDecrement" msgstr "" #: ../scripting/actions.cpp:1005 msgid "Exec: ActionDelete" msgstr "" #: ../scripting/actions.cpp:681 msgid "Exec: ActionEnumerate" msgstr "" #: ../scripting/actions.cpp:726 msgid "Exec: ActionEnumerate2" msgstr "" #: ../scripting/actions.cpp:686 msgid "Exec: ActionGetTime" msgstr "" #: ../scripting/actions.cpp:696 msgid "Exec: ActionImplementsOp" msgstr "" #: ../scripting/actions.cpp:1086 msgid "Exec: ActionInitArray" msgstr "" #: ../scripting/actions.cpp:1091 msgid "Exec: ActionInitObject" msgstr "" #: ../scripting/actions.cpp:691 msgid "Exec: ActionInstanceOf" msgstr "" #: ../scripting/actions.cpp:1010 msgid "Exec: ActionNewMethod" msgstr "" #: ../scripting/actions.cpp:586 msgid "Exec: ActionPushDuplicate" msgstr "" #: ../scripting/actions.cpp:1015 ../scripting/actions.cpp:1020 msgid "Exec: ActionStringAdd" msgstr "" #: ../scripting/actions.cpp:1096 msgid "Exec: ActionStringEquals" msgstr "" #: ../scripting/actions.cpp:1025 msgid "Exec: ActionStringExtract" msgstr "" #: ../scripting/actions.cpp:772 msgid "Exec: ActionStringGreater" msgstr "" #: ../scripting/actions.cpp:736 msgid "Exec: ActionToNumber" msgstr "" #: ../scripting/actions.cpp:731 msgid "Exec: ActionToString" msgstr "" #: ../scripting/actions.cpp:1147 msgid "Exec: ActionToggleQuality" msgstr "" #: ../scripting/actions.cpp:802 msgid "Exec: ActionTrace" msgstr "" #: ../scripting/actions.cpp:676 msgid "Exec: ActionTypeOf" msgstr "" #: ../scripting/actions.cpp:1319 msgid "Exec: ActionWith" msgstr "" #: ../swf.cpp:561 msgid "Execve failed, content will not be rendered" msgstr "execve错误,不会显示内容" #: ../scripting/actions.cpp:37 msgid "ExportAssetsTag Tag" msgstr "ExportAssetsTag标识" #: ../parsing/flv.cpp:38 msgid "FLV file: Version " msgstr "FLV文件:版本" #: ../backends/rendering.cpp:909 msgid "FPS: " msgstr "" #: ../scripting/toplevel.cpp:2680 msgid "Failure in reference counting" msgstr "引用错误计数" #: ../backends/rendering.cpp:285 ../backends/rendering.cpp:760 msgid "Faking " msgstr "伪" #: ../backends/rendering.cpp:199 msgid "Falling back to no double buffering" msgstr "回归到不用双缓冲" #: ../parsing/tags.cpp:168 msgid "FileAttributes tag not in the beginning" msgstr "FileAttributes标识不在起始" #: ../parsing/tags.cpp:1768 msgid "FileAttributesTag Tag" msgstr "FileAttributesTag标识" #: ../swftypes.cpp:288 ../swftypes.cpp:304 msgid "Fill array extended not supported" msgstr "不支持填充扩展组" #: ../swftypes.h:603 msgid "Fixed point bit field wider than 32 bit not supported" msgstr "不支持固定位域超过32位" #: ../scripting/abc.cpp:909 msgid "Flags:" msgstr "指示:" #: ../backends/rendering.cpp:85 msgid "Font File is " msgstr "字体文件为" #: ../scripting/flashsystem.cpp:105 msgid "Found definition for " msgstr "发现的定义" #: ../backends/rendering.cpp:442 msgid "Fragment shader compilation " msgstr "碎片着色器编译" #: ../swf.cpp:809 msgid "FrameRate " msgstr "帧速" #: ../scripting/abc_opcodes.cpp:2375 msgid "Function not good " msgstr "函数不良" #: ../scripting/abc.cpp:2199 #, fuzzy msgid "Function not implemented" msgstr "函数不良" #: ../backends/graphics.cpp:45 msgid "GL error " msgstr "GL错误" #: ../backends/rendering.cpp:584 msgid "GL errors during initialization: " msgstr "GL初始化错误:" #: ../backends/graphics.cpp:132 ../backends/graphics.cpp:174 #: ../backends/graphics.cpp:199 msgid "GL_INVALID_VALUE after glTexImage2D, width=" msgstr "GL_INVALID_VALUE在glTexImage2D后, 宽度=" #: ../scripting/actions.cpp:1367 msgid "GetURL2" msgstr "" #: ../scripting/actions.cpp:1378 msgid "GetURL2: exec" msgstr "" #: ../scripting/actions.cpp:1373 msgid "GetURL: exec" msgstr "" #: ../scripting/abc.cpp:1472 msgid "Getter not linkable" msgstr "" #: ../scripting/abc.cpp:1449 ../scripting/abc.cpp:1583 msgid "Getter trait: " msgstr "" #: ../scripting/flashsystem.cpp:138 ../scripting/flashutils.cpp:341 msgid "Getting definition for " msgstr "获取定义给" #: ../scripting/abc.cpp:961 msgid "Global is " msgstr "" #: ../scripting/flashevents.cpp:372 msgid "Handling event " msgstr "" #: ../backends/graphics.cpp:53 msgid "Ignoring " msgstr "忽略" #: ../scripting/abc_codesynt.cpp:685 ../scripting/abc_codesynt.cpp:1596 msgid "Ignoring at " msgstr "忽略" #: ../scripting/abc.cpp:922 msgid "Implements" msgstr "实现" #: ../backends/rendering.cpp:581 msgid "Incomplete FBO status " msgstr "不完全FBO status " #: ../parsing/tags.cpp:388 msgid "Inconsistent frame count " msgstr "不一致frame count " #: ../scripting/toplevel.cpp:3070 msgid "Integer to bool" msgstr "Integer到bool" #: ../swf.cpp:511 msgid "Invoking gnash!" msgstr "调用gnash" #: ../threading.cpp:51 msgid "Job terminated" msgstr "任务终止" #: ../scripting/toplevel.cpp:1779 msgid "LOG10E" msgstr "" #: ../scripting/toplevel.cpp:1780 msgid "LOG2E" msgstr "" #: ../scripting/abc_codesynt.cpp:1569 msgid "Last instruction before a new block was not a branch." msgstr "新块前最后指令不是分支" #: ../scripting/abc.cpp:1277 msgid "Last script (Entry Point)" msgstr "最后脚本(入口)" #: ../asobject.cpp:82 msgid "Less than comparison between type " msgstr "比较是否小于,类型" #: ../swftypes.cpp:238 ../swftypes.cpp:265 msgid "Line array extended not supported" msgstr "不支持扩展行组" #: ../scripting/abc_opcodes.cpp:2193 msgid "Linking with interface " msgstr "链接界面" #: ../scripting/flashdisplay.cpp:196 msgid "Loader async execution " msgstr "异步执行加载器" #: ../backends/netutils.cpp:394 msgid "LocalDownloader::execute: could not open local file: " msgstr "LocalDownloader::execute: 不能打开本地文件:" #: ../backends/netutils.cpp:386 msgid "LocalDownloader::execute: reading from local file failed: " msgstr "LocalDownloader::execute: 读取本地文件失败:" #: ../backends/netutils.cpp:359 msgid "LocalDownloader::execute: reading local file: " msgstr "LocalDownloader::execute: 读取本地文件:" #: ../scripting/flashsystem.cpp:86 ../scripting/flashsystem.cpp:121 #: ../scripting/flashutils.cpp:319 msgid "Looking for definition of " msgstr "查找定义" #: ../parsing/tags.cpp:1815 msgid "MaxRecusionDepth: " msgstr "" #: ../parsing/tags.cpp:1858 msgid "MetaData: " msgstr "" #: ../parsing/tags.cpp:1856 msgid "MetadataTag Tag" msgstr "MetadataTag标识" #: ../scripting/abc_codesynt.cpp:1482 msgid "Method " msgstr "方法" #: ../scripting/abc.cpp:1441 msgid "Method not linkable" msgstr "不可链接方法" #: ../scripting/abc.cpp:1418 ../scripting/abc.cpp:1662 msgid "Method trait: " msgstr "方法属性" #: ../parsing/tags.cpp:1333 ../parsing/tags.cpp:1500 msgid "Moving of registered objects not really supported" msgstr "并不支持移动注册对象" #: ../scripting/abc.cpp:1933 msgid "Multibyte not handled" msgstr "Multibyte未能处理" #: ../scripting/abc.cpp:339 ../scripting/abc.cpp:356 ../scripting/abc.cpp:488 #: ../scripting/abc.cpp:584 ../scripting/abc.cpp:619 ../scripting/abc.cpp:636 #: ../scripting/abc.cpp:782 msgid "Multiname to String not yet implemented for this kind " msgstr "本类中Multiname到String并未实现" #: ../scripting/abc.cpp:1122 msgid "Multiple binding on " msgstr "多次固定于" #: ../threading.cpp:74 msgid "Mutex " msgstr "" #: ../scripting/abc_opcodes.cpp:1332 ../scripting/abc_opcodes.cpp:1373 msgid "NOT found " msgstr "未发现 " #: ../scripting/abc_opcodes.cpp:1498 msgid "NOT found, pushing Undefined" msgstr "未发现, 压入未定义" #: ../scripting/abc_opcodes.cpp:1455 msgid "NOT found, pushing global" msgstr "未发现, 压入global" #: ../scripting/abc_opcodes.cpp:1369 ../scripting/abc_opcodes.cpp:1491 msgid "NOT found, trying Global" msgstr "未发现, 尝试Global" #: ../scripting/flashnet.cpp:439 #, fuzzy msgid "NetStream constructor" msgstr "完成调用Array创建" #: ../scripting/flashnet.cpp:516 msgid "NetStream::close called" msgstr "NetStream::close调用" #: ../scripting/abc_codesynt.cpp:676 ../scripting/abc_codesynt.cpp:731 msgid "New block at " msgstr "新块于" #: ../plugin/plugin.cpp:365 msgid "Newstream for " msgstr "Newstream给" #: ../scripting/abc.cpp:1412 ../scripting/abc.cpp:1558 msgid "Next slot has flags " msgstr "下一条具有标记" #: ../parsing/flv.cpp:43 msgid "No FLV file signature found" msgstr "没有FLV文件名" #: ../swf.cpp:73 msgid "No SWF file signature found" msgstr "没有SWF文件标识" #: ../backends/geometry.cpp:46 msgid "No edges in this shape" msgstr "该形状无边界" #: ../main.cpp:196 ../tightspark.cpp:94 msgid "No execution model enabled" msgstr "没有允许任何执行模式" #: ../plugin/plugin.cpp:266 msgid "No size in SetWindow" msgstr "SetWindow不含大小" #: ../swf.cpp:1063 msgid "No such Id on dictionary " msgstr "字典中不含该Id" #: ../backends/rendering.cpp:217 msgid "No suitable graphics configuration available" msgstr "没有合适图形配置可用" #: ../backends/rendering.cpp:573 msgid "Non enough color attachments available, input disabled" msgstr "没有足够的颜色附件可用,禁止输入" #: ../scripting/flashdisplay.cpp:492 msgid "Not a function" msgstr "不是函数" #: ../scripting/flashdisplay.cpp:601 msgid "Not enough frames loaded" msgstr "没有导入足够多帧" #: ../scripting/flashevents.cpp:368 msgid "Not handled event " msgstr "未处理事件" #: ../scripting/actions.h:640 msgid "Not implemented action" msgstr "未实现动作" #: ../scripting/abc_codesynt.cpp:1356 ../scripting/abc_codesynt.cpp:3928 msgid "Not implemented instruction @" msgstr "尚未实现指令@" #: ../scripting/flashevents.cpp:281 msgid "Not implemented mode for addEventListener" msgstr "addEventListener有未实现的模式" #: ../scripting/abc_interpreter.cpp:1261 msgid "Not intepreted instruction @" msgstr "未解释指令@" #: ../scripting/actions.cpp:68 ../scripting/actions.cpp:135 #: ../scripting/actions.cpp:453 ../scripting/actions.cpp:569 msgid "Not supported action opcode" msgstr "不支持动作opcode" #: ../swftypes.cpp:667 ../swftypes.cpp:699 msgid "Not supported fill style " msgstr "不支持填充方式" #: ../scripting/toplevel.cpp:3056 msgid "Null to bool" msgstr "Null到bool" #: ../scripting/toplevel.cpp:3061 msgid "Number to bool" msgstr "Number到bool" #: ../scripting/abc_opcodes.cpp:1740 ../scripting/abc_opcodes.cpp:1794 #: ../scripting/abc_opcodes.cpp:1855 msgid "Numeric type is " msgstr "数值类型为" #: ../scripting/abc_opcodes.cpp:303 msgid "Object" msgstr "对象" #: ../scripting/toplevel.cpp:3036 msgid "Object to bool" msgstr "对象到bool" #: ../scripting/abc_opcodes.cpp:667 msgid "Object type " msgstr "对象类型" #: ../asobject.cpp:139 ../asobject.cpp:161 msgid "Overloaded isEqual" msgstr "重载isEqual" #: ../asobject.cpp:78 msgid "Overloaded isLess" msgstr "重载isLess" #: ../swf.cpp:266 msgid "Parameters file not found" msgstr "未发现参数文件" #: ../asobject.cpp:503 msgid "Passthorugh of " msgstr "传递" #: ../parsing/tags.cpp:1373 msgid "PlaceObject2" msgstr "" #: ../parsing/tags.cpp:1540 msgid "PlaceObject3" msgstr "" #: ../parsing/tags.cpp:1271 ../parsing/tags.cpp:1438 msgid "Placing ID " msgstr "" #: ../parsing/tags.cpp:1602 msgid "ProductInfoTag Tag" msgstr "ProductInfoTag标识" #: ../scripting/abc_opcodes.cpp:388 ../scripting/abc_opcodes.cpp:392 msgid "Property not found " msgstr "未发现属性" #: ../parsing/tags_stub.cpp:34 msgid "Protect Tag" msgstr "Protect标识" #: ../scripting/abc_opcodes.cpp:338 ../scripting/abc_opcodes.cpp:811 msgid "Proxy::callProperty" msgstr "" #: ../scripting/flashutils.cpp:628 msgid "Proxy::getProperty" msgstr "" #: ../scripting/flashutils.cpp:638 msgid "Proxy::hasNext" msgstr "" #: ../scripting/flashutils.cpp:656 msgid "Proxy::nextName" msgstr "" #: ../scripting/flashutils.cpp:601 msgid "Proxy::setProperty" msgstr "" #: ../scripting/actions.cpp:1304 msgid "Push type: " msgstr "" #: ../scripting/actions.cpp:1262 #, fuzzy msgid "Push: Read bool " msgstr "Push: 读取bool " #: ../scripting/actions.cpp:1290 #, fuzzy msgid "Push: Read constant index " msgstr "Push: 读取constant index " #: ../scripting/actions.cpp:1271 #, fuzzy msgid "Push: Read double " msgstr "Push: 读取double " #: ../scripting/actions.cpp:1231 #, fuzzy msgid "Push: Read float " msgstr "Push: 读取float " #: ../scripting/actions.cpp:1280 #, fuzzy msgid "Push: Read integer " msgstr "Push: 读取integer " #: ../scripting/actions.cpp:1300 #, fuzzy msgid "Push: Read long constant index " msgstr "Push: 读取long constant index " #: ../scripting/actions.cpp:1253 #, fuzzy msgid "Push: Read reg number " msgstr "Push: 读取reg number " #: ../scripting/actions.cpp:1222 #, fuzzy msgid "Push: Read string " msgstr "Push: 读取string " #: ../scripting/actions.cpp:1237 msgid "Push: null" msgstr "" #: ../scripting/actions.cpp:1243 msgid "Push: undefined" msgstr "" #: ../parsing/tags.cpp:52 msgid "Reading tag type: " msgstr "读入标识类型:" #: ../backends/graphics.cpp:192 msgid "Reallocating texture to size " msgstr "重新分配图形大小" #: ../parsing/tags.cpp:1325 ../parsing/tags.cpp:1492 msgid "Registering ID " msgstr "组测ID" #: ../parsing/tags.cpp:239 msgid "RemoveObject2 Depth: " msgstr "RemoveObject2深度:" #: ../backends/rendering.cpp:57 msgid "RenderThread this=" msgstr "" #: ../scripting/abc.cpp:1177 msgid "Requested invalid method" msgstr "请求无效方法" #: ../swftypes.cpp:395 msgid "Reserved bits not so reserved" msgstr "保留未恰当保留位" #: ../swftypes.cpp:538 msgid "Reverting to fixed function" msgstr "恢复固定函数" #: ../main.cpp:218 msgid "Running in local-with-filesystem sandbox" msgstr "本地文件系统的沙盘中运行" #: ../main.cpp:214 msgid "Running in remote sandbox" msgstr "远程沙盘中运行" #: ../parsing/tags.cpp:1611 msgid "SWF Info:" msgstr "SWF信息:" #: ../scripting/abc.cpp:1256 msgid "Script N: " msgstr "脚本N:" #: ../parsing/tags.cpp:1813 msgid "ScriptLimitsTag Tag" msgstr "ScriptLimitsTag标识" #: ../scripting/flashsystem.cpp:199 msgid "Security::allowDomain" msgstr "" #: ../scripting/flashsystem.cpp:205 msgid "Security::allowInsecureDomain" msgstr "" #: ../scripting/flashsystem.cpp:211 msgid "Security::loadPolicyFile" msgstr "" #: ../scripting/flashsystem.cpp:217 msgid "Security::showSettings" msgstr "" #: ../scripting/abc.cpp:1503 msgid "Setter not linkable" msgstr "不可链接的设置器" #: ../scripting/abc.cpp:1480 ../scripting/abc.cpp:1622 msgid "Setter trait: " msgstr "" #: ../scripting/abc.cpp:1126 msgid "Setting class name to " msgstr "设置类名为" #: ../backends/rendering.cpp:428 #, fuzzy msgid "Shader lightspark.frag not found" msgstr "未发现lightspark.frag着色器" #: ../backends/rendering.cpp:465 #, fuzzy msgid "Shader lightspark.vert not found" msgstr "未发现lightspark.vert着色器" #: ../parsing/tags.cpp:768 msgid "Should be a FontTag" msgstr "应当为FontTag" #: ../parsing/tags.cpp:1224 msgid "ShowFrame" msgstr "显示框" #: ../swftypes.h:665 msgid "Signed bit field wider than 32 bit not supported" msgstr "不支持有符合位域超过32位" #: ../swftypes.cpp:1087 msgid "Skipping " msgstr "跳过" #: ../scripting/abc.cpp:1749 ../scripting/abc.cpp:1755 msgid "Slot " msgstr "条" #: ../parsing/tags_stub.cpp:88 msgid "SoundStreamBlockTag" msgstr "" #: ../parsing/tags_stub.cpp:52 msgid "SoundStreamHead Tag" msgstr "SoundStreamHead标识" #: ../parsing/tags_stub.cpp:58 msgid "SoundStreamHead2 Tag" msgstr "SoundStreamHead2标识" #: ../scripting/flashmedia.cpp:45 #, fuzzy msgid "SoundTransform constructor" msgstr "SoundTransform创建" #: ../scripting/abc.cpp:1230 msgid "Stack not clean at the end of function" msgstr "函数结束时未清空栈" #: ../parsing/tags_stub.cpp:46 msgid "StartSound Tag" msgstr "StartSound标识" #: ../scripting/abc_codesynt.cpp:1574 msgid "Starting block at " msgstr "开始块于" #: ../scripting/toplevel.cpp:3021 msgid "String to bool" msgstr "String到bool" #: ../swftypes.cpp:621 #, fuzzy msgid "Style not implemented" msgstr "未实现动作" #: ../scripting/abc.cpp:919 msgid "Super " msgstr "" #: ../scripting/abc_opcodes.cpp:1416 msgid "Super prototype name " msgstr "超原型名称" #: ../scripting/abc_interpreter.cpp:397 msgid "Switch default dest " msgstr "切换预设目标" #: ../scripting/abc_interpreter.cpp:404 msgid "Switch dest " msgstr "切换目标" #: ../scripting/abc.cpp:93 msgid "SymbolClassTag" msgstr "" #: ../scripting/abc.cpp:105 msgid "SymbolClassTag Exec" msgstr "" #: ../parsing/tags.cpp:300 msgid "Sync to variable name " msgstr "同步到可变名称" #: ../scripting/flashevents.cpp:119 msgid "Target for event " msgstr "目标设给事件" #: ../scripting/flashtext.cpp:100 msgid "TextField::Render" msgstr "" #: ../scripting/abc.cpp:1513 ../scripting/abc.cpp:1786 msgid "Trait not supported " msgstr "不支持的属性" #: ../asobject.cpp:84 ../asobject.cpp:167 ../scripting/abc_opcodes.cpp:1774 #: ../scripting/abc_opcodes.cpp:1837 ../scripting/abc_opcodes.cpp:1888 msgid "Type " msgstr "类型" #: ../backends/rendering.cpp:78 msgid "Unable to find suitable Serif font" msgstr "不能找到可用Serif字体" #: ../backends/rendering.cpp:238 msgid "Unable to load serif font" msgstr "不能加载Serif字体" #: ../parsing/tags.cpp:375 msgid "Unclassified tag inside Sprite?" msgstr "Sprite内未封装标识" #: ../swf.cpp:65 msgid "Uncompressed SWF file: Version " msgstr "解压SWF文件:版本" #: ../scripting/toplevel.cpp:1180 msgid "Undefined function" msgstr "未定义函数" #: ../scripting/toplevel.cpp:3051 msgid "Undefined to bool" msgstr "未定义给bool" #: ../timer.cpp:164 msgid "Unexpected failure of sem_timedwait.. Trying to go on. errno=" msgstr "sem_timedwait..意外失败,尝试继续运行。出错号=" #: ../scripting/abc.cpp:2113 msgid "Unexpected kind " msgstr "意外类型" #: ../scripting/abc.cpp:2021 msgid "Unexpected multiname kind " msgstr "意外多名称类型" #: ../scripting/abc.cpp:2045 msgid "Unexpected options type" msgstr "意外选项类型" #: ../scripting/flashnet.cpp:726 msgid "Unexpected tag type " msgstr "意外标识类型" #: ../scripting/toplevel.cpp:2162 msgid "Unicode not supported in String::fromCharCode" msgstr "String::fromCharCode不支持Unicode" #: ../parsing/tags_stub.cpp:106 msgid "Unimplemented Tag " msgstr "未实现标识" #: ../swftypes.h:647 msgid "Unsigned bit field wider than 32 bit not supported" msgstr "不支持无符合位域超过32位" #: ../scripting/actions.cpp:405 msgid "Unsupported ActionCode " msgstr "未支持的ActionCode " #: ../swftypes.cpp:907 msgid "Unsupported Filter Id " msgstr "不支持Filter Id " #: ../parsing/tags.cpp:209 msgid "Unsupported tag type " msgstr "不支持标识类型" #: ../backends/rendering.cpp:473 msgid "Vertex shader compilation " msgstr "着色器编译" #: ../backends/rendering.cpp:519 msgid "Video card does not support OpenGL 2.0... Aborting" msgstr "显卡不支持OpenGL 2.0. 放弃" #: ../backends/decoder.cpp:40 msgid "Video frame size " msgstr "图像框大小" #: ../scripting/abc_opcodes.cpp:1596 ../scripting/abc_opcodes.cpp:1680 msgid "We got a Undefined function" msgstr "发现未定义函数" #: ../scripting/abc_opcodes.cpp:825 ../scripting/abc_opcodes.cpp:829 msgid "We got a Undefined function " msgstr "发现未定义函数" #: ../scripting/abc_opcodes.cpp:303 msgid "We got a Undefined function on obj " msgstr "发现未定义函数于对象" #: ../scripting/abc_opcodes.cpp:285 msgid "We got a function not yet valid" msgstr "发现尚无效函数" #: ../scripting/abc_opcodes.cpp:1322 ../scripting/flashsystem.cpp:96 #: ../scripting/flashutils.cpp:333 msgid "We got an object not yet valid" msgstr "发现尚无效对象" #: ../backends/input.cpp:190 ../backends/input.cpp:266 msgid "We still miss " msgstr "尚缺" #: ../scripting/flashevents.cpp:292 msgid "Weird event reregistration" msgstr "反常事件再记录" #: ../backends/rendering.cpp:259 msgid "Window resize not supported in plugin" msgstr "插件不支持窗口缩放" #: ../asobject.cpp:704 msgid "[" msgstr "" #: ../scripting/abc_opcodes.cpp:169 ../scripting/abc_opcodes.cpp:174 msgid "]" msgstr "" #: ../asobject.cpp:704 ../scripting/abc_opcodes.cpp:921 #: ../scripting/abc_opcodes.cpp:927 ../scripting/abc_opcodes.cpp:933 msgid "] " msgstr "" #: ../scripting/abc_opcodes.cpp:164 msgid "] (" msgstr "" #: ../scripting/abc_opcodes.cpp:159 ../scripting/abc_opcodes.cpp:179 msgid "] (int)= " msgstr "" #: ../scripting/abc_opcodes.cpp:184 msgid "] = " msgstr "" #: ../scripting/abc_opcodes.cpp:948 ../scripting/abc_opcodes.cpp:964 #: ../scripting/abc_opcodes.cpp:973 ../scripting/abc_opcodes.cpp:995 #: ../scripting/abc_opcodes.cpp:1003 ../scripting/abc_opcodes.cpp:1012 #: ../scripting/abc_opcodes.cpp:1039 ../scripting/abc_opcodes.cpp:1047 #: ../scripting/abc_opcodes.cpp:1055 msgid "add " msgstr "加" #: ../scripting/abc_opcodes.cpp:1846 msgid "asTypelate" msgstr "" #: ../scripting/abc_opcodes.cpp:44 msgid "bitAnd_oi " msgstr "" #: ../scripting/abc_opcodes.cpp:35 msgid "bitAnd_oo " msgstr "" #: ../scripting/abc_opcodes.cpp:223 msgid "bitNot " msgstr "" #: ../scripting/abc_opcodes.cpp:242 ../scripting/abc_opcodes.cpp:252 msgid "bitOr " msgstr "" #: ../scripting/abc_opcodes.cpp:233 msgid "bitXor " msgstr "" #: ../scripting/abc_codesynt.cpp:751 msgid "block analysis: branches" msgstr "块分析:分支" #: ../scripting/abc_codesynt.cpp:713 msgid "block analysis: kill" msgstr "块分析:中止" #: ../scripting/abc_opcodes.cpp:2351 msgid "call " msgstr "调用" #: ../scripting/abc_opcodes.cpp:748 msgid "callPropVoid " msgstr "" #: ../scripting/abc_opcodes.cpp:263 msgid "callProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:1568 msgid "callSuper " msgstr "" #: ../scripting/abc_opcodes.cpp:1651 msgid "callSuperVoid " msgstr "" #: ../scripting/toplevel.cpp:2028 msgid "capturing groups " msgstr "" #: ../scripting/abc_opcodes.cpp:149 msgid "coerce " msgstr "" #: ../scripting/abc_opcodes.cpp:133 msgid "coerce_a" msgstr "" #: ../scripting/abc_opcodes.cpp:143 msgid "coerce_s" msgstr "" #: ../scripting/abc_opcodes.cpp:593 msgid "construct " msgstr "" #: ../scripting/abc_opcodes.cpp:682 msgid "constructGenericType " msgstr "" #: ../scripting/abc_opcodes.cpp:1957 msgid "constructProp " msgstr "" #: ../scripting/abc_opcodes.cpp:1399 msgid "constructSuper " msgstr "" #: ../scripting/abc_opcodes.cpp:87 msgid "convert_b" msgstr "" #: ../scripting/abc_opcodes.cpp:74 msgid "convert_d" msgstr "" #: ../scripting/abc_opcodes.cpp:103 msgid "convert_i" msgstr "" #: ../scripting/abc_opcodes.cpp:95 msgid "convert_u" msgstr "" #: ../scripting/abc_codesynt.cpp:784 ../scripting/abc_codesynt.cpp:2248 msgid "count " msgstr "计数" #: ../scripting/flashdisplay.cpp:505 msgid "createEmptyMovieClip" msgstr "" #: ../scripting/abc.cpp:876 msgid "dMultiname to String not yet implemented for this kind " msgstr "dMultiname到String在本类中尚未实现" #: ../scripting/abc_interpreter.cpp:1233 msgid "debug" msgstr "调试" #: ../scripting/abc_codesynt.cpp:37 msgid "debug_d " msgstr "" #: ../scripting/abc_codesynt.cpp:42 msgid "debug_i " msgstr "" #: ../scripting/abc_interpreter.cpp:1255 msgid "debugfile" msgstr "" #: ../scripting/abc_interpreter.cpp:1247 msgid "debugline" msgstr "" #: ../scripting/abc_opcodes.cpp:465 msgid "decrement" msgstr "" #: ../scripting/abc_opcodes.cpp:474 msgid "decrement_i" msgstr "" #: ../scripting/abc_codesynt.cpp:781 ../scripting/abc_codesynt.cpp:2245 msgid "default " msgstr "" #: ../scripting/abc_opcodes.cpp:2386 msgid "deleteProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:437 msgid "divide " msgstr "" #: ../scripting/abc_opcodes.cpp:429 msgid "divide: HACK" msgstr "" #: ../scripting/abc_codesynt.cpp:1359 ../scripting/abc_codesynt.cpp:3931 #: ../scripting/abc_interpreter.cpp:1262 msgid "dump " msgstr "" #: ../scripting/abc_opcodes.cpp:1183 msgid "dup: DONE" msgstr "" #: ../scripting/abc_opcodes.cpp:1137 msgid "equals " msgstr "" #: ../scripting/abc_opcodes.cpp:1467 msgid "findPropStrict " msgstr "" #: ../scripting/abc_opcodes.cpp:1430 msgid "findProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:458 msgid "getGlobalScope: " msgstr "" #: ../scripting/abc_opcodes.cpp:1342 msgid "getLex: " msgstr "" #: ../scripting/abc_interpreter.cpp:773 ../scripting/abc_interpreter.cpp:1210 msgid "getLocal " msgstr "" #: ../scripting/abc_opcodes.cpp:159 ../scripting/abc_opcodes.cpp:164 #: ../scripting/abc_opcodes.cpp:169 msgid "getLocal[" msgstr "" #: ../scripting/abc.cpp:306 msgid "getMultinameRTData not yet implemented for this kind " msgstr "getMultinameRTData在本类型中尚未实现" #: ../scripting/abc_opcodes.cpp:372 msgid "getProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:361 msgid "getProperty_i " msgstr "" #: ../scripting/abc_opcodes.cpp:2415 msgid "getScopeObject: " msgstr "" #: ../scripting/abc_opcodes.cpp:204 msgid "getSlot " msgstr "" #: ../scripting/abc_opcodes.cpp:1298 msgid "getSuper " msgstr "" #: ../scripting/toplevel.cpp:1463 msgid "getTimezoneOffset" msgstr "" #: ../backends/rendering.cpp:190 msgid "glX not present" msgstr "glX不存在" #: ../scripting/abc_opcodes.cpp:1521 msgid "greaterEquals" msgstr "" #: ../scripting/abc_opcodes.cpp:1510 msgid "greaterThan" msgstr "" #: ../scripting/abc_opcodes.cpp:2035 msgid "hasNext2 " msgstr "" #: ../scripting/abc_opcodes.cpp:1903 msgid "ifEq (" msgstr "" #: ../scripting/abc_opcodes.cpp:1943 msgid "ifFalse (" msgstr "" #: ../scripting/abc_opcodes.cpp:1252 msgid "ifGE (" msgstr "" #: ../scripting/abc_opcodes.cpp:1209 msgid "ifGT (" msgstr "" #: ../scripting/abc_opcodes.cpp:1232 msgid "ifLE (" msgstr "" #: ../scripting/abc_opcodes.cpp:496 msgid "ifLT (" msgstr "" #: ../scripting/abc_opcodes.cpp:520 msgid "ifLT_io " msgstr "" #: ../scripting/abc_opcodes.cpp:505 msgid "ifLT_oi" msgstr "" #: ../scripting/abc_opcodes.cpp:532 ../scripting/abc_opcodes.cpp:545 msgid "ifNE (" msgstr "" #: ../scripting/abc_opcodes.cpp:1262 msgid "ifNGE (" msgstr "" #: ../scripting/abc_opcodes.cpp:1221 msgid "ifNGT (" msgstr "" #: ../scripting/abc_opcodes.cpp:1242 msgid "ifNLE (" msgstr "" #: ../scripting/abc_opcodes.cpp:485 msgid "ifNLT (" msgstr "" #: ../scripting/abc_opcodes.cpp:1921 msgid "ifStrictEq " msgstr "" #: ../scripting/abc_opcodes.cpp:1927 msgid "ifStrictNE" msgstr "" #: ../scripting/abc_opcodes.cpp:846 msgid "ifTrue (" msgstr "" #: ../scripting/abc_opcodes.cpp:1933 msgid "in" msgstr "于" #: ../scripting/abc_opcodes.cpp:578 msgid "incLocal_i " msgstr "" #: ../scripting/abc_opcodes.cpp:2130 msgid "increment_i" msgstr "" #: ../scripting/abc_opcodes.cpp:1547 msgid "initProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:1720 msgid "isType " msgstr "" #: ../scripting/abc_opcodes.cpp:1768 #, fuzzy msgid "isType on non classed object " msgstr "isType于非类对象" #: ../scripting/abc_opcodes.cpp:1782 msgid "isTypelate" msgstr "" #: ../scripting/abc_opcodes.cpp:1830 #, fuzzy msgid "isTypelate on non classed object " msgstr "isTypelate于非类对象" #: ../scripting/abc_opcodes.cpp:840 msgid "jump " msgstr "转跳" #: ../scripting/abc_opcodes.cpp:938 msgid "kill " msgstr "中止" #: ../scripting/abc_opcodes.cpp:1080 ../scripting/abc_opcodes.cpp:1091 msgid "lShift " msgstr "左移位" #: ../scripting/abc_opcodes.cpp:111 msgid "label" msgstr "标记" #: ../scripting/abc_opcodes.cpp:1532 msgid "lessEquals" msgstr "小于等于" #: ../scripting/abc_opcodes.cpp:2334 msgid "lessThan" msgstr "小于" #: ../scripting/abc_opcodes.cpp:116 msgid "lookupswitch" msgstr "" #: ../scripting/abc_opcodes.cpp:859 msgid "modulo " msgstr "同余" #: ../scripting/abc_opcodes.cpp:572 msgid "multiply " msgstr "乘" #: ../scripting/abc_opcodes.cpp:562 msgid "multiply_oi " msgstr "" #: ../scripting/abc_opcodes.cpp:213 msgid "negate" msgstr "取负" #: ../scripting/abc_opcodes.cpp:2309 msgid "newActivation" msgstr "" #: ../scripting/abc_opcodes.cpp:2434 msgid "newArray " msgstr "" #: ../scripting/abc_opcodes.cpp:2428 msgid "newCatch " msgstr "" #: ../scripting/abc_opcodes.cpp:2200 msgid "newClass " msgstr "" #: ../scripting/abc_opcodes.cpp:2398 msgid "newFunction " msgstr "" #: ../scripting/abc_opcodes.cpp:2090 msgid "newObject " msgstr "" #: ../scripting/abc_opcodes.cpp:2164 msgid "nextName" msgstr "" #: ../scripting/abc_opcodes.cpp:2139 msgid "nextValue" msgstr "" #: ../parsing/tags.cpp:1364 ../parsing/tags.cpp:1531 msgid "no char to move at depth " msgstr "没有字符可供移动于深度" #: ../scripting/abc_opcodes.cpp:1128 msgid "not" msgstr "非" #: ../scripting/abc_opcodes.cpp:1888 msgid "not " msgstr "非" #: ../scripting/abc.cpp:1184 msgid "not implement opcode 0x" msgstr "不实现opcode 0x" #: ../scripting/abc_opcodes.cpp:1943 msgid "not taken" msgstr "未接受" #: ../scripting/abc_opcodes.cpp:485 ../scripting/abc_opcodes.cpp:496 #: ../scripting/abc_opcodes.cpp:532 ../scripting/abc_opcodes.cpp:545 #: ../scripting/abc_opcodes.cpp:846 ../scripting/abc_opcodes.cpp:1209 #: ../scripting/abc_opcodes.cpp:1221 ../scripting/abc_opcodes.cpp:1232 #: ../scripting/abc_opcodes.cpp:1242 ../scripting/abc_opcodes.cpp:1252 #: ../scripting/abc_opcodes.cpp:1262 ../scripting/abc_opcodes.cpp:1903 msgid "not taken)" msgstr "未接受)" #: ../scripting/abc.cpp:1839 msgid "parsing s32" msgstr "解释s32" #: ../scripting/abc.cpp:1889 ../scripting/abc.cpp:1893 msgid "parsing u30" msgstr "解释u30" #: ../scripting/abc.cpp:1814 msgid "parsing u32 " msgstr "解释u32 " #: ../scripting/abc_opcodes.cpp:154 msgid "pop: DONE" msgstr "弹出:DONE" #: ../scripting/abc_opcodes.cpp:2327 msgid "popScope" msgstr "" #: ../thread_pool.cpp:68 msgid "pthread_join failed in ~ThreadPool" msgstr "pthread_join于~ThreadPool失败" #: ../scripting/abc.cpp:989 msgid "pthread_join in ABCVm failed" msgstr "pthread_join于ABCVm失败 " #: ../scripting/abc_opcodes.cpp:553 msgid "pushByte " msgstr "" #: ../scripting/abc_opcodes.cpp:933 msgid "pushDouble [" msgstr "" #: ../scripting/abc_opcodes.cpp:1194 msgid "pushFalse" msgstr "" #: ../scripting/abc_opcodes.cpp:927 msgid "pushInt [" msgstr "" #: ../scripting/abc_opcodes.cpp:1200 msgid "pushNaN" msgstr "" #: ../scripting/abc_opcodes.cpp:127 msgid "pushNull" msgstr "" #: ../scripting/abc_opcodes.cpp:451 msgid "pushScope " msgstr "" #: ../scripting/abc_opcodes.cpp:189 msgid "pushShort " msgstr "" #: ../scripting/abc_opcodes.cpp:2422 msgid "pushString " msgstr "" #: ../scripting/abc_opcodes.cpp:1188 msgid "pushTrue" msgstr "" #: ../scripting/abc_opcodes.cpp:921 msgid "pushUInt [" msgstr "" #: ../scripting/abc_opcodes.cpp:121 msgid "pushUndefined" msgstr "" #: ../scripting/abc_opcodes.cpp:444 msgid "pushWith " msgstr "" #: ../scripting/abc_opcodes.cpp:1103 msgid "rShift " msgstr "" #: ../scripting/toplevel.cpp:2026 msgid "re: " msgstr "" #: ../scripting/abc_interpreter.cpp:636 msgid "returnValue " msgstr "" #: ../scripting/abc_interpreter.cpp:629 msgid "returnVoid" msgstr "" #: ../scripting/abc_interpreter.cpp:782 ../scripting/abc_interpreter.cpp:1222 msgid "setLocal " msgstr "" #: ../scripting/abc_opcodes.cpp:174 ../scripting/abc_opcodes.cpp:179 #: ../scripting/abc_opcodes.cpp:184 msgid "setLocal[" msgstr "" #: ../scripting/abc_opcodes.cpp:50 msgid "setProperty " msgstr "" #: ../scripting/abc_opcodes.cpp:66 msgid "setProperty_i " msgstr "" #: ../scripting/abc_opcodes.cpp:195 msgid "setSlot " msgstr "" #: ../scripting/abc_opcodes.cpp:1277 msgid "setSuper " msgstr "" #: ../scripting/abc_opcodes.cpp:1174 msgid "strictEquals" msgstr "" #: ../scripting/abc_opcodes.cpp:914 msgid "subtract " msgstr "" #: ../scripting/abc_opcodes.cpp:889 ../scripting/abc_opcodes.cpp:906 msgid "subtract: HACK" msgstr "" #: ../scripting/abc_opcodes.cpp:880 msgid "subtract_do " msgstr "" #: ../scripting/abc_opcodes.cpp:896 msgid "subtract_io " msgstr "" #: ../scripting/abc_opcodes.cpp:869 msgid "subtract_oi " msgstr "" #: ../scripting/abc_opcodes.cpp:2304 msgid "swap" msgstr "" #: ../scripting/abc_codesynt.cpp:3287 msgid "synt add" msgstr "" #: ../scripting/abc_codesynt.cpp:3184 msgid "synt astypelate" msgstr "" #: ../scripting/abc_codesynt.cpp:3594 msgid "synt bitand" msgstr "" #: ../scripting/abc_codesynt.cpp:3270 msgid "synt bitnot" msgstr "" #: ../scripting/abc_codesynt.cpp:3627 msgid "synt bitor" msgstr "" #: ../scripting/abc_codesynt.cpp:3649 msgid "synt bitxor" msgstr "" #: ../scripting/abc_codesynt.cpp:2542 msgid "synt call" msgstr "" #: ../scripting/abc_codesynt.cpp:2578 msgid "synt callproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:2692 msgid "synt callpropvoid" msgstr "" #: ../scripting/abc_codesynt.cpp:2564 msgid "synt callsuper" msgstr "" #: ../scripting/abc_codesynt.cpp:2679 msgid "synt callsupervoid" msgstr "" #: ../scripting/abc_codesynt.cpp:3139 msgid "synt checkfilter" msgstr "" #: ../scripting/abc_codesynt.cpp:3149 msgid "synt coerce" msgstr "" #: ../scripting/abc_codesynt.cpp:3160 msgid "synt coerce_a" msgstr "" #: ../scripting/abc_codesynt.cpp:3174 msgid "synt coerce_s" msgstr "" #: ../scripting/abc_codesynt.cpp:2553 msgid "synt construct" msgstr "" #: ../scripting/abc_codesynt.cpp:2705 msgid "synt constructgenerictype" msgstr "" #: ../scripting/abc_codesynt.cpp:2666 msgid "synt constructprop" msgstr "" #: ../scripting/abc_codesynt.cpp:2655 msgid "synt constructsuper" msgstr "" #: ../scripting/abc_codesynt.cpp:3125 msgid "synt convert_b" msgstr "" #: ../scripting/abc_codesynt.cpp:3110 msgid "synt convert_d" msgstr "" #: ../scripting/abc_codesynt.cpp:3080 msgid "synt convert_i" msgstr "" #: ../scripting/abc_codesynt.cpp:3074 msgid "synt convert_s" msgstr "" #: ../scripting/abc_codesynt.cpp:3095 msgid "synt convert_u" msgstr "" #: ../scripting/abc_codesynt.cpp:3900 msgid "synt debug" msgstr "" #: ../scripting/abc_codesynt.cpp:3922 msgid "synt debugfile" msgstr "" #: ../scripting/abc_codesynt.cpp:3914 msgid "synt debugline" msgstr "" #: ../scripting/abc_codesynt.cpp:3228 msgid "synt decrement" msgstr "" #: ../scripting/abc_codesynt.cpp:3791 msgid "synt decrement_i" msgstr "" #: ../scripting/abc_codesynt.cpp:3025 msgid "synt deleteproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:3444 msgid "synt divide" msgstr "" #: ../scripting/abc_codesynt.cpp:2404 msgid "synt dup" msgstr "" #: ../scripting/abc_codesynt.cpp:3672 msgid "synt equals" msgstr "" #: ../scripting/abc_codesynt.cpp:2812 msgid "synt findproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:2779 msgid "synt findpropstrict" msgstr "" #: ../scripting/abc_codesynt.cpp:2757 msgid "synt getdescendants" msgstr "" #: ../scripting/abc_codesynt.cpp:2949 msgid "synt getglobalscope" msgstr "" #: ../scripting/abc_codesynt.cpp:2824 msgid "synt getlex" msgstr "" #: ../scripting/abc_codesynt.cpp:2882 msgid "synt getlocal" msgstr "" #: ../scripting/abc_codesynt.cpp:3833 msgid "synt getlocal_n " msgstr "" #: ../scripting/abc_codesynt.cpp:2968 msgid "synt getproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:2957 msgid "synt getscopeobject" msgstr "" #: ../scripting/abc_codesynt.cpp:3036 msgid "synt getslot" msgstr "" #: ../scripting/abc_codesynt.cpp:1630 msgid "synt getsuper" msgstr "" #: ../scripting/abc_codesynt.cpp:3738 msgid "synt greaterequals" msgstr "" #: ../scripting/abc_codesynt.cpp:3725 msgid "synt greaterthan" msgstr "" #: ../scripting/abc_codesynt.cpp:2497 msgid "synt hasnext2" msgstr "" #: ../scripting/abc_codesynt.cpp:1908 msgid "synt ifeq" msgstr "" #: ../scripting/abc_codesynt.cpp:1876 msgid "synt iffalse " msgstr "" #: ../scripting/abc_codesynt.cpp:2127 msgid "synt ifge" msgstr "" #: ../scripting/abc_codesynt.cpp:2093 msgid "synt ifgt" msgstr "" #: ../scripting/abc_codesynt.cpp:2055 msgid "synt ifle" msgstr "" #: ../scripting/abc_codesynt.cpp:2015 msgid "synt iflt " msgstr "" #: ../scripting/abc_codesynt.cpp:1965 msgid "synt ifne " msgstr "" #: ../scripting/abc_codesynt.cpp:1784 msgid "synt ifnge" msgstr "" #: ../scripting/abc_codesynt.cpp:1751 msgid "synt ifngt" msgstr "" #: ../scripting/abc_codesynt.cpp:1719 msgid "synt ifnle" msgstr "" #: ../scripting/abc_codesynt.cpp:1680 msgid "synt ifnlt" msgstr "" #: ../scripting/abc_codesynt.cpp:2161 msgid "synt ifstricteq" msgstr "" #: ../scripting/abc_codesynt.cpp:2193 msgid "synt ifstrictne" msgstr "" #: ../scripting/abc_codesynt.cpp:1837 msgid "synt iftrue" msgstr "" #: ../scripting/abc_codesynt.cpp:3762 msgid "synt in" msgstr "" #: ../scripting/abc_codesynt.cpp:3808 msgid "synt inclocal_i" msgstr "" #: ../scripting/abc_codesynt.cpp:3205 msgid "synt increment" msgstr "" #: ../scripting/abc_codesynt.cpp:3774 msgid "synt increment_i" msgstr "" #: ../scripting/abc_codesynt.cpp:3014 msgid "synt initproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:3751 msgid "synt istypelate" msgstr "" #: ../scripting/abc_codesynt.cpp:1821 msgid "synt jump " msgstr "" #: ../scripting/abc_codesynt.cpp:1654 msgid "synt kill " msgstr "" #: ../scripting/abc_codesynt.cpp:1672 msgid "synt label" msgstr "" #: ../scripting/abc_codesynt.cpp:3712 msgid "synt lessequals" msgstr "" #: ../scripting/abc_codesynt.cpp:3699 msgid "synt lessthan" msgstr "" #: ../scripting/abc_codesynt.cpp:774 ../scripting/abc_codesynt.cpp:2236 msgid "synt lookupswitch" msgstr "" #: ../scripting/abc_codesynt.cpp:3514 msgid "synt lshift" msgstr "" #: ../scripting/abc_codesynt.cpp:3474 msgid "synt modulo" msgstr "" #: ../scripting/abc_codesynt.cpp:3401 msgid "synt multiply" msgstr "" #: ../scripting/abc_codesynt.cpp:3195 msgid "synt negate" msgstr "" #: ../scripting/abc_codesynt.cpp:2738 msgid "synt newactivation" msgstr "" #: ../scripting/abc_codesynt.cpp:2727 msgid "synt newarray" msgstr "" #: ../scripting/abc_codesynt.cpp:2768 msgid "synt newcatch" msgstr "" #: ../scripting/abc_codesynt.cpp:2746 msgid "synt newclass" msgstr "" #: ../scripting/abc_codesynt.cpp:2531 msgid "synt newfunction" msgstr "" #: ../scripting/abc_codesynt.cpp:2716 msgid "synt newobject" msgstr "" #: ../scripting/abc_codesynt.cpp:2303 msgid "synt nextname" msgstr "" #: ../scripting/abc_codesynt.cpp:2332 msgid "synt nextvalue" msgstr "" #: ../scripting/abc_codesynt.cpp:3256 msgid "synt not" msgstr "" #: ../scripting/abc_codesynt.cpp:2393 msgid "synt pop" msgstr "" #: ../scripting/abc_codesynt.cpp:2295 msgid "synt popscope" msgstr "" #: ../scripting/abc_codesynt.cpp:2345 msgid "synt pushbyte" msgstr "" #: ../scripting/abc_codesynt.cpp:2472 msgid "synt pushdouble" msgstr "" #: ../scripting/abc_codesynt.cpp:2377 msgid "synt pushfalse" msgstr "" #: ../scripting/abc_codesynt.cpp:2440 msgid "synt pushint" msgstr "" #: ../scripting/abc_codesynt.cpp:2385 msgid "synt pushnan" msgstr "" #: ../scripting/abc_codesynt.cpp:2316 msgid "synt pushnull" msgstr "" #: ../scripting/abc_codesynt.cpp:2489 msgid "synt pushscope" msgstr "" #: ../scripting/abc_codesynt.cpp:2357 msgid "synt pushshort" msgstr "" #: ../scripting/abc_codesynt.cpp:2429 msgid "synt pushstring" msgstr "" #: ../scripting/abc_codesynt.cpp:2369 msgid "synt pushtrue" msgstr "" #: ../scripting/abc_codesynt.cpp:2456 msgid "synt pushuint" msgstr "" #: ../scripting/abc_codesynt.cpp:2324 msgid "synt pushundefined" msgstr "" #: ../scripting/abc_codesynt.cpp:2287 msgid "synt pushwith" msgstr "" #: ../scripting/abc_codesynt.cpp:2626 msgid "synt returnvalue" msgstr "" #: ../scripting/abc_codesynt.cpp:2604 msgid "synt returnvoid" msgstr "" #: ../scripting/abc_codesynt.cpp:3538 msgid "synt rshift" msgstr "" #: ../scripting/abc_codesynt.cpp:2928 msgid "synt setlocal " msgstr "" #: ../scripting/abc_codesynt.cpp:3878 msgid "synt setlocal_n " msgstr "" #: ../scripting/abc_codesynt.cpp:2835 msgid "synt setproperty" msgstr "" #: ../scripting/abc_codesynt.cpp:3049 msgid "synt setslot" msgstr "" #: ../scripting/abc_codesynt.cpp:1641 msgid "synt setsuper" msgstr "" #: ../scripting/abc_codesynt.cpp:3689 msgid "synt strictequals" msgstr "" #: ../scripting/abc_codesynt.cpp:3348 msgid "synt subtract" msgstr "" #: ../scripting/abc_codesynt.cpp:2417 msgid "synt swap" msgstr "" #: ../scripting/abc_codesynt.cpp:1605 msgid "synt throw" msgstr "" #: ../scripting/abc_codesynt.cpp:3246 msgid "synt typeof" msgstr "" #: ../scripting/abc_codesynt.cpp:3559 msgid "synt urshift" msgstr "" #: ../scripting/abc_opcodes.cpp:1943 msgid "taken" msgstr "已接受" #: ../scripting/abc_opcodes.cpp:485 ../scripting/abc_opcodes.cpp:496 #: ../scripting/abc_opcodes.cpp:532 ../scripting/abc_opcodes.cpp:545 #: ../scripting/abc_opcodes.cpp:846 ../scripting/abc_opcodes.cpp:1209 #: ../scripting/abc_opcodes.cpp:1221 ../scripting/abc_opcodes.cpp:1232 #: ../scripting/abc_opcodes.cpp:1242 ../scripting/abc_opcodes.cpp:1252 #: ../scripting/abc_opcodes.cpp:1262 ../scripting/abc_opcodes.cpp:1903 msgid "taken)" msgstr "已接受)" #: ../scripting/abc_opcodes.cpp:713 msgid "typeOf" msgstr "" #: ../scripting/abc_opcodes.cpp:1113 ../scripting/abc_opcodes.cpp:1122 msgid "urShift " msgstr "" #: ../backends/rendering.cpp:106 msgid "~RenderThread this=" msgstr "" #~ msgid " :: " #~ msgstr " :: " #~ msgid "Function Tag" #~ msgstr "Function尚未实现" #~ msgid "NetStream Tag" #~ msgstr "NetStream创建" #~ msgid "Style Tag" #~ msgstr "Style尚未实现" lightspark-0.7.2/media/000077500000000000000000000000001212105246600147465ustar00rootroot00000000000000lightspark-0.7.2/media/lightspark-ico-128x128.png000066400000000000000000002005701212105246600213330ustar00rootroot00000000000000PNG  IHDR>agAMA abKGD pHYs B(xtIME &> IDATx@ 4/-) 7BB8 R[? >_T  t)~/6c   1.#y/9 $$YS>+)y l52&[W@ h,(<;*lgM q IDATf   WT>NJ8d [SS<VP=V*IG4[WA`*mkN-* m7yvXI NN9E@0lCsnSf7 vpSy$x}QO;41%jjo::+C@0_ /kq'(QL8Afmr''"  ^YC1Xim!DA/32& !OK7O%ci:8*TQ<(& ,*!EA0r2di1/$_]D#!0.#64'0."@?.1/#=~ GD2DB1PM9 [WB1eD IDAT"GD3\XB wsUuKuy a^FKG5lfM(P\c63&ztX&$C@/V dl    UDfmt   sz  6D_{#\c=:+!b ^YB<V#EB263&hbJzKm I#%8\^ ]\  #9= #!EA1.+ )' $"]Z a\D>;, 2/#2/#ZV@)'xoSVlE }]>;," gaIO IDAT4"qkP AB42&)'AA95(.,!>:+&$<A!!  8 8'mfN)''%b%'>:,-* -* (&VQ< :7):7) (LG5a'$ )v~ qiO2.",* #  UP;!51%>:+0,!#  wpS&$      E@0        %"74&!.; IDAT?    ,*A=.PJ7&#KF4 51% `[CWQ<A<-" "  94'  56'   HD2 YT>FA0 [fFA1\V??:,yh  ?:,:6(2/#(% e py  kdJEA05#!HC2}tW95(%!85'l{*(#!HC2lv (&h`HxYs}2." eJE30-#51$[T?~vW ]W@>;7*MG6rkO+(51$>;7(!UO;VP< $ 3/# ! &$2.#=9*" ] IDATFC2 r|!=9+95'%" ͚ WENZ            #!ɻE84(           _XC ̘gO3ArpyGUXcqzt~iMH5 2/" KF41." A<- D?/C?/-+ +' 2/" /,!-*  <8*!`qiNwnR&#/=ohbI{rU~cmµ*' ^iŸ'$aKF4vVP<gcm Ñ YeD@0g^OI6E@/}LG5" LG5(%0-! {sV A<- A<- x&#'$@8)bm{84'oz94'+(NH6P\C>.d#[Xd-;m&]'^&4h#[#[&])`#[=Jx#[#[#[,a#[R^$\-cz#[!0e#[#[#[GS+9l#[S_S_+(=9*2/#74' g_G=9*40$`ZC2@q6DtF@1+)ogMFB1*'ogN h`H      aphN+( yZ z 3/#'$1."|tVskPs}C>.;6(u~LF5jcJ}tWyuxCP}84&|]~^P\`yqToyhsd `k *'#u|zrUzrU~qzxv> IDAT]WA|tV1."}D@0?;,|:6)[U?` -* {#!leK.+ +(KF4jbIi$"QL9ak0   ._F+,9o IDATn `Uaa5XlC'twr|- t' V\BY`(0FB< 6C:/) " сIDATV)IENDB`lightspark-0.7.2/media/lightspark-ico-16x16.png000066400000000000000000000022361212105246600211620ustar00rootroot00000000000000PNG  IHDRagAMA abKGD pHYs B(xtIME +6} IDAT85&lw%$`[CC   |wZNI00"(' qmR5^֡ ~qkOZs }y[ B@0hp X.   d_F I! =:+!86(ZU@TM:# MG5|-S>֜)  uW$"!d#!C>.S?# *( 69{=(5VOYIENDB`lightspark-0.7.2/media/lightspark-ico-192x192.png000066400000000000000000004410721212105246600213410ustar00rootroot00000000000000PNG  IHDRRlgAMA abKGD pHYs B(xtIME O IDATx+~" ! 40/-, ??:4 'JH>t IDAT(WU+__/?eSYs-in lu~iy}O$w*H  !+* DA0 {x <:,UO; d8+a IDATGF3XS@}r :9*hdK \)2 A?/keKg hfJ30$Z_PN;YU>Y2=<-mhMy>CC1c^E`YYU?HF5OyrnP%#Jl~ytWGd\ZC:7)II IDATZytWMWkgL$#Jb22%WS>GmtyysV@~uqT 7[c`H#!=BED2;7*I&64'EB2b +w}  ++ MI7hVlr%$%#"" ##RN:>qtz 63'54%.-!Ns IDAT(*KF53+~3,* GD397)20&A?.N (?<-WU?   CB01/#ji<<+^ZC0."0.#0.#ZV@3HjfK%#CA1C@/ nhN 9 inQM953&XU?)'ztWunag +*1/#YU?/-"icK.8u{<9+hcJ$$GC2G3 [WARN:ZXBVblr/,!wrU zuW(ag soR2/$ b\E}xM IDAT~ w,*>;+ociRN:b]F \XA&g TP<{gy a brh HE330$e ,* a~j%"=:,ztW =:+ i[mf M-87hd IDATcd H]`HZU"!$"  a\EogL(-N!IE4<8*]XBUI  ^YBA>/$"$"ZV@52% @;,W~J.+ gB?/ ohNh &&J.+!ztVH-smQ HJZV? @ @ ;7*1 IDAT M9 9950%(&63&1.# )&:,.,! ?:,IE3  )&:9 /-!#!:8 #!'.NJ7.+MH6f`G -&,*@<-95(--RM:73&73&.#;8)D@0 $"" " WQ>   Dۨ IDAT+(woSngM  !+~!30$vX  ~rjP  oxZT? &$/+ &$73'# 1."41% 85(# C?.NI6$!(%   sjQ(&                62%     %"62% 62&.U IDAT    GB1=9+UO<A<-QL8)&  qjN 84' C>/C>/  '$0,! A<-  A<.*'*'-* ?;,JE3 RL9 3/# |tkQ py_YCWQ< hs[U?&$  {<7)HD2FA1~uW  v&#2/#2/#2.#  k rjO=9*-VQ IDATHC2tlQ%"3/#l:5($"!s x2/$)'+(v|*':6)q { PJ7gr|*'42%}]^XBr|>:*?51%(%i,)RK:?40$ skOhbI  o40$QL9|sV1." 84&UP;phN" SL8A<-P IDAT%#VP<VP;SN;YB>.0-!=9*KF50-!Y+((% &$# )&85' ;7*MI6HC163&73&  smP-ER~       ȕ[-0-!            PL88            ͚ ?2@p " ʼls]WA !!g`H6Bx\ IDAT+~CP}CP}CP}woSXR=cr|NH6h pzlvgr95(gq0-!yTO;!2/"S_  SM:u~/,!̘ɻ_%#SN:kulvfp/,!y uamfLe>:+oxYS>woS+){\0-"YR>85'}LX84'}JE340$ #!b[D'$|]30#EA0u)&|]2/#+(}uW,)gp-* w [U?s+)51%u>Jy~^| '$g85'! ID384' { bEA0| &#d} +(x 63&+)D?/\V@ iaH1BB IDATmdK Xc%3gT`UN;kcJXR= h`HaZC }! +)}B=.blfp&$  -* vȕiWQ< m}]uo*')'%# TO;hÒ:6)}A=-A=-}voRLG5WQ<:6)wZ slPcmJF4rjO[U?ku[OJ73/#>:+ ^iPK851$ haI,)EA0ZeQL940$ a@LzMH5qsI?MzϚ OI7YMH5aZDumQq{r|f3/#Zf 30#74'ceER~&#kdJ{B>- vavX rjOl z%#$!TN;FB1C>.sTO;D?/skP}ZA OI7<8) mfL[V@ZT>|sW3/#OI7  zrUbPK8\VAohMleK@<- 30#B=.u0-"84&nw -) !?;,b h%#[#[t~#[#[qis~ m[Kg IDATe-* ̾œ;7)WohM umQ/,!/,!v ohMohMY7X <8*+(T .MY z2/#f<7)tmQ)&y-]BHZQbKiH IDATFf?YGTCCG9\@jE=X X6Fr\Dݭ IDATo,Ga<:+~o|lfv)T/M0sWne Ve;)`V #o IDAT6WQ (JK< 7;;:!/--)! ! IDATv(X!IENDB`lightspark-0.7.2/media/lightspark-ico-22x22.png000066400000000000000000000040641212105246600211550ustar00rootroot00000000000000PNG  IHDRĴl;gAMA abKGD pHYs B(xtIME *cIDAT8Y ~<q}ZVAIF3jZ   gdI/+"Mbkq 52%""$&KG56`lr A>.TP<**31%>   ""><0<PSjfK/.!+)-+ aj! oOWS>faIKH621%<1 0!VR<b]E^XBr|41%YS= 40$ "U`TN:>:+z 95'" !(&Yd` ! 4/#NI79  A<.""!#!@<,\ '$OJ7*' &$$ ;!O=u&pIENDB`lightspark-0.7.2/media/lightspark-ico-24x24.png000066400000000000000000000046461212105246600211670ustar00rootroot00000000000000PNG  IHDRw=gAMA abKGD pHYs B(xtIME )*J #IDATH  tA {o ('jdKq4   plP(&esx  ""WS=ge`H20$\e^MTP<2/$=*1.#%xngM~vXlv95(YS>3Ar z 0,!6:6(HD3" _f_G  #"gaG PL8)&)&>:+# 62%i/,!/+ mwIw'sA)W kڪTIENDB`lightspark-0.7.2/media/lightspark-ico-256x256.png000066400000000000000000010014661212105246600213430ustar00rootroot00000000000000PNG  IHDR\rfgAMA abKGD pHYs B(xtIME 8h IDATx dz IDAT -+ *90-- 6;<9(IH>CPH >WS3K IDAT/cU Xe6-lY DtFWs0[!V'~O-{l9 IDAT*Ff  $#84$ e ,*?=/;7(k'</-"SO;1/#yv| *)]XA30$h0.A>.^ZC lr  GD1c]G_D VT>SO;|/L IDATQ+* njO[r a^FEA0aAIH6a\D{6;;,mgLX_?@/gaIM~IF3ZWAT^mjN0-"hA  ytW}ޟS IDAT,01&hcHd&okP%$^" snPV(qmQ O'33%ZU@K!w{|xY P$daH(&W)65'PL9` IDAT 0t{ upRlNns~x[jiw{unR Ru]ZC&$BNOM90.#8(FE273'> ) ;:*?<-hT''$"#"44%C@0bk IDATt&%42%42%:;,<8*<9DB2@>. ED31/#0 "98)HE3.,!PL8('a`y}@>.WU?    a^GWTlqDB0XU? )(1."/.#'%rmS /dk&%lgM'& 1.#?<-;9*xsUDLhl a_F20# <9+GC3,+smQjWx~20$IF4XT>B?0ZU?+ IDAT21#VR=FC2>;/30"Pavz fbI>;,fcI VBbg20#kfMzuV*,lqVQ=YV?e`Gtj(&ysU>=,0."+kq rlQ97)tnROpaeQM9b]EsmRF&ktnS<8).UP:VM 85(.+ &$2/# AV"RN;74' 1."1."2/#unRRG [V@FC1"!"!ZU@ VI96(gGD2c]FkOJ8 >HXS>smR [V@ EGQM9TP<b IDATI10-!ZU@ EGhcJ/IGB2G5EB1    3/#?2  .+ 0.#74& 3/#8;.+!62&>;,,)*:NJ895( ;;BI IDATMG5;# 8.2/## .c]F+/ {\KF40-[V@ge_G0-"- " @<-@<--';8) /,!/,!)"31$+(+( uϟ IDAT  d^F HC3HC3  ! _YBb85( !  ibIqiN   0-"{sU  qiO 85(1."" SL:1-"0-"$!D@/ .+ &#%#B>.n/ IDAT %#-*41$ 83' -* OJ7 )' B=.XR<(%'$     QL9 '#'$        QL9        51$     %#62&    -*/+" QK9(% Ag IDAT    HC3'$@<,_YB84'    >:+(%'$(%(%$#<7*40# 1." (&)&)&D?0# # C=.  52$ !B>.@;-@;,    A=-E@0zqT f_G KE4   E@0 IDAT TN:_YB+(zz 51%OJ7HC1 lvQL9=9* |'$GC2F@01."_  ,*3/#30$*& k  ;Hw ~uWngM/,!W+D?/mfL+-* k+'!v -ĥ IDAT63'%#v97&)'v! w#! )&+(v%#')'>:+o 96(2/"tlPw nxMF4T72&j>:+w(&$" D@0eB IDAT3/#|]KF461%74'hbIskO OL9Q>:+VP<piM IC1Q0,! \U@mfL@;,*'VP<VP<B?.@<-RK9WR<,)iaHBC?. :6(=9+=9*'$ &$B40$ %#(%  &$# $"%#$!A IDAT2."-}KE4;8)73&   tF@01?p%"52%40$!!՟ec2."              (#62&cRM:              phL -:m         ќEQ HC2 :4'KH5XXd  Ǔ gq Wy- IDATyHSc(grf_FGB2}fo84'$=LF4mw84'xSN:4q IDAT /,!z  wY+)<8)73&{LG5skO52%>9*S_phN=9*&#TO;b[D Xcu&# $!GC2 ,)FB1 wyqT*'d]E :6)hgq!{\FB1# QL9P\ voRaZDZS>N[umQvPK8wYNI7b\DqjO 0-!!ɻ!n UaZfw^ilvQK8BO|GT?Kz{e 51%C>. KF5hsLG5~Ǖ̾qYS>/,!$"XcT_y{R _XB~keK84'a[D JE30-!HC2C>. [U?74'm84'e_F3/$ n ID3wX YS=!ku~$"VP< @<,>9+ w{YumQ95(s '$RL8fq} pC>.UO;piN\fYS>OI7<8*XR=cjbIGB2^XB_jcJ nEA0uzr|r|r|{ l h}tWC>. q -+ R^Xc-* eleKXR=40$`qiNNH6}^EA0Ӎ IDAT~{LG5 WR< ^WASM:&#NH6v=Jx./!N[HT" ogMmJE340$ZT?~51$ngLpiNAO|]V@<8*SM:2/#XR=A=- pywvnR{\[goywphMvyf40$oMX r ,)xqS>:+2/#  ?;+UO;kdJFB1{sU" IDATaR^TO;kv=9*-* *'phNohM{sVtlP skPhphNf >:+TO;~kzrHC2?;,i" }tWt(%JE33/#yZ+(woSmfLnvnR(%`ZCƹyqTZT>̾phN#!d]EyZ nR,)LX‘ $"qiN'$.+ VQ<LX}84'   ,)84'<8* JE4eDQ}‘LX}84'Hd=Jx6Cs`Ua_jbrr{40$:6)uZj{x/KD IDATrt-* QL9:6)D@0T6\}dg*'*'#5Ct@;-  CK[gfZT>6mD@0p  eZT>Ju(%MI6 JN~L IDATj 7y-g%^T$K@N>P=XZ IDATV?_?}hebzQX N0!]4O{W/> IDAT\H\.?j\+5p9sFb"E~^k) IDATc9$QG5M.T(~Ps::sP%l\ Rf=. IDAT(`X8WT<PI( HHC 4:;<&8/-..)!"    n IDAT=O3IDAT]תdIENDB`lightspark-0.7.2/media/lightspark-ico-32x32.png000066400000000000000000000102561212105246600211570ustar00rootroot00000000000000PNG  IHDR szzgAMA abKGD pHYs B(xtIME )NZ+IDATX   EF( (rc *(faI*)u&&  \Y@JH7r7   z[ P &# [XB" b.'&64'b^H ouiqr vpT%ah  }[W@khEA1r V` ePQM:~^y[SO;z K5:7)`[D P< =$;7*NI7v# (% "!qjN74%phO73&2.#vX1-"$"y ;7))%RM:40$ -@=-  73&OI6 )'.+ =8*30$)'RL9c\Dc\E \aZC52%:6(-* '$;6)}"-*LH5C>//, #!  -M9 s@MF'W9GI<IENDB`lightspark-0.7.2/media/lightspark-ico-36x36.png000066400000000000000000000123621212105246600211670ustar00rootroot00000000000000PNG  IHDR$$gAMA abKGD pHYs B(xtIME (&cwoIDATX d83&</@ =;+'$z~%$olQ%"Z M   ysV iC    RP<63&k] )('$SN:Oe-)  96)%%&'=9+/-,!aKG7Q~YaP<`sWS>ck  xX   75'B?/'%  HS ^a[D  N753$$!g`GA'SN;-!@<.:6(EA0#    ݹvoS41$$ 85($##!xZ!62& :6) B=-3+:l#!|}/,!%3/#d]E~gp0-!7HC3   GSldK{s%Z#!LG5 )&,( [T?nfL;7)[T?85''&+))&f1."+)`YB" .+ d]F {Ze+t~c [K\3C5#B_ IENDB`lightspark-0.7.2/media/lightspark-ico-48x48.png000066400000000000000000000223121212105246600211710ustar00rootroot00000000000000PNG  IHDR00WgAMA abKGD pHYs B(xtIME '%v. IDATh0$ (K@4dUb;;* y(9><-jeKfZ xsT[{xrVezz     dbI)&jq     :<,B=.TB+);:+&$ &) GB04})) 76(<9* 99+20#3cbg }_&%b]G |4nul""wrT%z (&''px  t&Pii    g]     UY%$f`H" @=-@=-X #zsV " @=-; > ~@<-7,~vYPL9" +(^XBVP<VP< (%#,)<8)c\E    mfL(%  -h`HyqT-* 2/" /,!yD?/|qjO CP}al&$ C>.WQ< H%#>:+m|'#1."mfKtkQt}EB1+)7j !GC2WQ=ء ;7)    y'$l}tW JG55; +GB1~ !}uWMG5>:+~vW \V@zrU:6([U? @=-2/#LF4TM:,(a[D 63&PJ7RL9 Zeɻ+'2/#PK8LH5w)& z[d (%C?/mfL   51%a[D 40%aZC51$/, /,! WQ<-)R_[f[fB7i/,!A<-{jKp;IDAT4{TJ( B&NIENDB`lightspark-0.7.2/media/lightspark-ico-64x64.png000066400000000000000000000403461212105246600211740ustar00rootroot00000000000000PNG  IHDR@@iqgAMA abKGD pHYs B(xtIME 'u IDATx@@*(" BJA.!1(: m !0-#OK7 sF%&ohN'&u~{QO<YU>h HVR=JH5G7ytWG0uy LJ8>;,AB|      `[C:a (& icKA]{~21$KH6 b]Fy# ko/-! 63'<9*;9+OJ7DJcipkO/-"D@0(&/Q|.+" 74()-+ajeLP)"!'&'%      nw}]ii    n+6O^., ZU?uoS\UfbI@<-ZU?G !TQ<A=. =@=9,A=->:,B77)74'{sV'&#!#!MI6  ogM  " TM;'%:7(      '%$! A IDAT  aZC84&^WB=8*74& 62&qhO0-"0-"<7*.,  LYLG4KF4,)q-;mvnRvnRǻ%!7#!b[DumQ%!7,)|\b[D ];7)OJ7|sV -* 95(   D?/JE3|OJ7Wb        ՟aXR=   2-"@meoGTYdjcJ2/#95(YS=cm@=-51$s|jcJ96( ldK  kdK2.#B=.'$ '#Zf r{-*84')'NJ6/+  t:6(hrQ]\h&#phNkdK ZT>[U?ibI,)OI7.+ c\DCP} mfLxZ mfL~uWb\DEA0b+=9+,)q{  MH5b[D3/#?:,s}GC2s}(%w@M{TN:!z_$! -*KF4n )&HD3;8*tlP@<--*umQRM9+'(&?;, GB1*(s?Lz?Lz=Jx|,)30#c`rkP@$IHW$ P(} 0E_tZm %3>+'% DA|JKIDAT+urIENDB`lightspark-0.7.2/media/lightspark-ico-72x72.png000066400000000000000000000507561212105246600212000ustar00rootroot00000000000000PNG  IHDRHHUGgAMA abKGD pHYs B(xtIME %+|a IDATxHQ @C0'w9:a=h] +)ZT?iYd^F><-vf76(tpSW2.."smRR"$YW?@=.^$  xrVh   njPR-w|    [XB&$DQms'%.." IH5/-"0lQsy LI787)  H+,* 74(<9*:8*hcK v> $"fcJ/,!yrU*]ekNK4icNa\ESaR<a{      z#[d!fbIIF3hbJ##D@14J# 1/#1.#1.# n^ R LA>. 20#<9* QKSO;VQ=0-"JF5~20# SB53&YT??BJt IDATC?/'&B>. 1 =)!D@0  '&3/#;8);8)LH5(&)&a[DxY  %,),)(&UQ<   \U@2/#,)!        2/#2.#    RM9z\@<-2/# :6)NI7!!=9*  QK8} }]cm}!*&j {sUHC2,'$!zZf_GxF@.3/#e@<,{$#;8) nfMf_FO84( 0-!JE4=8*A=-o[f    '% ?TO:     : g`k:Gv)7k9GvN[&4h'6i3ArKX^i;,:7) 62%FB1\a[DVQ<vW<b\D@<,B=- umRcnHC2 TM:kuB=.85'ogMy=9+ lX=8*;7)1."vb]V@&#D?/63&TO;GA1_ZC;8*~uV@<- A>-(%2/#!%#62%D?/",a{t~ /d%3g SIDAT5UGC20=p<8*JE3oBN_Ta?(U%Hy ~~+ [{FCB('  } IENDB`lightspark-0.7.2/media/lightspark-ico-96x96.png000066400000000000000000001104431212105246600212020ustar00rootroot00000000000000PNG  IHDR``w8gAMA abKGD pHYs B(xtIME $0* IDATx* &   =B1&#\F6fOm w s}   "!?;+'&qB(;:*\XAml31%liMp%3 UQ<UQ=hRLH7ZWARjc`H;8)N~ ztV WoNK:B?.]x} rmQRios{wX BXntsmQ =( ty,,   hdK6 -lqU&o IDAT&$JH4/-"mgO cfkp86(IE4,* *(vrU]L`h 0/" =;,KH6*(ysV( !u{ .,!gbI$#c^FW|PM9faI34'62&F%fl%#glgN .dk        '_"Wgo wv><-?<-?<->;, y  #Wa%${uW_g\WA B=-y_ +;] ]4* !76(Vn\LH6LH6 ! MM {]^YC  WR=eL"e`G(&!AB;8+-* '%!$A*'C?/LH6A89"|uXID3 &# ]XB]XB(&rlPe- IDATP B=.  $ XR>kdK % 0,!0-"'$3/#>;,?/ >9+=9+<7)"      KE4          0-"    !B>.<9*VO<:6(95(;7) JE4C>/,),)!'$  ;7*PJ8ZT@ ?LzYS>ID2TO;)&r|||(&)&_&# r .* "  q*'*(s1."y0-!=9*k;8)vXWQ<EA/G;7)*'_YB[T?`YC84' &#84'?;,+(  HB2  /W #!=:+Q\g             Ķ(&sUER~ N|8 IDATFr|Uar|{_j;jcJKF4TO;62%2/#JE340$(&jbJ#!62&3/#1-" :6) $"]WA ZfTO;phM{sVdn62%,)#!jbIz[s| ҜxYkdKR_v$#[8FuLXR^,:l=Jx)`z$\fq/=n#[KW(_~#[,a[f)8j#[=Jx*`KWFR~;Hw,aGSb[C e^F>:+A<- yqUIE3C>.(7jMY52%D@0 umQmfL -* PJ8B=.D@0    vĒ~^  ylC>.KF4tlQwoSYS>NYLG5WQ<52%;Hw(%0-!EA0WQ<%#)&{sVvKF4 leKlhumQ !w !oxoyzrU+(A<-kdK{e{[ )&OI7`YCC>.m =Jx4BrKWXdUZe Ual_%\#[+`^i*'xbCQK8 7j&T>VB_IvtmZ4!Zt-pIDAT2vE9lHkN^D }f BBB'&'"  o܃2IENDB`lightspark-0.7.2/media/lightspark-ico.svg000066400000000000000000000355601212105246600204200ustar00rootroot00000000000000 lightspark-0.7.2/media/lightspark-logo.svg000066400000000000000000000544551212105246600206120ustar00rootroot00000000000000 lightspark-0.7.2/media/lightspark.desktop000066400000000000000000000004001212105246600205030ustar00rootroot00000000000000[Desktop Entry] Name=Lightspark Comment=An alternative flash player TryExec=lightspark Exec=lightspark Icon=lightspark NoDisplay=true Type=Application Categories=GNOME;GTK;AudioVideo;Video;Player; MimeType=application/x-shockwave-flash; StartupNotify=true lightspark-0.7.2/resources/000077500000000000000000000000001212105246600157015ustar00rootroot00000000000000lightspark-0.7.2/resources/ErrorConstants.xml000066400000000000000000001125411212105246600214150ustar00rootroot00000000000000 This table contains all of the error messages generated by core avmplus. This will likely be replaced by a resource table for easy localization. %o = ScriptObject* %t = Traits* %m = MethodInfo* %n = Multiname (name portion only) %N = Multiname (namespace portion only) %a = Atom %d = int %f = double %S = Stringp %s = char* The system is out of memory. The method %1 is not implemented. Number.toPrecision has a range of 1 to 21. Number.toFixed and Number.toExponential have a range of 0 to 20. Specified value is not within expected range. precision argument. Number.toPrecision has a range of 1 to 21. Number.toFixed and Number.toExponential have a range of 0 to 20. ]]> The radix argument must be between 2 and 36; got %1. radix argument of a method or property. Pass a value between 2 and 36 as a radix argument. ]]> Method %1 was invoked on an incompatible object. Array index is not a positive integer (%1). %1 is not a function. big instead of blg):
var blg:String = "foo";
var big:Sprite = new Sprite();
var error:int = big.length(); 
]]>
Instantiation attempted on a non-constructor. %1 is ambiguous; Found more than one matching binding. Cannot access a property or method of a null object reference. null can have no properties. This error can occur in some unexpected (though valid) situations. For example, consider the following code, which creates a Sprite object. Because this Sprite object is never added to the display list (through the addChild() method of a DisplayObjectContainer object), its stage property is set to null. Thus, the example generates this error because Sprite object's stage property cannot have any properties:
import flash.display.Sprite;
var sprite1:Sprite = new Sprite();
var q:String = sprite1.stage.quality;
]]>
A term is undefined and has no properties. var obj:Object = new Object(); obj.a = "foo"; trace(obj.b.prop);

You can also see this error because of a misspelling, for example in the following, where mc represents a MovieClip object in the display list, and the stage property is misspelled with a capital S (it should be stage):

trace(mc.Stage.quality);
]]>
Method %1 contained illegal opcode %2 at offset %3. note at the bottom of this table.* ]]> The last instruction exceeded code size. note at the bottom of this table.* ]]> Cannot call OP_findproperty when scopeDepth is 0. note at the bottom of this table.* ]]> Class %1 could not be found. Method %1 cannot set default xml namespace note at the bottom of this table.* ]]> Descendants operator (..) not supported on type %1. Scope stack overflow occurred. note at the bottom of this table.* ]]> Scope stack underflow occurred. note at the bottom of this table.* ]]> Getscopeobject %1 is out of bounds. note at the bottom of this table.* ]]> Code cannot fall off the end of a method. note at the bottom of this table.* ]]> At least one branch target was not on a valid instruction in the method. note at the bottom of this table.* ]]> Type void may only be used as a function return type. note at the bottom of this table.* ]]> Stack overflow occurred. note at the bottom of this table.* ]]> Stack underflow occurred. note at the bottom of this table.* ]]> An invalid register %1 was accessed. note at the bottom of this table.* ]]> Slot %1 exceeds slotCount=%2 of %3. note at the bottom of this table.* ]]> Method_info %1 exceeds method_count=%2. note at the bottom of this table.* ]]> Disp_id %1 exceeds max_disp_id=%2 of %3. note at the bottom of this table.* ]]> Disp_id %1 is undefined on %2. note at the bottom of this table.* ]]> Stack depth is unbalanced. %1 != %2. note at the bottom of this table.* ]]> Scope depth is unbalanced. %1 != %2. note at the bottom of this table.* ]]> Cpool index %1 is out of range %2. note at the bottom of this table.* ]]> Cpool entry %1 is wrong type. note at the bottom of this table.* ]]> Type Coercion failed: cannot convert %1 to %2. Illegal super expression found in method %1. note at the bottom of this table.* ]]> Cannot assign to a method %1 on %2. note at the bottom of this table.* ]]> %1 is already defined. for loops in the same function definition) are considered to be in the same scope. See the note at the bottom of this table.* ]]> Cannot verify method until it is referenced. note at the bottom of this table.* ]]> The right-hand side of instanceof must be a class or function. instanceof operator must be a class or function. ]]> The right-hand side of operator must be a class. is operator must be a class. ]]> Not an ABC file. major_version=%1 minor_version=%2. Invalid code_length=%1. note at the bottom of this table.* ]]> MethodInfo-%1 unsupported flags=%2. note at the bottom of this table.* ]]> Unsupported traits kind=%1. note at the bottom of this table.* ]]> MethodInfo-%1 referenced before definition. note at the bottom of this table.* ]]> No entry point was found. note at the bottom of this table.* ]]> Prototype objects must be vanilla Objects. note at the bottom of this table.* ]]> Cannot convert %1 to primitive. note at the bottom of this table.* ]]> Illegal early binding access to %1. note at the bottom of this table.* ]]> Invalid URI passed to %1 function. note at the bottom of this table.* ]]> Illegal override of %1 in %2. note at the bottom of this table.* ]]> Illegal range or target offsets in exception handler. note at the bottom of this table.* ]]> Cannot create property %1 on %2. %1 can only contain methods. note at the bottom of this table.* ]]> Illegal operand type: %1 must be %2. note at the bottom of this table.* ]]> ClassInfo-%1 is referenced before definition. note at the bottom of this table.* ]]> ClassInfo %1 exceeds class_count=%2. note at the bottom of this table.* ]]> The value %1 cannot be converted to %2 without losing precision. This error also appears for out-of-range assignments, such as the following:

var m0:int = 2147483648; // int.MAX_VALUE == 2147483647

You can also see this error when using the bitwise left shift operator (<<). For example, consider the following code:

var m0:uint = 0xFF;
var m1:uint = m0<<24;

The result of left shift operator (<<) is interpreted as a 32-bit two's complement number with sign. In the example, the result is a negative value, which causes the error when assigned to the uint typed property. A workaround is the following:

var m0:uint = 0xFF;
var m1:uint = uint(m0<<24);
]]>
Argument count mismatch on %1. Expected %2, got %3. Cannot call method %1 as constructor. f() in Class A:
class A {
       function f() {}
    }
In the following code, extracting the function causes no error. However, creating a new instance of the function causes an error.
var a = new A()
    var m = a.f // extract f, don't call it
    m() // same as a.f()
    new m() // causes this error
]]>
Variable %1 is not defined. trace(x) generates an error because x is undefined. However, the statement trace(y) doesn't generate an error because y is defined:
trace("hello world")
    trace(x) // x is undefined
    var y
    trace(y) // No error, y is defined.
]]>
The form function('function body') is not supported. eval() and function(). Thus, calling these as a constructor in ActionScript 3.0 generates this error. ]]> Native method %1 has illegal method body. note at the bottom of this table.* ]]> %1 and %2 cannot be reconciled. note at the bottom of this table.* ]]> Property %1 not found on %2 and there is no default value. x, which is not defined and cannot be created dynamically:
class A {} // sealed class, not dynamic
    trace(new A().x) // no property x defined on A, and A is not dynamic
]]>
Method %1 not found on %2 super statement to call a function, but the function doesn't exist in the super class. For example, the following code generates the error:
class A() {}
class B extends A {
  function f() { trace(super.f()); } // error 1070, there is no f on A
}
]]>
Function %1 has already been bound to %2. Disp_id 0 is illegal. note at the bottom of this table.* ]]> Non-override method %1 replaced because of duplicate disp_id %2. note at the bottom of this table.* ]]> Illegal write to read-only property %1 on %2. Math is not a function. math() as a function, but the Math class is a class with static methods. ]]> Math is not a constructor. Illegal read of write-only property %1 on %2. Illegal opcode/multiname combination: %1<%2>. note at the bottom of this table.* ]]> Native methods are not allowed in loaded code. note at the bottom of this table.* ]]> Illegal value for namespace. note at the bottom of this table.* ]]> Property %1 not found on %2 and there is no default value. No default namespace has been set. note at the bottom of this table.* ]]> The prefix "%1" for element "%2" is not bound. foo namespace to match foo:x:
<foo:x xmlns:clowns='http://circuscenter.org'>
]]>
Element or attribute ("%1") does not match QName production: QName::=(NCName':')?NCName. foo: or :foo as an element or attribute name, but there is nothing on the other side of the colon. ]]> The element type "%1" must be terminated by the matching end-tag "</%2>". The %1 method only works on lists containing one item. addNamespace, appendChild, childIndex, inScopeNamespaces, insertChildAfter, insertChildBefore, name, namespace, localName, namespaceDeclarations, nodeKind, prependChild, removeNamespace, replace, setChildren, setLocalName, setName, and setNamespace. ]]> Assignment to indexed XML is not allowed. The markup in the document following the root element must be well-formed.
  • Parsing an XMLList style object as XML
  • Misbalanced strings
  • ]]>
    Assignment to lists with more than one item is not supported. XML parser failure: element is malformed. >
    is missing:
    <a/><b></b
    ]]> XML parser failure: Unterminated CDATA section. XML parser failure: Unterminated XML declaration. XML parser failure: Unterminated DOCTYPE declaration. XML parser failure: Unterminated comment. XML parser failure: Unterminated attribute. XML parser failure: Unterminated element. XML parser failure: Unterminated processing instruction. Illegal prefix %1 for no namespace. ns = new Namespace ("prefix", ""); ]]> Cannot supply flags when constructing one RegExp from another. new operator and set the flags as desired. For example, this statement creates a regular expression and specifies flag settings:
    var re:RegExp = new RegExp("ali", /s)
    Alternatively, this statement creates a regular expression that has the same flags as re:
    var re2:RegExp = new RegExp(re, ...)
    ]]>
    Cannot verify method %1 with unknown scope. note at the bottom of this table.* ]]> Illegal default value for type %1. note at the bottom of this table.* ]]> Class %1 cannot extend final base class. note at the bottom of this table.* ]]> Attribute "%1" was already specified for element "%2". The ABC data is corrupt, attempt to read out of bounds. note at the bottom of this table.* ]]> The OP_newclass opcode was used with the incorrect base class. note at the bottom of this table.* ]]> Attempt to directly call unbound function %1 from method %2. note at the bottom of this table.* ]]> %1 cannot extend %2. note at the bottom of this table.* ]]> %1 cannot implement %2. note at the bottom of this table.* ]]> Argument count mismatch on class coercion. Expected 1, got %1. OP_newactivation used in method without NEED_ACTIVATION flag. note at the bottom of this table.* ]]> OP_getglobalslot or OP_setglobalslot used with no global scope. note at the bottom of this table.* ]]> %1 is not a constructor. second argument to Function.prototype.apply must be an array. Invalid XML name: %1. Illegal cyclical loop between nodes. Delete operator is not supported with operand of type %1. Cannot delete property %1 on %2. Method %1 has a duplicate method body. Interface method %1 has illegal method body. Filter operator not supported on type %1. OP_hasnext2 requires object and index to be distinct registers. The index %1 is out of range %2. Cannot change the length of a fixed Vector. Type application attempted on a non-parameterized type. Incorrect number of type parameters for %1. Expected %2, got %3. Cyclic structure cannot be converted to JSON string. Replacer argument to JSON stringifier must be an array or a two parameter function. Invalid JSON parse input. A script has executed for longer than the default timeout period of 15 seconds. A script failed to exit after 30 seconds and was terminated. Argument %1 cannot be null. The value specified for argument %1 is invalid. public function doSomething(const:int):void { } this ["doSomething"] ("str") generates an error at runtime because doSomething is cast as an int data type. ]]> When the callback argument is a method of a class, the optional this argument must be null. Worker is already started. Starting a worker that already failed is not supported. Worker has terminated." unlock() with no preceding matching lock(). Invalid condition timeout value: %1. Condition cannot notify if associated mutex is not owned. Condition cannot notifyAll if associated mutex is not owned. Condition cannot wait if associated mutex is not owned. Condition cannot be initialized. Mutex cannot be initialized. Only the worker's parent may call start. One of the parameters is invalid. The supplied index is out of bounds. Parameter %1 must be non-null. Parameter %1 must be one of the accepted values. %1 class cannot be instantiated. End of file was encountered. There was an error decompressing the data. Parameter %1 must be non-empty string. The Proxy class does not implement getProperty. It must be overridden by a subclass. The Proxy class does not implement setProperty. It must be overridden by a subclass. The Proxy class does not implement callProperty. It must be overridden by a subclass. The Proxy class does not implement hasProperty. It must be overridden by a subclass. The Proxy class does not implement deleteProperty. It must be overridden by a subclass. The Proxy class does not implement getDescendants. It must be overridden by a subclass. The Proxy class does not implement nextNameIndex. It must be overridden by a subclass. The Proxy class does not implement nextName. It must be overridden by a subclass. The Proxy class does not implement nextValue. It must be overridden by a subclass. The value %1 is not a valid Array length. Unable to read object in stream. The class %1 does not implement flash.utils.IExternalizable but is aliased to an externalizable class.
    lightspark-0.7.2/src/000077500000000000000000000000001212105246600144565ustar00rootroot00000000000000lightspark-0.7.2/src/CMakeLists.txt000066400000000000000000000160031212105246600172160ustar00rootroot00000000000000#************************************************************************** # Lightspark, a free flash player implementation # # Copyright (C) 2010-2013 Alessandro Pignotti # Copyright (C) 2010 Giacomo Spigler # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . #************************************************************************** # liblightspark.so sources SET(LIBSPARK_SOURCES allclasses.cpp asobject.cpp compat.cpp logger.cpp memory_support.cpp swf.cpp swftypes.cpp thread_pool.cpp threading.cpp timer.cpp tiny_string.cpp errorconstants.cpp backends/audio.cpp backends/builtindecoder.cpp backends/config.cpp backends/decoder.cpp backends/extscriptobject.cpp backends/geometry.cpp backends/graphics.cpp backends/image.cpp backends/input.cpp backends/netutils.cpp backends/pluginmanager.cpp backends/rendering.cpp backends/rendering_context.cpp backends/rtmputils.cpp backends/security.cpp backends/urlutils.cpp backends/xml_support.cpp parsing/amf3_generator.cpp parsing/config.cpp parsing/crossdomainpolicy.cpp parsing/flv.cpp parsing/streams.cpp parsing/tags.cpp parsing/tags_stub.cpp parsing/textfile.cpp scripting/abc.cpp scripting/abc_codesynt.cpp scripting/abc_fast_interpreter.cpp scripting/abc_interpreter.cpp scripting/abc_optimizer.cpp scripting/abc_opcodes.cpp scripting/abctypes.cpp scripting/flash/accessibility/flashaccessibility.cpp scripting/flash/desktop/flashdesktop.cpp scripting/flash/display/BitmapContainer.cpp scripting/flash/display/BitmapData.cpp scripting/flash/display/DisplayObject.cpp scripting/flash/display/IBitmapDrawable.cpp scripting/flash/display/flashdisplay.cpp scripting/flash/display/TokenContainer.cpp scripting/flash/events/flashevents.cpp scripting/flash/external/ExternalInterface.cpp scripting/flash/filters/flashfilters.cpp scripting/flash/geom/flashgeom.cpp scripting/flash/media/flashmedia.cpp scripting/flash/net/flashnet.cpp scripting/flash/net/URLRequestHeader.cpp scripting/flash/net/URLStream.cpp scripting/flash/net/XMLSocket.cpp scripting/flash/errors/flasherrors.cpp scripting/flash/sensors/flashsensors.cpp scripting/flash/system/flashsystem.cpp scripting/flash/text/flashtext.cpp scripting/flash/text/flashtextengine.cpp scripting/flash/utils/flashutils.cpp scripting/flash/ui/Keyboard.cpp scripting/flash/xml/flashxml.cpp scripting/toplevel/Array.cpp scripting/toplevel/ASString.cpp scripting/toplevel/Boolean.cpp scripting/toplevel/Date.cpp scripting/toplevel/Error.cpp scripting/toplevel/Integer.cpp scripting/toplevel/Math.cpp scripting/toplevel/Number.cpp scripting/toplevel/RegExp.cpp scripting/toplevel/UInteger.cpp scripting/toplevel/Vector.cpp scripting/toplevel/XML.cpp scripting/toplevel/XMLList.cpp scripting/class.cpp scripting/toplevel/toplevel.cpp platforms/engineutils.cpp) IF(MINGW) SET(LIBSPARK_SOURCES ${LIBSPARK_SOURCES} platforms/slowpaths_generic.cpp) ELSE() IF(${i386}) SET(LIBSPARK_SOURCES ${LIBSPARK_SOURCES} platforms/fastpaths_x86.cpp) SET(LIBSPARK_SOURCES ${LIBSPARK_SOURCES} platforms/fastpaths_i686.asm) ELSEIF(${x86_64}) SET(LIBSPARK_SOURCES ${LIBSPARK_SOURCES} platforms/fastpaths_x86.cpp) SET(LIBSPARK_SOURCES ${LIBSPARK_SOURCES} platforms/fastpaths_amd64.asm) ELSE() SET(LIBSPARK_SOURCES ${LIBSPARK_SOURCES} platforms/slowpaths_generic.cpp) ENDIF(${i386}) ENDIF(MINGW) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/scripting) # liblightspark.so target IF(CMAKE_COMPILER_IS_GNUCC) ADD_LIBRARY(spark SHARED ${LIBSPARK_SOURCES}) IF(NOT WIN32) #win32's cmake doesn't like liblightspark and lightspark.exe having the same name SET_TARGET_PROPERTIES(spark PROPERTIES OUTPUT_NAME lightspark) ENDIF() IF(MINGW) SET_TARGET_PROPERTIES(spark PROPERTIES LINK_FLAGS "-Wl,--export-all-symbols") ELSE() SET_TARGET_PROPERTIES(spark PROPERTIES LINK_FLAGS "-Wl,--version-script=${PROJECT_SOURCE_DIR}/src/lightspark.expmap") ENDIF() SET_TARGET_PROPERTIES(spark PROPERTIES LINK_INTERFACE_LIBRARIES "") ELSE (CMAKE_COMPILER_IS_GNUCC) ADD_LIBRARY(spark STATIC ${LIBSPARK_SOURCES}) ENDIF (CMAKE_COMPILER_IS_GNUCC) TARGET_LINK_LIBRARIES(spark ${CAIRO_LIBRARIES} ${ZLIB_LIBRARIES} ${Boost_LIBRARIES} ${LLVM_LIBS_CORE} ${LLVM_LIBS_JIT} ${LLVM_LDFLAGS} ${OPTIONAL_LIBRARIES} ${GTK_LIBRARIES} ${FREETYPE_LIBRARIES} ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${PCRE_LIBRARIES} ${GLIBMM_LIBRARIES} ${GMODULE_LIBRARIES} ${XMLPP_LIBRARIES} ${CMAKE_DL_LIBS} ${EXTRA_LIBS_LIBRARIES} ${X11_LIBRARIES}) SET_TARGET_PROPERTIES(spark PROPERTIES VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}") SET_TARGET_PROPERTIES(spark PROPERTIES SOVERSION "${MAJOR_VERSION}.${MINOR_VERSION}") IF(ENABLE_GLES2) TARGET_LINK_LIBRARIES(spark ${GLES2_LIBRARIES}) ELSE() TARGET_LINK_LIBRARIES(spark ${OPENGL_LIBRARIES} ${GLEW_LIBRARIES}) ENDIF(ENABLE_GLES2) PACK_LIBRARY(spark) #We have to use LIBRARY on linux and RUNTIME on win32 INSTALL(TARGETS spark RUNTIME DESTINATION ${PRIVATELIBDIR} LIBRARY DESTINATION ${PRIVATELIBDIR}) # lightspark executable target IF(COMPILE_LIGHTSPARK) ADD_EXECUTABLE(lightspark main.cpp) TARGET_LINK_LIBRARIES(lightspark spark) #With STATICDEPS, all deps are compiled into spark IF(NOT STATICDEPS) TARGET_LINK_LIBRARIES(lightspark ${Boost_LIBRARIES} ${X11_LIBRARIES} ${GTK_LIBRARIES} ${GLIBMM_LIBRARIES} ${GTHREAD_LIBRARIES}) ENDIF() PACK_EXECUTABLE(lightspark) INSTALL(FILES ${PROJECT_SOURCE_DIR}/src/lightspark.frag DESTINATION ${LSDATADIR}) INSTALL(FILES ${PROJECT_SOURCE_DIR}/src/lightspark.vert DESTINATION ${LSDATADIR}) INSTALL(TARGETS lightspark RUNTIME DESTINATION ${BINDIR}) IF(UNIX) INSTALL(FILES ${PROJECT_SOURCE_DIR}/docs/man/lightspark.1 DESTINATION share/man/man1) ENDIF(UNIX) ENDIF(COMPILE_LIGHTSPARK) # tightspark executable target IF(COMPILE_TIGHTSPARK) ADD_EXECUTABLE(tightspark tightspark.cpp) TARGET_LINK_LIBRARIES(tightspark spark) #With STATICDEPS, all deps are compiled into spark IF(NOT STATICDEPS) TARGET_LINK_LIBRARIES(tightspark ${Boost_LIBRARIES} ${GLIBMM_LIBRARIES} ${GTHREAD_LIBRARIES}) ENDIF() INSTALL(TARGETS tightspark RUNTIME DESTINATION ${BINDIR}) PACK_EXECUTABLE(tightspark) ENDIF(COMPILE_TIGHTSPARK) # Browser plugin IF(COMPILE_PLUGIN) ADD_SUBDIRECTORY(plugin) ENDIF(COMPILE_PLUGIN) ADD_SUBDIRECTORY(backends/interfaces) lightspark-0.7.2/src/allclasses.cpp000066400000000000000000000067451212105246600173240ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2012-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "scripting/toplevel/ASString.h" #include "scripting/toplevel/Date.h" #include "scripting/toplevel/Math.h" #include "scripting/toplevel/RegExp.h" #include "scripting/toplevel/Vector.h" #include "scripting/toplevel/XML.h" #include "scripting/toplevel/XMLList.h" #include "scripting/flash/accessibility/flashaccessibility.h" #include "scripting/flash/desktop/flashdesktop.h" #include "scripting/flash/display/flashdisplay.h" #include "scripting/flash/display/BitmapData.h" #include "scripting/flash/events/flashevents.h" #include "scripting/flash/filters/flashfilters.h" #include "scripting/flash/net/flashnet.h" #include "scripting/flash/net/URLRequestHeader.h" #include "scripting/flash/net/URLStream.h" #include "scripting/flash/net/XMLSocket.h" #include "scripting/flash/system/flashsystem.h" #include "scripting/flash/sensors/flashsensors.h" #include "scripting/flash/utils/flashutils.h" #include "scripting/flash/geom/flashgeom.h" #include "scripting/flash/external/ExternalInterface.h" #include "scripting/flash/media/flashmedia.h" #include "scripting/flash/xml/flashxml.h" #include "scripting/flash/errors/flasherrors.h" #include "scripting/flash/text/flashtext.h" #include "scripting/flash/text/flashtextengine.h" #include "scripting/flash/ui/Keyboard.h" using namespace lightspark; //Orrible preprocessor hack: //We need to assign a unique, progressive ID to each actionscript class //The idea is to write the info about all classes in allclasses.h //The file will be included twice with different definitions of REGISTER_CLASS_NAME and REGISTER_CLASS_NAME2 //The first time an enumeration will be build, the second time it will be used to assign the values //Phase 1: build an enumeration #define REGISTER_CLASS_NAME(TYPE, NS) \ CLASS_##TYPE, #define REGISTER_CLASS_NAME2(TYPE,NAME,NS) \ CLASS_##TYPE, enum ASClassIds { //Leave a space for the special Class class CLASS_CLASS=0, #include "allclasses.h" CLASS_LAST }; #undef REGISTER_CLASS_NAME #undef REGISTER_CLASS_NAME2 //Phase 2: use the enumeratio to assign unique ids #define REGISTER_CLASS_NAME(TYPE, NS) \ template<> const char* ClassName::name = #TYPE; \ template<> const char* ClassName::ns = NS; \ template<> unsigned ClassName::id = CLASS_##TYPE; #define REGISTER_CLASS_NAME2(TYPE,NAME,NS) \ template<> const char* ClassName::name = NAME; \ template<> const char* ClassName::ns = NS; \ template<> unsigned int ClassName::id = CLASS_##TYPE; #include "allclasses.h" //Define a variable to let outside code know the number of defined classes uint32_t asClassCount = CLASS_LAST; lightspark-0.7.2/src/allclasses.h000066400000000000000000000213711212105246600167610ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2012-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ //DO NOT ADD INCLUDE GUARD HERE! This needs to be included twice in allclasses.cpp REGISTER_CLASS_NAME(Array,"") REGISTER_CLASS_NAME2(ASObject,"Object","") REGISTER_CLASS_NAME2(ASQName,"QName","") REGISTER_CLASS_NAME2(ASString, "String", "") REGISTER_CLASS_NAME(Boolean,"") REGISTER_CLASS_NAME(Date,"") REGISTER_CLASS_NAME2(Global,"global","") REGISTER_CLASS_NAME2(IFunction,"Function","") REGISTER_CLASS_NAME2(Integer,"int","") REGISTER_CLASS_NAME(Math,"") REGISTER_CLASS_NAME(Namespace,"") REGISTER_CLASS_NAME(Number,"") REGISTER_CLASS_NAME(RegExp,"") REGISTER_CLASS_NAME2(UInteger,"uint","") REGISTER_CLASS_NAME2(ASError, "Error", "") REGISTER_CLASS_NAME(SecurityError,"") REGISTER_CLASS_NAME(ArgumentError,"") REGISTER_CLASS_NAME(DefinitionError,"") REGISTER_CLASS_NAME(EvalError,"") REGISTER_CLASS_NAME(RangeError,"") REGISTER_CLASS_NAME(ReferenceError,"") REGISTER_CLASS_NAME(SyntaxError,"") REGISTER_CLASS_NAME(TypeError,"") REGISTER_CLASS_NAME(URIError,"") REGISTER_CLASS_NAME(VerifyError,"") REGISTER_CLASS_NAME(UninitializedError,"") REGISTER_CLASS_NAME(XML,"") REGISTER_CLASS_NAME(XMLList,"") //Vectors REGISTER_CLASS_NAME(Vector,"__AS3__.vec") //Accessibility REGISTER_CLASS_NAME(AccessibilityProperties,"flash.accessibility") REGISTER_CLASS_NAME(AccessibilityImplementation,"flash.accessibility") //Desktop (AIR) REGISTER_CLASS_NAME(NativeApplication,"flash.desktop") //Display REGISTER_CLASS_NAME(AVM1Movie,"flash.display") REGISTER_CLASS_NAME(Bitmap,"flash.display") REGISTER_CLASS_NAME(BitmapData,"flash.display") REGISTER_CLASS_NAME(BitmapDataChannel,"flash.display") REGISTER_CLASS_NAME(BlendMode,"flash.display") REGISTER_CLASS_NAME(DisplayObject,"flash.display") REGISTER_CLASS_NAME(DisplayObjectContainer,"flash.display") REGISTER_CLASS_NAME(FrameLabel,"flash.display") REGISTER_CLASS_NAME(GradientType,"flash.display") REGISTER_CLASS_NAME(Graphics,"flash.display") REGISTER_CLASS_NAME(IBitmapDrawable,"flash.display") REGISTER_CLASS_NAME(InteractiveObject,"flash.display") REGISTER_CLASS_NAME(InterpolationMethod,"flash.display") REGISTER_CLASS_NAME(LineScaleMode,"flash.display") REGISTER_CLASS_NAME(Loader,"flash.display") REGISTER_CLASS_NAME(LoaderInfo,"flash.display") REGISTER_CLASS_NAME(MorphShape,"flash.display") REGISTER_CLASS_NAME(MovieClip,"flash.display") REGISTER_CLASS_NAME(Scene,"flash.display") REGISTER_CLASS_NAME(Shader,"flash.display") REGISTER_CLASS_NAME(Shape,"flash.display") REGISTER_CLASS_NAME(SimpleButton,"flash.display") REGISTER_CLASS_NAME(SpreadMethod,"flash.display") REGISTER_CLASS_NAME(Sprite,"flash.display") REGISTER_CLASS_NAME(Stage,"flash.display") REGISTER_CLASS_NAME(StageAlign,"flash.display") REGISTER_CLASS_NAME(StageDisplayState,"flash.display") REGISTER_CLASS_NAME(StageScaleMode,"flash.display") REGISTER_CLASS_NAME(StageQuality,"flash.display") //Events REGISTER_CLASS_NAME(AsyncErrorEvent,"flash.events") REGISTER_CLASS_NAME(DRMErrorEvent,"flash.events") REGISTER_CLASS_NAME(DRMStatusEvent,"flash.events") REGISTER_CLASS_NAME(DataEvent,"flash.events") REGISTER_CLASS_NAME(ErrorEvent,"flash.events") REGISTER_CLASS_NAME(Event,"flash.events") REGISTER_CLASS_NAME(EventDispatcher,"flash.events") REGISTER_CLASS_NAME(EventPhase,"flash.events") REGISTER_CLASS_NAME(FocusEvent,"flash.events") REGISTER_CLASS_NAME(FullScreenEvent,"flash.events") REGISTER_CLASS_NAME(HTTPStatusEvent,"flash.events") REGISTER_CLASS_NAME(IEventDispatcher,"flash.events") REGISTER_CLASS_NAME(IOErrorEvent,"flash.events") REGISTER_CLASS_NAME(InvokeEvent,"flash.events") REGISTER_CLASS_NAME(KeyboardEvent,"flash.events") REGISTER_CLASS_NAME(MouseEvent,"flash.events") REGISTER_CLASS_NAME(NetStatusEvent,"flash.events") REGISTER_CLASS_NAME(ProgressEvent,"flash.events") REGISTER_CLASS_NAME(SecurityErrorEvent,"flash.events") REGISTER_CLASS_NAME(StageVideoEvent,"flash.events") REGISTER_CLASS_NAME(StageVideoAvailabilityEvent,"flash.events") REGISTER_CLASS_NAME(StatusEvent,"flash.events") REGISTER_CLASS_NAME(TextEvent,"flash.events") REGISTER_CLASS_NAME(TimerEvent,"flash.events") //External interface (browser interaction) REGISTER_CLASS_NAME(ExternalInterface,"flash.external") //Filters REGISTER_CLASS_NAME(BitmapFilter,"flash.filters") REGISTER_CLASS_NAME(DropShadowFilter,"flash.filters") REGISTER_CLASS_NAME(GlowFilter,"flash.filters") //Geom REGISTER_CLASS_NAME(ColorTransform,"flash.geom") REGISTER_CLASS_NAME(Matrix,"flash.geom") REGISTER_CLASS_NAME(Point,"flash.geom") REGISTER_CLASS_NAME2(Rectangle,"Rectangle","flash.geom") REGISTER_CLASS_NAME(Transform,"flash.geom") REGISTER_CLASS_NAME(Vector3D,"flash.geom") //Media REGISTER_CLASS_NAME(Sound,"flash.media") REGISTER_CLASS_NAME(SoundChannel,"flash.media") REGISTER_CLASS_NAME(SoundLoaderContext,"flash.media") REGISTER_CLASS_NAME(SoundTransform,"flash.media") REGISTER_CLASS_NAME(StageVideo,"flash.media") REGISTER_CLASS_NAME(StageVideoAvailability,"flash.media") REGISTER_CLASS_NAME(Video,"flash.media") REGISTER_CLASS_NAME(VideoStatus,"flash.media") //Net REGISTER_CLASS_NAME(NetConnection,"flash.net") REGISTER_CLASS_NAME(NetStream,"flash.net") REGISTER_CLASS_NAME(ObjectEncoding,"flash.net") REGISTER_CLASS_NAME(Responder,"flash.net") REGISTER_CLASS_NAME(SharedObject,"flash.net") REGISTER_CLASS_NAME(URLLoader,"flash.net") REGISTER_CLASS_NAME(URLLoaderDataFormat,"flash.net") REGISTER_CLASS_NAME(URLRequest,"flash.net") REGISTER_CLASS_NAME(URLRequestHeader,"flash.net") REGISTER_CLASS_NAME(URLRequestMethod,"flash.net") REGISTER_CLASS_NAME(URLStream,"flash.net") REGISTER_CLASS_NAME(URLVariables,"flash.net") REGISTER_CLASS_NAME(XMLSocket,"flash.net") //Errors REGISTER_CLASS_NAME(EOFError,"flash.errors") REGISTER_CLASS_NAME(IOError,"flash.errors") REGISTER_CLASS_NAME(IllegalOperationError,"flash.errors") REGISTER_CLASS_NAME(InvalidSWFError,"flash.errors") REGISTER_CLASS_NAME(MemoryError,"flash.errors") REGISTER_CLASS_NAME(ScriptTimeoutError,"flash.errors") REGISTER_CLASS_NAME(StackOverflowError,"flash.errors") //Sensors REGISTER_CLASS_NAME(Accelerometer,"flash.sensors") //System REGISTER_CLASS_NAME(ApplicationDomain,"flash.system") REGISTER_CLASS_NAME(Capabilities,"flash.system") REGISTER_CLASS_NAME(LoaderContext,"flash.system") REGISTER_CLASS_NAME(Security,"flash.system") REGISTER_CLASS_NAME(SecurityDomain,"flash.system") REGISTER_CLASS_NAME(System,"flash.system") //Text REGISTER_CLASS_NAME2(ASFont,"Font","flash.text") REGISTER_CLASS_NAME(AntiAliasType,"flash.text") REGISTER_CLASS_NAME(FontStyle,"flash.text") REGISTER_CLASS_NAME(FontType,"flash.text") REGISTER_CLASS_NAME(GridFitType,"flash.text") REGISTER_CLASS_NAME(TextColorType,"flash.text") REGISTER_CLASS_NAME(TextDisplayMode,"flash.text") REGISTER_CLASS_NAME(TextField,"flash.text") REGISTER_CLASS_NAME(TextFieldAutoSize,"flash.text") REGISTER_CLASS_NAME(TextFieldType,"flash.text") REGISTER_CLASS_NAME(TextFormat,"flash.text") REGISTER_CLASS_NAME(TextFormatAlign,"flash.text") REGISTER_CLASS_NAME(TextLineMetrics,"flash.text") REGISTER_CLASS_NAME(StaticText,"flash.text") REGISTER_CLASS_NAME(StyleSheet,"flash.text") //Text engine REGISTER_CLASS_NAME(ContentElement,"flash.text.engine") REGISTER_CLASS_NAME(ElementFormat,"flash.text.engine") REGISTER_CLASS_NAME(FontDescription,"flash.text.engine") REGISTER_CLASS_NAME(FontWeight,"flash.text.engine") REGISTER_CLASS_NAME(TextBlock,"flash.text.engine") REGISTER_CLASS_NAME(TextElement,"flash.text.engine") REGISTER_CLASS_NAME(TextLine,"flash.text.engine") //Utils REGISTER_CLASS_NAME(ByteArray,"flash.utils") REGISTER_CLASS_NAME(Dictionary,"flash.utils") REGISTER_CLASS_NAME(Endian,"flash.utils") REGISTER_CLASS_NAME(IDataInput,"flash.utils") REGISTER_CLASS_NAME(IDataOutput,"flash.utils") REGISTER_CLASS_NAME(IExternalizable,"flash.utils") REGISTER_CLASS_NAME(Proxy,"flash.utils") REGISTER_CLASS_NAME(Timer,"flash.utils") //UI REGISTER_CLASS_NAME(Keyboard,"flash.ui") REGISTER_CLASS_NAME(KeyboardType,"flash.ui") REGISTER_CLASS_NAME(KeyLocation,"flash.ui") //XML REGISTER_CLASS_NAME(XMLDocument,"flash.xml") REGISTER_CLASS_NAME(XMLNode,"flash.xml") lightspark-0.7.2/src/asobject.cpp000066400000000000000000001134751212105246600167670ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "scripting/abc.h" #include "asobject.h" #include "scripting/class.h" #include #include #include "compat.h" #include "parsing/amf3_generator.h" #include "scripting/toplevel/ASString.h" #include "scripting/toplevel/Date.h" #include "scripting/toplevel/XML.h" #include "scripting/toplevel/XMLList.h" #include "scripting/toplevel/Error.h" using namespace lightspark; using namespace std; string ASObject::toDebugString() { check(); string ret; if(getClass()) { ret="[object "; ret+=getClass()->class_name.name.raw_buf(); ret+="]"; } else if(this->is()) ret = "Undefined"; else if(this->is()) ret = "Null"; else if(this->is()) { ret = "[class "; ret+=this->as()->class_name.getQualifiedName().raw_buf(); ret+="]"; } else { assert(false); } return ret; } tiny_string ASObject::toString() { check(); switch(this->getObjectType()) { case T_UNDEFINED: return "undefined"; case T_NULL: return "null"; case T_BOOLEAN: return as()->val ? "true" : "false"; case T_NUMBER: return as()->toString(); case T_INTEGER: return as()->toString(); case T_UINTEGER: return as()->toString(); case T_STRING: return as()->data; default: //everything else is an Object regarding to the spec return toPrimitive(STRING_HINT)->toString(); } } TRISTATE ASObject::isLess(ASObject* r) { check(); return toPrimitive()->isLess(r); } int variables_map::getNextEnumerable(unsigned int start) const { if(start>=Variables.size()) return -1; const_var_iterator it=Variables.begin(); unsigned int i=0; while(isecond.kind!=DYNAMIC_TRAIT) { ++i; ++it; if(it==Variables.end()) return -1; } return i; } uint32_t ASObject::nextNameIndex(uint32_t cur_index) { // First -1 converts one-base cur_index to zero-based, +1 // moves to the next position (first position to be // considered). Final +1 converts back to one-based. return Variables.getNextEnumerable(cur_index-1+1)+1; } _R ASObject::nextName(uint32_t index) { assert_and_throw(implEnable); return _MR(Class::getInstanceS(getNameAt(index-1))); } _R ASObject::nextValue(uint32_t index) { assert_and_throw(implEnable); return getValueAt(index-1); } void ASObject::sinit(Class_base* c) { c->setDeclaredMethodByQName("hasOwnProperty",AS3,Class::getFunction(hasOwnProperty),NORMAL_METHOD,true); c->prototype->setVariableByQName("toString","",Class::getFunction(_toString),DYNAMIC_TRAIT); c->prototype->setVariableByQName("toLocaleString","",Class::getFunction(_toString),DYNAMIC_TRAIT); c->prototype->setVariableByQName("valueOf","",Class::getFunction(valueOf),DYNAMIC_TRAIT); c->prototype->setVariableByQName("hasOwnProperty","",Class::getFunction(hasOwnProperty),DYNAMIC_TRAIT); c->prototype->setVariableByQName("isPrototypeOf","",Class::getFunction(isPrototypeOf),DYNAMIC_TRAIT); c->prototype->setVariableByQName("propertyIsEnumerable","",Class::getFunction(propertyIsEnumerable),DYNAMIC_TRAIT); } void ASObject::buildTraits(ASObject* o) { } bool ASObject::isEqual(ASObject* r) { check(); //if we are comparing the same object the answer is true if(this==r) return true; switch(r->getObjectType()) { case T_NULL: case T_UNDEFINED: return false; case T_NUMBER: case T_INTEGER: case T_UINTEGER: case T_STRING: { _R primitive(toPrimitive()); return primitive->isEqual(r); } case T_BOOLEAN: { _R primitive(toPrimitive()); return primitive->toNumber()==r->toNumber(); } default: { XMLList *xl=dynamic_cast(r); if(xl) return xl->isEqual(this); XML *x=dynamic_cast(r); if(x && x->hasSimpleContent()) return x->toString()==toString(); } } LOG(LOG_CALLS,_("Equal comparison between type ")<getObjectType()); if(classdef) LOG(LOG_CALLS,_("Type ") << classdef->class_name); return false; } bool ASObject::isEqualStrict(ASObject* r) { return ABCVm::strictEqualImpl(this, r); } uint32_t ASObject::toUInt() { return toInt(); } uint16_t ASObject::toUInt16() { unsigned int val32=toUInt(); return val32 & 0xFFFF; } int32_t ASObject::toInt() { return 0; } /* Implements ECMA's ToPrimitive (9.1) and [[DefaultValue]] (8.6.2.6) */ _R ASObject::toPrimitive(TP_HINT hint) { //See ECMA 8.6.2.6 for default hint regarding Date if(hint == NO_HINT) { if(this->is()) hint = STRING_HINT; else hint = NUMBER_HINT; } if(isPrimitive()) { this->incRef(); return _MR(this); } /* for HINT_STRING evaluate first toString, then valueOf * for HINT_NUMBER do it the other way around */ if(hint == STRING_HINT && has_toString()) { _R ret = call_toString(); if(ret->isPrimitive()) return ret; } if(has_valueOf()) { _R ret = call_valueOf(); if(ret->isPrimitive()) return ret; } if(hint != STRING_HINT && has_toString()) { _R ret = call_toString(); if(ret->isPrimitive()) return ret; } throw Class::getInstanceS(); return _MR((ASObject*)NULL); } bool ASObject::has_valueOf() { multiname valueOfName(NULL); valueOfName.name_type=multiname::NAME_STRING; valueOfName.name_s_id=getSys()->getUniqueStringId("valueOf"); valueOfName.ns.push_back(nsNameAndKind("",NAMESPACE)); valueOfName.ns.push_back(nsNameAndKind(AS3,NAMESPACE)); valueOfName.isAttribute = false; return hasPropertyByMultiname(valueOfName, true, true); } /* calls the valueOf function on this object * we cannot just call the c-function, because it can be overriden from AS3 code */ _R ASObject::call_valueOf() { multiname valueOfName(NULL); valueOfName.name_type=multiname::NAME_STRING; valueOfName.name_s_id=getSys()->getUniqueStringId("valueOf"); valueOfName.ns.push_back(nsNameAndKind("",NAMESPACE)); valueOfName.ns.push_back(nsNameAndKind(AS3,NAMESPACE)); valueOfName.isAttribute = false; assert_and_throw(hasPropertyByMultiname(valueOfName, true, true)); _NR o=getVariableByMultiname(valueOfName,SKIP_IMPL); if (!o->is()) throwError(kCallOfNonFunctionError, valueOfName.normalizedName()); IFunction* f=o->as(); incRef(); ASObject *ret=f->call(this,NULL,0); return _MR(ret); } bool ASObject::has_toString() { multiname toStringName(NULL); toStringName.name_type=multiname::NAME_STRING; toStringName.name_s_id=getSys()->getUniqueStringId("toString"); toStringName.ns.push_back(nsNameAndKind("",NAMESPACE)); toStringName.ns.push_back(nsNameAndKind(AS3,NAMESPACE)); toStringName.isAttribute = false; return ASObject::hasPropertyByMultiname(toStringName, true, true); } /* calls the toString function on this object * we cannot just call the c-function, because it can be overriden from AS3 code */ _R ASObject::call_toString() { multiname toStringName(NULL); toStringName.name_type=multiname::NAME_STRING; toStringName.name_s_id=getSys()->getUniqueStringId("toString"); toStringName.ns.push_back(nsNameAndKind("",NAMESPACE)); toStringName.ns.push_back(nsNameAndKind(AS3,NAMESPACE)); toStringName.isAttribute = false; assert(ASObject::hasPropertyByMultiname(toStringName, true, true)); _NR o=getVariableByMultiname(toStringName,SKIP_IMPL); assert_and_throw(o->is()); IFunction* f=o->as(); incRef(); ASObject *ret=f->call(this,NULL,0); return _MR(ret); } bool ASObject::isPrimitive() const { // ECMA 3, section 4.3.2, T_INTEGER and T_UINTEGER are added // because they are special cases of Number return type==T_NUMBER || type ==T_UNDEFINED || type == T_NULL || type==T_STRING || type==T_BOOLEAN || type==T_INTEGER || type==T_UINTEGER; } variables_map::variables_map(MemoryAccount* m): Variables(std::less(), reporter_allocator(m)),slots_vars(m) { } variable* variables_map::findObjVar(uint32_t nameId, const nsNameAndKind& ns, TRAIT_KIND createKind, uint32_t traitKinds) { var_iterator ret=Variables.find(varName(nameId,ns)); if(ret!=Variables.end()) { if(!(ret->second.kind & traitKinds)) { assert(createKind==NO_CREATE_TRAIT); return NULL; } return &ret->second; } //Name not present, insert it if we have to create it if(createKind==NO_CREATE_TRAIT) return NULL; var_iterator inserted=Variables.insert(make_pair(varName(nameId, ns), variable(createKind)) ).first; return &inserted->second; } bool ASObject::hasPropertyByMultiname(const multiname& name, bool considerDynamic, bool considerPrototype) { //We look in all the object's levels uint32_t validTraits=DECLARED_TRAIT; if(considerDynamic) validTraits|=DYNAMIC_TRAIT; if(Variables.findObjVar(name, NO_CREATE_TRAIT, validTraits)!=NULL) return true; if(classdef && classdef->borrowedVariables.findObjVar(name, NO_CREATE_TRAIT, DECLARED_TRAIT)!=NULL) return true; //Check prototype inheritance chain if(getClass() && considerPrototype) { Prototype* proto = getClass()->prototype.getPtr(); while(proto) { if(proto->getObj()->findGettable(name) != NULL) return true; proto=proto->prevPrototype.getPtr(); } } //Must not ask for non borrowed traits as static class member are not valid return false; } void ASObject::setDeclaredMethodByQName(const tiny_string& name, const tiny_string& ns, IFunction* o, METHOD_TYPE type, bool isBorrowed) { setDeclaredMethodByQName(name, nsNameAndKind(ns, NAMESPACE), o, type, isBorrowed); } void ASObject::setDeclaredMethodByQName(const tiny_string& name, const nsNameAndKind& ns, IFunction* o, METHOD_TYPE type, bool isBorrowed) { setDeclaredMethodByQName(getSys()->getUniqueStringId(name), ns, o, type, isBorrowed); } void ASObject::setDeclaredMethodByQName(uint32_t nameId, const nsNameAndKind& ns, IFunction* o, METHOD_TYPE type, bool isBorrowed) { check(); #ifndef NDEBUG assert(!initialized); #endif //borrowed properties only make sense on class objects assert(!isBorrowed || dynamic_cast(this)); //use setVariableByQName(name,ns,o,DYNAMIC_TRAIT) on prototypes /* * Set the inClass property if not previously set. * This is used for builtin methods. Methods defined by AS3 code * get their inClass set in buildTrait. * It is necesarry to decide if o is a function or a method, * i.e. if a method closure should be created in getProperty. */ if(isBorrowed && o->inClass == NULL) o->inClass = this->as(); variable* obj=NULL; if(isBorrowed) { assert(this->is()); obj=this->as()->borrowedVariables.findObjVar(nameId,ns,DECLARED_TRAIT, DECLARED_TRAIT); } else obj=Variables.findObjVar(nameId,ns,DECLARED_TRAIT, DECLARED_TRAIT); switch(type) { case NORMAL_METHOD: { obj->setVar(o); break; } case GETTER_METHOD: { if(obj->getter!=NULL) obj->getter->decRef(); obj->getter=o; break; } case SETTER_METHOD: { if(obj->setter!=NULL) obj->setter->decRef(); obj->setter=o; break; } } } bool ASObject::deleteVariableByMultiname(const multiname& name) { variable* obj=Variables.findObjVar(name,NO_CREATE_TRAIT,DYNAMIC_TRAIT|DECLARED_TRAIT); if(obj==NULL) { if (classdef && classdef->isSealed) return false; // fixed properties cannot be deleted if (hasPropertyByMultiname(name,true,true)) return false; //unknown variables must return true return true; } //Only dynamic traits are deletable if (obj->kind != DYNAMIC_TRAIT) return false; assert(obj->getter==NULL && obj->setter==NULL && obj->var!=NULL); //Now dereference the value obj->var->decRef(); //Now kill the variable Variables.killObjVar(name); return true; } //In all setter we first pass the value to the interface to see if special handling is possible void ASObject::setVariableByMultiname_i(const multiname& name, int32_t value) { check(); setVariableByMultiname(name,abstract_i(value),CONST_NOT_ALLOWED); } variable* ASObject::findSettableImpl(variables_map& map, const multiname& name, bool* has_getter) { variable* ret=map.findObjVar(name,NO_CREATE_TRAIT,DECLARED_TRAIT|DYNAMIC_TRAIT); if(ret) { //It seems valid for a class to redefine only the getter, so if we can't find //something to get, it's ok if(!(ret->setter || ret->var)) { ret=NULL; if(has_getter) *has_getter=true; } } return ret; } variable* ASObject::findSettable(const multiname& name, bool* has_getter) { return findSettableImpl(Variables, name, has_getter); } void ASObject::setVariableByMultiname(const multiname& name, ASObject* o, CONST_ALLOWED_FLAG allowConst, Class_base* cls) { check(); assert(!cls || classdef->isSubClass(cls)); //NOTE: we assume that [gs]etSuper and [sg]etProperty correctly manipulate the cur_level (for getActualClass) bool has_getter=false; variable* obj=findSettable(name, &has_getter); if (obj && (obj->kind == CONSTANT_TRAIT && allowConst==CONST_NOT_ALLOWED)) { throwError(kConstWriteError, name.normalizedName(), classdef->as()->getQualifiedClassName()); } if(!obj && cls) { //Look for borrowed traits before //It's valid to override only a getter, so keep //looking for a settable even if a super class sets //has_getter to true. obj=cls->findBorrowedSettable(name,&has_getter); if(obj && cls->isFinal && !obj->setter) { throwError(kCannotAssignToMethodError, name.normalizedName(), cls ? cls->getQualifiedClassName() : ""); } } //Do not lookup in the prototype chain. This is tested behaviour if(!obj) { if(has_getter) // Is this a read-only property? { throwError(kConstWriteError, name.normalizedName(), cls ? cls->getQualifiedClassName() : ""); } // Properties can not be added to a sealed class if (cls && cls->isSealed) { throwError(kWriteSealedError, name.normalizedName(), cls->getQualifiedClassName()); } //Create a new dynamic variable obj=Variables.findObjVar(name,DYNAMIC_TRAIT,DYNAMIC_TRAIT); } if(obj->setter) { //Call the setter LOG(LOG_CALLS,_("Calling the setter")); //Overriding function is automatically done by using cur_level IFunction* setter=obj->setter; //One argument can be passed without creating an array ASObject* target=this; target->incRef(); _R ret= _MR( setter->call(target,&o,1) ); assert_and_throw(ret->is()); LOG(LOG_CALLS,_("End of setter")); } else { assert_and_throw(!obj->getter); obj->setVar(o); } } void ASObject::setVariableByQName(const tiny_string& name, const tiny_string& ns, ASObject* o, TRAIT_KIND traitKind) { const nsNameAndKind tmpns(ns, NAMESPACE); setVariableByQName(name, tmpns, o, traitKind); } void ASObject::setVariableByQName(const tiny_string& name, const nsNameAndKind& ns, ASObject* o, TRAIT_KIND traitKind) { setVariableByQName(getSys()->getUniqueStringId(name), ns, o, traitKind); } void ASObject::setVariableByQName(uint32_t nameId, const nsNameAndKind& ns, ASObject* o, TRAIT_KIND traitKind) { assert_and_throw(Variables.findObjVar(nameId,ns,NO_CREATE_TRAIT,traitKind)==NULL); variable* obj=Variables.findObjVar(nameId,ns,traitKind,traitKind); obj->setVar(o); } void ASObject::initializeVariableByMultiname(const multiname& name, ASObject* o, multiname* typemname, ABCContext* context, TRAIT_KIND traitKind) { check(); variable* obj=findSettable(name); if(obj) { //Initializing an already existing variable LOG(LOG_NOT_IMPLEMENTED,"Variable " << name << "already initialized"); o->decRef(); return; } Variables.initializeVar(name, o, typemname, context, traitKind); } variable::variable(TRAIT_KIND _k, ASObject* _v, multiname* _t, const Type* _type) : var(_v),typeUnion(NULL),setter(NULL),getter(NULL),kind(_k),traitState(NO_STATE) { if(_type) { //The type is known, use it instead of the typemname type=_type; traitState=TYPE_RESOLVED; } else { traitTypemname=_t; } } void variable::setVar(ASObject* v) { //Resolve the typename if we have one //currentCallContext may be NULL when inserting legacy //children, which is done outisde any ABC context if(!(traitState&TYPE_RESOLVED) && traitTypemname && getVm()->currentCallContext) { type = Type::getTypeFromMultiname(traitTypemname, getVm()->currentCallContext->context); assert(type); traitState=TYPE_RESOLVED; } if((traitState&TYPE_RESOLVED) && type) v = type->coerce(v); if(var) var->decRef(); var=v; } void variable::setVarNoCoerce(ASObject* v) { if(var) var->decRef(); var=v; } void variables_map::killObjVar(const multiname& mname) { uint32_t name=mname.normalizedNameId(); //The namespaces in the multiname are ordered. So it's possible to use lower_bound //to find the first candidate one and move from it assert(!mname.ns.empty()); var_iterator ret=Variables.lower_bound(varName(name,mname.ns.front())); auto nsIt=mname.ns.begin(); //Find the namespace while(ret!=Variables.end() && ret->first.nameId==name) { //breaks when the namespace is not found const nsNameAndKind& ns=ret->first.ns; if(ns==*nsIt) { Variables.erase(ret); return; } else if(*nsItfirst.nameId==name) { //breaks when the namespace is not found const nsNameAndKind& ns=ret->first.ns; if(ns==*nsIt) { if(ret->second.kind & traitKinds) return &ret->second; else return NULL; } else if(*nsIthasEmptyName()) throwError(kWriteSealedError, mname.normalizedName(), "" /* TODO: class name */); var_iterator inserted=Variables.insert( make_pair(varName(name,mname.ns[0]),variable(createKind))).first; return &inserted->second; } assert(mname.ns.size() == 1); var_iterator inserted=Variables.insert( make_pair(varName(name,mname.ns[0]),variable(createKind))).first; return &inserted->second; } const variable* variables_map::findObjVar(const multiname& mname, uint32_t traitKinds) const { uint32_t name=mname.normalizedNameId(); assert(!mname.ns.empty()); const_var_iterator ret=Variables.lower_bound(varName(name,mname.ns.front())); auto nsIt=mname.ns.begin(); //Find the namespace while(ret!=Variables.end() && ret->first.nameId==name) { //breaks when the namespace is not found const nsNameAndKind& ns=ret->first.ns; if(ns==*nsIt) { if(ret->second.kind & traitKinds) return &ret->second; else return NULL; } else if(*nsItis() || obj->is()); if(obj->is()) { //Casting undefined to an object (of unknown class) //results in Null obj->decRef(); obj = getSys()->getNullRef(); } } else obj = type->coerce(obj); assert(traitKind==DECLARED_TRAIT || traitKind==CONSTANT_TRAIT); uint32_t name=mname.normalizedNameId(); Variables.insert(make_pair(varName(name, mname.ns[0]), variable(traitKind, obj, typemname, type))); } ASFUNCTIONBODY(ASObject,generator) { //By default we assume it's a passthrough cast if(argslen==1) { LOG(LOG_CALLS,_("Passthrough of ") << args[0]); args[0]->incRef(); return args[0]; } else return Class::getInstanceS(); } ASFUNCTIONBODY(ASObject,_toString) { tiny_string ret; if(obj->getClass()) { ret="[object "; ret+=obj->getClass()->class_name.name; ret+="]"; } else if (obj->is()) { ret="[object "; ret+=static_cast(obj)->class_name.name; ret+="]"; } else ret="[object Object]"; return Class::getInstanceS(ret); } ASFUNCTIONBODY(ASObject,hasOwnProperty) { assert_and_throw(argslen==1); multiname name(NULL); name.name_type=multiname::NAME_STRING; name.name_s_id=getSys()->getUniqueStringId(args[0]->toString()); name.ns.push_back(nsNameAndKind("",NAMESPACE)); name.isAttribute=false; bool ret=obj->hasPropertyByMultiname(name, true, false); return abstract_b(ret); } ASFUNCTIONBODY(ASObject,valueOf) { obj->incRef(); return obj; } ASFUNCTIONBODY(ASObject,isPrototypeOf) { assert_and_throw(argslen==1); bool ret =false; Class_base* cls = args[0]->getClass(); while (cls != NULL) { if (cls->prototype->getObj() == obj) { ret = true; break; } Class_base* clsparent = cls->prototype->getObj()->getClass(); if (clsparent == cls) break; cls = clsparent; } return abstract_b(ret); } ASFUNCTIONBODY(ASObject,propertyIsEnumerable) { assert_and_throw(argslen==1); multiname name(NULL); name.name_type=multiname::NAME_STRING; name.name_s_id=getSys()->getUniqueStringId(args[0]->toString()); name.ns.push_back(nsNameAndKind("",NAMESPACE)); name.isAttribute=false; if (obj->is()) // propertyIsEnumerable(index) isn't mentioned in the ECMA specs but is tested for { Array* a = static_cast(obj); unsigned int index = 0; if (a->isValidMultiname(name,index)) { return abstract_b(index < (unsigned int)a->size()); } } if (obj->hasPropertyByMultiname(name,true,false)) return abstract_b(true); return abstract_b(false); } ASFUNCTIONBODY(ASObject,_constructor) { return NULL; } void ASObject::initSlot(unsigned int n, const multiname& name) { Variables.initSlot(n,name.name_s_id,name.ns[0]); } int32_t ASObject::getVariableByMultiname_i(const multiname& name) { check(); _NR ret=getVariableByMultiname(name); assert_and_throw(!ret.isNull()); return ret->toInt(); } const variable* ASObject::findGettableImpl(const variables_map& map, const multiname& name) { const variable* ret=map.findObjVar(name,DECLARED_TRAIT|DYNAMIC_TRAIT); if(ret) { //It seems valid for a class to redefine only the setter, so if we can't find //something to get, it's ok if(!(ret->getter || ret->var)) ret=NULL; } return ret; } const variable* ASObject::findGettable(const multiname& name) const { return findGettableImpl(Variables,name); } const variable* ASObject::findVariableByMultiname(const multiname& name, GET_VARIABLE_OPTION opt, Class_base* cls) { //Get from the current object without considering borrowed properties const variable* var=findGettable(name); if(!var && cls) { //Look for borrowed traits before var=cls->findBorrowedGettable(name); } if(!var && cls) { //Check prototype chain Prototype* proto = cls->prototype.getPtr(); while(proto) { var = proto->getObj()->findGettable(name); if(var) break; proto = proto->prevPrototype.getPtr(); } } return var; } _NR ASObject::getVariableByMultiname(const multiname& name, GET_VARIABLE_OPTION opt, Class_base* cls) { check(); assert(!cls || classdef->isSubClass(cls)); const variable* obj=findVariableByMultiname(name, opt, cls); if(!obj) return NullRef; if(obj->getter) { //Call the getter ASObject* target=this; if(target->classdef) { LOG(LOG_CALLS,_("Calling the getter on type ") << target->classdef->class_name); } else { LOG(LOG_CALLS,_("Calling the getter")); } IFunction* getter=obj->getter; target->incRef(); ASObject* ret=getter->call(target,NULL,0); LOG(LOG_CALLS,_("End of getter")); // No incRef because ret is a new instance return _MNR(ret); } else { assert_and_throw(!obj->setter); assert_and_throw(obj->var); if(obj->var->getObjectType()==T_FUNCTION && obj->var->as()->isMethod()) { LOG(LOG_CALLS,"Attaching this " << this << " to function " << name); //the obj reference is acquired by the smart reference this->incRef(); IFunction* f=obj->var->as()->bind(_MR(this),-1); //No incref is needed, as the function is a new instance return _MNR(f); } obj->var->incRef(); return _MNR(obj->var); } } _NR ASObject::getVariableByMultiname(const tiny_string& name, std::list namespaces) { multiname varName(NULL); varName.name_type=multiname::NAME_STRING; varName.name_s_id=getSys()->getUniqueStringId(name); for (auto ns=namespaces.begin(); ns!=namespaces.end(); ns++) varName.ns.push_back(nsNameAndKind(*ns,NAMESPACE)); varName.isAttribute = false; return getVariableByMultiname(varName,SKIP_IMPL); } _NR ASObject::executeASMethod(const tiny_string& methodName, std::list namespaces, ASObject* const* args, uint32_t num_args) { _NR o = getVariableByMultiname(methodName, namespaces); if (o.isNull() || !o->is()) throwError(kCallOfNonFunctionError, methodName); IFunction* f=o->as(); incRef(); ASObject *ret=f->call(this,args,num_args); return _MNR(ret); } void ASObject::check() const { //Put here a bunch of safety check on the object #ifndef NDEBUG assert(getRefCount()>0); #endif Variables.check(); } void variables_map::check() const { //Heavyweight stuff #ifdef EXPENSIVE_DEBUG variables_map::const_var_iterator it=Variables.begin(); for(;it!=Variables.end();++it) { variables_map::const_var_iterator next=it; ++next; if(next==Variables.end()) break; //No double definition of a single variable should exist if(it->first.nameId==next->first.nameId && it->first.ns==next->first.ns) { if(it->second.var==NULL && next->second.var==NULL) continue; if(it->second.var==NULL || next->second.var==NULL) { LOG(LOG_INFO, it->first.nameId << " " << it->first.ns); LOG(LOG_INFO, it->second.var << ' ' << it->second.setter << ' ' << it->second.getter); LOG(LOG_INFO, next->second.var << ' ' << next->second.setter << ' ' << next->second.getter); abort(); } if(it->second.var->getObjectType()!=T_FUNCTION || next->second.var->getObjectType()!=T_FUNCTION) { LOG(LOG_INFO, it->first.nameId); abort(); } } } #endif } void variables_map::dumpVariables() { var_iterator it=Variables.begin(); for(;it!=Variables.end();++it) { const char* kind; switch(it->second.kind) { case DECLARED_TRAIT: case CONSTANT_TRAIT: kind="Declared: "; break; case DYNAMIC_TRAIT: kind="Dynamic: "; break; case NO_CREATE_TRAIT: assert(false); } LOG(LOG_INFO, kind << '[' << it->first.ns << "] "<< getSys()->getStringFromUniqueId(it->first.nameId) << ' ' << it->second.var << ' ' << it->second.setter << ' ' << it->second.getter); } } variables_map::~variables_map() { destroyContents(); } void variables_map::destroyContents() { var_iterator it=Variables.begin(); for(;it!=Variables.end();++it) { if(it->second.var) it->second.var->decRef(); if(it->second.setter) it->second.setter->decRef(); if(it->second.getter) it->second.getter->decRef(); } Variables.clear(); } ASObject::ASObject(MemoryAccount* m):Variables(m),classdef(NULL), type(T_OBJECT),traitsInitialized(false),implEnable(true) { #ifndef NDEBUG //Stuff only used in debugging initialized=false; #endif } ASObject::ASObject(Class_base* c):Variables((c)?c->memoryAccount:NULL),classdef(NULL), type(T_OBJECT),traitsInitialized(false),implEnable(true) { setClass(c); #ifndef NDEBUG //Stuff only used in debugging initialized=false; #endif } ASObject::ASObject(const ASObject& o):Variables((o.classdef)?o.classdef->memoryAccount:NULL),classdef(NULL), type(o.type),traitsInitialized(false),implEnable(true) { if(o.classdef) setClass(o.classdef); #ifndef NDEBUG //Stuff only used in debugging initialized=false; #endif assert_and_throw(o.Variables.size()==0); } void ASObject::setClass(Class_base* c) { if(classdef) { classdef->abandonObject(this); classdef->decRef(); } classdef=c; if(classdef) { classdef->acquireObject(this); classdef->incRef(); } } void ASObject::finalize() { Variables.destroyContents(); if(classdef) { classdef->abandonObject(this); classdef->decRef(); classdef=NULL; } } ASObject::~ASObject() { finalize(); } void variables_map::initSlot(unsigned int n, uint32_t nameId, const nsNameAndKind& ns) { if(n>slots_vars.size()) slots_vars.resize(n,Variables.end()); var_iterator ret=Variables.find(varName(nameId,ns)); if(ret==Variables.end()) { //Name not present, no good throw RunTimeException("initSlot on missing variable"); } slots_vars[n-1]=ret; } void variables_map::setSlot(unsigned int n,ASObject* o) { validateSlotId(n); slots_vars[n-1]->second.setVar(o); } void variables_map::setSlotNoCoerce(unsigned int n,ASObject* o) { validateSlotId(n); slots_vars[n-1]->second.setVarNoCoerce(o); } void variables_map::validateSlotId(unsigned int n) const { if(n == 0 || n-1second.setter) throw UnsupportedException("setSlot has setters"); } else throw RunTimeException("setSlot out of bounds"); } variable* variables_map::getValueAt(unsigned int index) { //TODO: CHECK behaviour on overridden methods if(indexsecond; } else throw RunTimeException("getValueAt out of bounds"); } _R ASObject::getValueAt(int index) { variable* obj=Variables.getValueAt(index); assert_and_throw(obj); if(obj->getter) { //Call the getter LOG(LOG_CALLS,_("Calling the getter")); IFunction* getter=obj->getter; incRef(); _R ret(getter->call(this,NULL,0)); LOG(LOG_CALLS,_("End of getter")); return ret; } else { obj->var->incRef(); return _MR(obj->var); } } tiny_string variables_map::getNameAt(unsigned int index) const { //TODO: CHECK behaviour on overridden methods if(indexgetStringFromUniqueId(it->first.nameId); } else throw RunTimeException("getNameAt out of bounds"); } unsigned int ASObject::numVariables() const { return Variables.size(); } void ASObject::constructionComplete() { } void ASObject::serializeDynamicProperties(ByteArray* out, std::map& stringMap, std::map& objMap, std::map traitsMap) const { Variables.serialize(out, stringMap, objMap, traitsMap); } void variables_map::serialize(ByteArray* out, std::map& stringMap, std::map& objMap, std::map& traitsMap) const { //Pairs of name, value auto it=Variables.begin(); for(;it!=Variables.end();it++) { if(it->second.kind!=DYNAMIC_TRAIT) continue; //Dynamic traits always have empty namespace assert(it->first.ns.hasEmptyName()); out->writeStringVR(stringMap,getSys()->getStringFromUniqueId(it->first.nameId)); it->second.var->serialize(out, stringMap, objMap, traitsMap); } //The empty string closes the object out->writeStringVR(stringMap, ""); } void ASObject::serialize(ByteArray* out, std::map& stringMap, std::map& objMap, std::map& traitsMap) { //0x0A -> object marker out->writeByte(object_marker); //Check if the object has been already serialized to send it by reference auto it=objMap.find(this); if(it!=objMap.end()) { //The least significant bit is 0 to signal a reference out->writeU29(it->second << 1); return; } Class_base* type=getClass(); assert_and_throw(type); //Check if an alias is registered auto aliasIt=getSys()->aliasMap.begin(); const auto aliasEnd=getSys()->aliasMap.end(); //Linear search for alias tiny_string alias; for(;aliasIt!=aliasEnd;++aliasIt) { if(aliasIt->second==type) { alias=aliasIt->first; break; } } bool serializeTraits = alias.empty()==false; if(type->isSubClass(InterfaceClass::getClass())) { //Custom serialization necessary if(!serializeTraits) throwError(kInvalidParamError); out->writeU29(0x7); out->writeStringVR(stringMap, alias); //Invoke writeExternal multiname writeExternalName(NULL); writeExternalName.name_type=multiname::NAME_STRING; writeExternalName.name_s_id=getSys()->getUniqueStringId("writeExternal"); writeExternalName.ns.push_back(nsNameAndKind("",NAMESPACE)); writeExternalName.isAttribute = false; _NR o=getVariableByMultiname(writeExternalName,SKIP_IMPL); assert_and_throw(!o.isNull() && o->getObjectType()==T_FUNCTION); IFunction* f=o->as(); this->incRef(); out->incRef(); ASObject* const tmpArg[1] = {out}; f->call(this, tmpArg, 1); return; } //Add the object to the map objMap.insert(make_pair(this, objMap.size())); uint32_t traitsCount=0; const variables_map::const_var_iterator beginIt = Variables.Variables.begin(); const variables_map::const_var_iterator endIt = Variables.Variables.end(); //Check if the class traits has been already serialized to send it by reference auto it2=traitsMap.find(type); if(it2!=traitsMap.end()) out->writeU29((it2->second << 2) | 1); else { traitsMap.insert(make_pair(type, traitsMap.size())); for(variables_map::const_var_iterator varIt=beginIt; varIt != endIt; ++varIt) { if(varIt->second.kind==DECLARED_TRAIT) { if(!varIt->first.ns.hasEmptyName()) { //Skip variable with a namespace, like protected ones continue; } traitsCount++; } } uint32_t dynamicFlag=(type->isSealed)?0:(1 << 3); out->writeU29((traitsCount << 4) | dynamicFlag | 0x03); out->writeStringVR(stringMap, alias); for(variables_map::const_var_iterator varIt=beginIt; varIt != endIt; ++varIt) { if(varIt->second.kind==DECLARED_TRAIT) { if(!varIt->first.ns.hasEmptyName()) { //Skip variable with a namespace, like protected ones continue; } out->writeStringVR(stringMap, getSys()->getStringFromUniqueId(varIt->first.nameId)); } } } for(variables_map::const_var_iterator varIt=beginIt; varIt != endIt; ++varIt) { if(varIt->second.kind==DECLARED_TRAIT) { if(!varIt->first.ns.hasEmptyName()) { //Skip variable with a namespace, like protected ones continue; } varIt->second.var->serialize(out, stringMap, objMap, traitsMap); } } if(!type->isSealed) serializeDynamicProperties(out, stringMap, objMap, traitsMap); } ASObject *ASObject::describeType() const { xmlpp::DomParser p; xmlpp::Element* root=p.get_document()->create_root_node("type"); // type attributes Class_base* prot=getClass(); if(prot) { root->set_attribute("name", prot->getQualifiedClassName().raw_buf()); if(prot->super) root->set_attribute("base", prot->super->getQualifiedClassName().raw_buf()); } bool isDynamic = classdef && !classdef->isSealed; root->set_attribute("isDynamic", isDynamic?"true":"false"); bool isFinal = classdef && classdef->isFinal; root->set_attribute("isFinal", isFinal?"true":"false"); root->set_attribute("isStatic", "false"); if(prot) prot->describeInstance(root); // TODO: undocumented constructor node return Class::getInstanceS(root); } bool ASObject::hasprop_prototype() { variable* var=Variables.findObjVar(BUILTIN_STRINGS::PROTOTYPE,nsNameAndKind(BUILTIN_NAMESPACES::EMPTY_NS), NO_CREATE_TRAIT,(DECLARED_TRAIT|DYNAMIC_TRAIT)); return (var && var->var); } ASObject* ASObject::getprop_prototype() { variable* var=Variables.findObjVar(BUILTIN_STRINGS::PROTOTYPE,nsNameAndKind(BUILTIN_NAMESPACES::EMPTY_NS), NO_CREATE_TRAIT,(DECLARED_TRAIT|DYNAMIC_TRAIT)); return var ? var->var : NULL; } /* * (creates and) sets the property 'prototype' to o * 'prototype' is usually DYNAMIC_TRAIT, but on Class_base * it is a DECLARED_TRAIT, which is gettable only */ void ASObject::setprop_prototype(_NR& o) { ASObject* obj = o.getPtr(); obj->incRef(); multiname prototypeName(NULL); prototypeName.name_type=multiname::NAME_STRING; prototypeName.name_s_id=getSys()->getUniqueStringId("prototype"); prototypeName.ns.push_back(nsNameAndKind("",NAMESPACE)); bool has_getter = false; variable* ret=findSettable(prototypeName,&has_getter); if(!ret && has_getter) throwError(kConstWriteError, prototypeName.normalizedName(), classdef ? classdef->as()->getQualifiedClassName() : ""); if(!ret) ret = Variables.findObjVar(prototypeName,DYNAMIC_TRAIT,DECLARED_TRAIT|DYNAMIC_TRAIT); if(ret->setter) { this->incRef(); _MR( ret->setter->call(this,&obj,1) ); } else ret->setVar(obj); } tiny_string ASObject::getClassName() { if (getClass()) return getClass()->getQualifiedClassName(); else return ""; } lightspark-0.7.2/src/asobject.h000066400000000000000000000434221212105246600164260ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef ASOBJECT_H #define ASOBJECT_H 1 #include "compat.h" #include "swftypes.h" #include "smartrefs.h" #include "threading.h" #include "memory_support.h" #include #include #define ASFUNCTION(name) \ static ASObject* name(ASObject* , ASObject* const* args, const unsigned int argslen) /* declare setter/getter and associated member variable */ #define ASPROPERTY_GETTER(type,name) \ type name; \ ASFUNCTION( _getter_##name) #define ASPROPERTY_SETTER(type,name) \ type name; \ ASFUNCTION( _setter_##name) #define ASPROPERTY_GETTER_SETTER(type, name) \ type name; \ ASFUNCTION( _getter_##name); \ ASFUNCTION( _setter_##name) /* declare setter/getter for already existing member variable */ #define ASFUNCTION_GETTER(name) \ ASFUNCTION( _getter_##name) #define ASFUNCTION_SETTER(name) \ ASFUNCTION( _setter_##name) #define ASFUNCTION_GETTER_SETTER(name) \ ASFUNCTION( _getter_##name); \ ASFUNCTION( _setter_##name) /* general purpose body for an AS function */ #define ASFUNCTIONBODY(c,name) \ ASObject* c::name(ASObject* obj, ASObject* const* args, const unsigned int argslen) /* full body for a getter declared by ASPROPERTY_GETTER or ASFUNCTION_GETTER */ #define ASFUNCTIONBODY_GETTER(c,name) \ ASObject* c::_getter_##name(ASObject* obj, ASObject* const* args, const unsigned int argslen) \ { \ if(!obj->is()) \ throw Class::getInstanceS("Function applied to wrong object"); \ c* th = obj->as(); \ if(argslen != 0) \ throw Class::getInstanceS("Arguments provided in getter"); \ return ArgumentConversionname)>::toAbstract(th->name); \ } /* full body for a getter declared by ASPROPERTY_SETTER or ASFUNCTION_SETTER */ #define ASFUNCTIONBODY_SETTER(c,name) \ ASObject* c::_setter_##name(ASObject* obj, ASObject* const* args, const unsigned int argslen) \ { \ if(!obj->is()) \ throw Class::getInstanceS("Function applied to wrong object"); \ c* th = obj->as(); \ if(argslen != 1) \ throw Class::getInstanceS("Wrong number of arguments in setter"); \ th->name = ArgumentConversionname)>::toConcrete(args[0]); \ return NULL; \ } /* full body for a getter declared by ASPROPERTY_SETTER or ASFUNCTION_SETTER. * After the property has been updated, the callback member function is called with the old value * as parameter */ #define ASFUNCTIONBODY_SETTER_CB(c,name,callback) \ ASObject* c::_setter_##name(ASObject* obj, ASObject* const* args, const unsigned int argslen) \ { \ if(!obj->is()) \ throw Class::getInstanceS("Function applied to wrong object"); \ c* th = obj->as(); \ if(argslen != 1) \ throw Class::getInstanceS("Wrong number of arguments in setter"); \ decltype(th->name) oldValue = th->name; \ th->name = ArgumentConversionname)>::toConcrete(args[0]); \ th->callback(oldValue); \ return NULL; \ } /* full body for a getter declared by ASPROPERTY_GETTER_SETTER or ASFUNCTION_GETTER_SETTER */ #define ASFUNCTIONBODY_GETTER_SETTER(c,name) \ ASFUNCTIONBODY_GETTER(c,name) \ ASFUNCTIONBODY_SETTER(c,name) #define ASFUNCTIONBODY_GETTER_SETTER_CB(c,name,callback) \ ASFUNCTIONBODY_GETTER(c,name) \ ASFUNCTIONBODY_SETTER_CB(c,name,callback) /* registers getter/setter with Class_base. To be used in ::sinit()-functions */ #define REGISTER_GETTER(c,name) \ c->setDeclaredMethodByQName(#name,"",Class::getFunction(_getter_##name),GETTER_METHOD,true) #define REGISTER_SETTER(c,name) \ c->setDeclaredMethodByQName(#name,"",Class::getFunction(_setter_##name),SETTER_METHOD,true) #define REGISTER_GETTER_SETTER(c,name) \ REGISTER_GETTER(c,name); \ REGISTER_SETTER(c,name) namespace lightspark { class ASObject; class IFunction; template class Class; class Class_base; class ByteArray; class Loader; class Type; class ABCContext; enum TRAIT_KIND { NO_CREATE_TRAIT=0, DECLARED_TRAIT=1, DYNAMIC_TRAIT=2, CONSTANT_TRAIT=9 /* constants are also declared traits */ }; enum TRAIT_STATE { NO_STATE=0, HAS_GETTER_SETTER=1, TYPE_RESOLVED=2 }; struct variable { ASObject* var; union { multiname* traitTypemname; const Type* type; void* typeUnion; }; IFunction* setter; IFunction* getter; TRAIT_KIND kind; TRAIT_STATE traitState; variable(TRAIT_KIND _k) : var(NULL),typeUnion(NULL),setter(NULL),getter(NULL),kind(_k),traitState(NO_STATE) {} variable(TRAIT_KIND _k, ASObject* _v, multiname* _t, const Type* type); void setVar(ASObject* v); /* * To be used only if the value is guaranteed to be of the right type */ void setVarNoCoerce(ASObject* v); }; struct varName { uint32_t nameId; nsNameAndKind ns; varName(uint32_t name, const nsNameAndKind& _ns):nameId(name),ns(_ns){} bool operator<(const varName& r) const { //Sort by name first if(nameId==r.nameId) { //Then by namespace return ns,reporter_allocator>> mapType; mapType Variables; typedef std::map::iterator var_iterator; typedef std::map::const_iterator const_var_iterator; std::vector> slots_vars; variables_map(MemoryAccount* m); /** Find a variable in the map @param createKind If this is different from NO_CREATE_TRAIT and no variable is found a new one is created with the given kind @param traitKinds Bitwise OR of accepted trait kinds */ variable* findObjVar(uint32_t nameId, const nsNameAndKind& ns, TRAIT_KIND createKind, uint32_t traitKinds); variable* findObjVar(const multiname& mname, TRAIT_KIND createKind, uint32_t traitKinds); /** * Const version of findObjVar, useful when looking for getters */ const variable* findObjVar(const multiname& mname, uint32_t traitKinds) const; //Initialize a new variable specifying the type (TODO: add support for const) void initializeVar(const multiname& mname, ASObject* obj, multiname* typemname, ABCContext* context, TRAIT_KIND traitKind); void killObjVar(const multiname& mname); ASObject* getSlot(unsigned int n) { assert_and_throw(n > 0 && n<=slots_vars.size()); return slots_vars[n-1]->second.var; } /* * This method does throw if the slot id is not valid */ void validateSlotId(unsigned int n) const; void setSlot(unsigned int n,ASObject* o); /* * This version of the call is guarantee to require no type conversion * this is verified at optimization time */ void setSlotNoCoerce(unsigned int n,ASObject* o); void initSlot(unsigned int n, uint32_t nameId, const nsNameAndKind& ns); int size() const { return Variables.size(); } tiny_string getNameAt(unsigned int i) const; variable* getValueAt(unsigned int i); int getNextEnumerable(unsigned int i) const; ~variables_map(); void check() const; void serialize(ByteArray* out, std::map& stringMap, std::map& objMap, std::map& traitsMap) const; void dumpVariables(); void destroyContents(); }; enum METHOD_TYPE { NORMAL_METHOD=0, SETTER_METHOD=1, GETTER_METHOD=2 }; //for toPrimitive enum TP_HINT { NO_HINT, NUMBER_HINT, STRING_HINT }; class ASObject: public memory_reporter, public boost::intrusive::list_base_hook<>, public RefCountable { friend class ABCVm; friend class ABCContext; friend class Class_base; //Needed for forced cleanup friend void lookupAndLink(Class_base* c, const tiny_string& name, const tiny_string& interfaceNs); friend class IFunction; //Needed for clone private: variables_map Variables; Class_base* classdef; const variable* findGettable(const multiname& name) const DLL_LOCAL; variable* findSettable(const multiname& name, bool* has_getter=NULL) DLL_LOCAL; protected: ASObject(MemoryAccount* m); ASObject(const ASObject& o); virtual ~ASObject(); SWFOBJECT_TYPE type; bool traitsInitialized:1; void serializeDynamicProperties(ByteArray* out, std::map& stringMap, std::map& objMap, std::map traitsMap) const; void setClass(Class_base* c); static variable* findSettableImpl(variables_map& map, const multiname& name, bool* has_getter); static const variable* findGettableImpl(const variables_map& map, const multiname& name); public: ASObject(Class_base* c); #ifndef NDEBUG //Stuff only used in debugging bool initialized:1; #endif bool implEnable:1; Class_base* getClass() const { return classdef; } ASFUNCTION(_constructor); ASFUNCTION(_toString); ASFUNCTION(hasOwnProperty); ASFUNCTION(valueOf); ASFUNCTION(isPrototypeOf); ASFUNCTION(propertyIsEnumerable); void check() const; static void s_incRef(ASObject* o) { o->incRef(); } static void s_decRef(ASObject* o) { if(o) o->decRef(); } static void s_decRef_safe(ASObject* o,ASObject* o2) { if(o && o!=o2) o->decRef(); } /* The finalize function should be implemented in all derived class that stores pointers. It should decRef all referenced objects. It's guaranteed that the only operations that will happen on the object after finalization are decRef and delete. Each class must call BaseClass::finalize in their finalize function. The finalize method must be callable multiple time with the same effects (no double frees). Each class must also call his own ::finalize in the destructor!*/ virtual void finalize(); enum GET_VARIABLE_OPTION {NONE=0x00, SKIP_IMPL=0x01, XML_STRICT=0x02}; virtual _NR getVariableByMultiname(const multiname& name, GET_VARIABLE_OPTION opt=NONE) { return getVariableByMultiname(name,opt,classdef); } /* * Helper method using the get the raw variable struct instead of calling the getter. * It is used by getVariableByMultiname and by early binding code */ const variable* findVariableByMultiname(const multiname& name, GET_VARIABLE_OPTION opt, Class_base* cls); /* * Gets a variable of this object. It looks through all classes (beginning at cls), * then the prototype chain, and then instance variables. * If the property found is a getter, it is called and its return value returned. */ _NR getVariableByMultiname(const multiname& name, GET_VARIABLE_OPTION opt, Class_base* cls); virtual int32_t getVariableByMultiname_i(const multiname& name); /* Simple getter interface for the common case */ _NR getVariableByMultiname(const tiny_string& name, std::list namespaces); /* * Execute a AS method on this object. Returns the value * returned by the function. One reference of each args[i] is * consumed. The method must exist, otherwise a TypeError is * thrown. */ _NR executeASMethod(const tiny_string& methodName, std::list namespaces, ASObject* const* args, uint32_t num_args); virtual void setVariableByMultiname_i(const multiname& name, int32_t value); enum CONST_ALLOWED_FLAG { CONST_ALLOWED=0, CONST_NOT_ALLOWED }; virtual void setVariableByMultiname(const multiname& name, ASObject* o, CONST_ALLOWED_FLAG allowConst) { setVariableByMultiname(name,o,allowConst,classdef); } /* * Sets variable of this object. It looks through all classes (beginning at cls), * then the prototype chain, and then instance variables. * If the property found is a setter, it is called with the given 'o'. * If no property is found, an instance variable is created. * Setting CONSTANT_TRAIT is only allowed if allowConst is true */ void setVariableByMultiname(const multiname& name, ASObject* o, CONST_ALLOWED_FLAG allowConst, Class_base* cls); /* * Called by ABCVm::buildTraits to create DECLARED_TRAIT or CONSTANT_TRAIT and set their type */ void initializeVariableByMultiname(const multiname& name, ASObject* o, multiname* typemname, ABCContext* context, TRAIT_KIND traitKind); /* * Called by ABCVm::initProperty (implementation of ABC instruction), it is allowed to set CONSTANT_TRAIT */ void initializeVariableByMultiname(const multiname& name, ASObject* o); virtual bool deleteVariableByMultiname(const multiname& name); void setVariableByQName(const tiny_string& name, const tiny_string& ns, ASObject* o, TRAIT_KIND traitKind); void setVariableByQName(const tiny_string& name, const nsNameAndKind& ns, ASObject* o, TRAIT_KIND traitKind); void setVariableByQName(uint32_t nameId, const nsNameAndKind& ns, ASObject* o, TRAIT_KIND traitKind); //NOTE: the isBorrowed flag is used to distinguish methods/setters/getters that are inside a class but on behalf of the instances void setDeclaredMethodByQName(const tiny_string& name, const tiny_string& ns, IFunction* o, METHOD_TYPE type, bool isBorrowed); void setDeclaredMethodByQName(const tiny_string& name, const nsNameAndKind& ns, IFunction* o, METHOD_TYPE type, bool isBorrowed); void setDeclaredMethodByQName(uint32_t nameId, const nsNameAndKind& ns, IFunction* o, METHOD_TYPE type, bool isBorrowed); virtual bool hasPropertyByMultiname(const multiname& name, bool considerDynamic, bool considerPrototype); ASObject* getSlot(unsigned int n) { return Variables.getSlot(n); } void setSlot(unsigned int n,ASObject* o) { Variables.setSlot(n,o); } void setSlotNoCoerce(unsigned int n,ASObject* o) { Variables.setSlotNoCoerce(n,o); } void initSlot(unsigned int n, const multiname& name); unsigned int numVariables() const; tiny_string getNameAt(int i) const { return Variables.getNameAt(i); } _R getValueAt(int i); SWFOBJECT_TYPE getObjectType() const { return type; } /* Implements ECMA's 9.8 ToString operation, but returns the concrete value */ tiny_string toString(); virtual int32_t toInt(); virtual uint32_t toUInt(); uint16_t toUInt16(); /* Implements ECMA's 9.3 ToNumber operation, but returns the concrete value */ number_t toNumber(); /* Implements ECMA's ToPrimitive (9.1) and [[DefaultValue]] (8.6.2.6) */ _R toPrimitive(TP_HINT hint = NO_HINT); bool isPrimitive() const; /* helper functions for calling the "valueOf" and * "toString" AS-functions which may be members of this * object */ bool has_valueOf(); _R call_valueOf(); bool has_toString(); _R call_toString(); /* Helper function for calling getClass()->getQualifiedClassName() */ virtual tiny_string getClassName(); ASFUNCTION(generator); /* helpers for the dynamic property 'prototype' */ bool hasprop_prototype(); ASObject* getprop_prototype(); void setprop_prototype(_NR& prototype); //Comparison operators virtual bool isEqual(ASObject* r); virtual bool isEqualStrict(ASObject* r); virtual TRISTATE isLess(ASObject* r); static void sinit(Class_base* c); static void buildTraits(ASObject* o); //Enumeration handling virtual uint32_t nextNameIndex(uint32_t cur_index); virtual _R nextName(uint32_t index); virtual _R nextValue(uint32_t index); //Called when the object construction is completed. Used by MovieClip implementation virtual void constructionComplete(); /** Serialization interface The various maps are used to implement reference type of the AMF3 spec */ virtual void serialize(ByteArray* out, std::map& stringMap, std::map& objMap, std::map& traitsMap); virtual ASObject *describeType() const; /* returns true if the current object is of type T */ template bool is() const { return dynamic_cast(this); } /* returns this object casted to the given type. * You have to make sure that it actually is the type (see is() above) */ template const T* as() const { return static_cast(this); } template T* as() { return static_cast(this); } /* Returns a debug string identifying this object */ virtual std::string toDebugString(); }; class Number; class UInteger; class Integer; class Boolean; class Template_base; class ASString; class Function; class Array; class Null; class Undefined; class Type; template<> inline bool ASObject::is() const { return type==T_NUMBER; } template<> inline bool ASObject::is() const { return type==T_INTEGER; } template<> inline bool ASObject::is() const { return type==T_UINTEGER; } template<> inline bool ASObject::is() const { return type==T_BOOLEAN; } template<> inline bool ASObject::is() const { return type==T_STRING; } template<> inline bool ASObject::is() const { return type==T_FUNCTION; } template<> inline bool ASObject::is() const { return type==T_UNDEFINED; } template<> inline bool ASObject::is() const { return type==T_NULL; } template<> inline bool ASObject::is() const { return type==T_ARRAY; } template<> inline bool ASObject::is() const { return type==T_CLASS; } template<> inline bool ASObject::is() const { return type==T_TEMPLATE; } template<> inline bool ASObject::is() const { return type==T_CLASS; } } #endif /* ASOBJECT_H */ lightspark-0.7.2/src/backends/000077500000000000000000000000001212105246600162305ustar00rootroot00000000000000lightspark-0.7.2/src/backends/CMakeLists.txt000066400000000000000000000000011212105246600207570ustar00rootroot00000000000000 lightspark-0.7.2/src/backends/audio.cpp000066400000000000000000000073061212105246600200430ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "swf.h" #include "backends/audio.h" #include "backends/config.h" #include #include "logger.h" //Needed or not with compat.h and compat.cpp? #ifdef _WIN32 # include #else # include # include #endif using namespace lightspark; using namespace std; /**************** AudioManager::AudioManager ***************** It should search for a list of audio plugin lib files (liblightsparkAUDIOAPIplugin.so) Then, it should read a config file containing the user's defined audio API choosen as audio backend If no file or none selected default to none Else Select and load the good audio plugin lib files *****************/ AudioManager::AudioManager ( PluginManager *sharedPluginManager ) : oAudioPlugin(NULL), selectedAudioBackend(""), pluginManager(sharedPluginManager) { // string DesiredAudio = get_audioConfig(); //Looks for the audio selected in the user's config string DesiredAudio = Config::getConfig()->getAudioBackendName(); set_audiobackend ( DesiredAudio ); } bool AudioManager::pluginLoaded() const { return oAudioPlugin != NULL; } AudioStream *AudioManager::createStreamPlugin ( AudioDecoder *decoder ) { if ( pluginLoaded() ) { return oAudioPlugin->createStream ( decoder ); } else { LOG ( LOG_ERROR, _ ( "No audio plugin loaded, can't create stream" ) ); return NULL; } } bool AudioManager::isTimingAvailablePlugin() const { if ( pluginLoaded() ) { return oAudioPlugin->isTimingAvailable(); } else { LOG ( LOG_ERROR, _ ( "isTimingAvailablePlugin: No audio plugin loaded" ) ); return false; } } void AudioManager::set_audiobackend ( string desired_backend ) { if ( selectedAudioBackend != desired_backend ) //Load the desired backend only if it's not already loaded { load_audioplugin ( desired_backend ); selectedAudioBackend = desired_backend; } } void AudioManager::get_audioBackendsList() { audioplugins_list = pluginManager->get_backendsList ( AUDIO ); } void AudioManager::refresh_audioplugins_list() { audioplugins_list.clear(); get_audioBackendsList(); } void AudioManager::release_audioplugin() { if ( pluginLoaded() ) { pluginManager->release_plugin ( oAudioPlugin ); } } void AudioManager::load_audioplugin ( string selected_backend ) { LOG ( LOG_INFO, _ ( ( ( string ) ( "the selected backend is: " + selected_backend ) ).c_str() ) ); release_audioplugin(); oAudioPlugin = static_cast ( pluginManager->get_plugin ( selected_backend ) ); if ( !pluginLoaded() ) { LOG ( LOG_INFO, _ ( "Could not load the audiobackend" ) ); } } /************************** stop AudioManager ***************************/ AudioManager::~AudioManager() { release_audioplugin(); pluginManager = NULL; //The plugin manager is not deleted since it's been created outside of the audio manager } lightspark-0.7.2/src/backends/audio.h000066400000000000000000000042431212105246600175050ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_AUDIO_H #define BACKENDS_AUDIO_H 1 #include "compat.h" #include "backends/decoder.h" #include #include "backends/pluginmanager.h" #include "backends/interfaces/audio/IAudioPlugin.h" //convenience typedef for the pointers to the 2 functions we expect to find in the plugin libraries typedef IPlugin * ( *PLUGIN_FACTORY ) (); typedef void ( *PLUGIN_CLEANUP ) ( IPlugin * ); namespace lightspark { class AudioManager { private: std::vectoraudioplugins_list; IAudioPlugin *oAudioPlugin; std::string selectedAudioBackend; void load_audioplugin ( std::string selected_backend ); void release_audioplugin(); PluginManager *pluginManager; public: AudioManager ( PluginManager *sharePluginManager ); bool pluginLoaded() const; AudioStream *createStreamPlugin ( AudioDecoder *decoder ); bool isTimingAvailablePlugin() const; void set_audiobackend ( std::string desired_backend ); void get_audioBackendsList(); void refresh_audioplugins_list(); void muteAll() { oAudioPlugin->muteAll(); } void unmuteAll() { oAudioPlugin->unmuteAll(); } void toggleMuteAll() { oAudioPlugin->toggleMuteAll(); } bool allMuted() { return oAudioPlugin->allMuted(); } ~AudioManager(); }; }; #endif /* BACKENDS_AUDIO_H */ lightspark-0.7.2/src/backends/builtindecoder.cpp000066400000000000000000000115321212105246600217320ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2011-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "backends/builtindecoder.h" using namespace lightspark; BuiltinStreamDecoder::BuiltinStreamDecoder(std::istream& _s): stream(_s),prevSize(0),decodedAudioBytes(0),decodedVideoFrames(0),decodedTime(0),frameRate(0.0) { STREAM_TYPE t=classifyStream(stream); if(t==FLV_STREAM) { FLV_HEADER h(stream); valid=h.isValid(); } else valid=false; } BuiltinStreamDecoder::STREAM_TYPE BuiltinStreamDecoder::classifyStream(std::istream& s) { char buf[3]; s.read(buf,3); STREAM_TYPE ret; if(strncmp(buf,"FLV",3)==0) ret=FLV_STREAM; else throw ParseException("File signature not recognized"); s.seekg(0); return ret; } bool BuiltinStreamDecoder::decodeNextFrame() { UI32_FLV PreviousTagSize; stream >> PreviousTagSize; assert_and_throw(PreviousTagSize==prevSize); //Check tag type and read it UI8 TagType; stream >> TagType; switch(TagType) { case 8: { AudioDataTag tag(stream); prevSize=tag.getTotalLen(); if(audioDecoder==NULL) { audioCodec=tag.SoundFormat; switch(tag.SoundFormat) { case AAC: assert_and_throw(tag.isHeader()) #ifdef ENABLE_LIBAVCODEC audioDecoder=new FFMpegAudioDecoder(tag.SoundFormat, tag.packetData, tag.packetLen); #else audioDecoder=new NullAudioDecoder(); #endif tag.releaseBuffer(); break; case MP3: #ifdef ENABLE_LIBAVCODEC audioDecoder=new FFMpegAudioDecoder(tag.SoundFormat,NULL,0); #else audioDecoder=new NullAudioDecoder(); #endif decodedAudioBytes+=audioDecoder->decodeData(tag.packetData,tag.packetLen,decodedTime); //Adjust timing decodedTime=decodedAudioBytes/audioDecoder->getBytesPerMSec(); break; default: throw RunTimeException("Unsupported SoundFormat"); } } else { assert_and_throw(audioCodec==tag.SoundFormat); decodedAudioBytes+=audioDecoder->decodeData(tag.packetData,tag.packetLen,decodedTime); //Adjust timing decodedTime=decodedAudioBytes/audioDecoder->getBytesPerMSec(); } break; } case 9: { VideoDataTag tag(stream); prevSize=tag.getTotalLen(); //If the framerate is known give the right timing, otherwise use decodedTime from audio uint32_t frameTime=(frameRate!=0.0)?(decodedVideoFrames*1000/frameRate):decodedTime; if(videoDecoder==NULL) { //If the isHeader flag is on then the decoder becomes the owner of the data if(tag.isHeader()) { //The tag is the header, initialize decoding #ifdef ENABLE_LIBAVCODEC videoDecoder=new FFMpegVideoDecoder(tag.codec,tag.packetData,tag.packetLen, frameRate); #else videoDecoder=new NullVideoDecoder(); #endif tag.releaseBuffer(); } else { //First packet but no special handling #ifdef ENABLE_LIBAVCODEC videoDecoder=new FFMpegVideoDecoder(tag.codec,NULL,0,frameRate); #else videoDecoder=new NullVideoDecoder(); #endif videoDecoder->decodeData(tag.packetData,tag.packetLen, frameTime); decodedVideoFrames++; } } else { videoDecoder->decodeData(tag.packetData,tag.packetLen, frameTime); decodedVideoFrames++; } break; } case 18: { metadataTag=ScriptDataTag(stream); prevSize=metadataTag.getTotalLen(); //The frameRate of the container overrides the stream if(metadataTag.metadataDouble.find("framerate") != metadataTag.metadataDouble.end()) frameRate=metadataTag.metadataDouble["framerate"]; break; } default: LOG(LOG_ERROR,_("Unexpected tag type ") << (int)TagType << _(" in FLV")); return false; } return true; } bool BuiltinStreamDecoder::getMetadataInteger(const char* name, uint32_t& ret) const { auto it=metadataTag.metadataInteger.find(name); if(it == metadataTag.metadataInteger.end()) return false; ret=it->second; return true; } bool BuiltinStreamDecoder::getMetadataDouble(const char* name, double& ret) const { auto it=metadataTag.metadataDouble.find(name); if(it == metadataTag.metadataDouble.end()) return false; ret=it->second; return true; } lightspark-0.7.2/src/backends/builtindecoder.h000066400000000000000000000033521212105246600214000ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2011-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_BUILTINDECODER_H #define BACKENDS_BUILTINDECODER_H 1 #include "backends/decoder.h" #include "parsing/flv.h" namespace lightspark { class BuiltinStreamDecoder: public StreamDecoder { private: std::istream& stream; unsigned int prevSize; LS_AUDIO_CODEC audioCodec; uint32_t decodedAudioBytes; uint32_t decodedVideoFrames; //The decoded time is computed from the decodedAudioBytes to avoid drifts uint32_t decodedTime; double frameRate; ScriptDataTag metadataTag; enum STREAM_TYPE { FLV_STREAM=0 }; STREAM_TYPE classifyStream(std::istream& s); public: BuiltinStreamDecoder(std::istream& _s); bool decodeNextFrame(); bool getMetadataInteger(const char* name, uint32_t& ret) const; bool getMetadataDouble(const char* name, double& ret) const; }; }; #endif /* BACKENDS_BUILTINDECODER_H */ lightspark-0.7.2/src/backends/config.cpp000066400000000000000000000143571212105246600202130ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include #include #include #include "backends/config.h" #include "compat.h" #include "logger.h" #include "exceptions.h" using namespace lightspark; using namespace std; using namespace boost::filesystem; Config* Config::getConfig() { static Config conf; return &conf; } #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN # include const std::string LS_REG_KEY = "SOFTWARE\\MozillaPlugins\\@lightspark.github.com/Lightspark;version=1"; std::string readRegistryEntry(std::string name) { char lszValue[255]; HKEY hKey; LONG returnStatus; DWORD dwType=REG_SZ; DWORD dwSize=sizeof(lszValue);; returnStatus = RegOpenKeyEx(HKEY_CURRENT_USER, LS_REG_KEY.c_str(), 0L, KEY_QUERY_VALUE, &hKey); if(returnStatus != ERROR_SUCCESS) { LOG(LOG_ERROR,"Could not open registry key " << LS_REG_KEY); return ""; } returnStatus = RegQueryValueEx(hKey, name.c_str(), NULL, &dwType, (LPBYTE)&lszValue, &dwSize); if(returnStatus != ERROR_SUCCESS) { LOG(LOG_ERROR,"Could not read registry key value " << LS_REG_KEY << "\\" << name); return ""; } if(dwType != REG_SZ) { LOG(LOG_ERROR,"Registry key" << LS_REG_KEY << "\\" << name << " has unexpected type"); return ""; } RegCloseKey(hKey); if(dwSize == 0) return ""; /* strip terminating '\0' - string may or may not have one */ if(lszValue[dwSize] == '\0') dwSize--; return std::string(lszValue,dwSize); } #endif Config::Config(): parser(NULL), //CONFIGURATION FILENAME AND SEARCH DIRECTORIES configFilename("lightspark.conf"), systemConfigDirectories(g_get_system_config_dirs()),userConfigDirectory(g_get_user_config_dir()), //DEFAULT SETTINGS defaultCacheDirectory((string) g_get_user_cache_dir() + "/lightspark"), cacheDirectory(defaultCacheDirectory),cachePrefix("cache"), audioBackend(INVALID),audioBackendName(""), renderingEnabled(true) { #ifdef _WIN32 const char* exePath = getExectuablePath(); if(exePath) userConfigDirectory = exePath; #endif audioBackendNames[PULSEAUDIO] = "pulseaudio"; audioBackendNames[SDL] = "sdl"; audioBackendNames[WINMM] = "winmm"; //Try system configs first string sysDir; const char* const* cursor = systemConfigDirectories; while(*cursor != NULL) { sysDir = *cursor; parser = new ConfigParser(sysDir + "/" + configFilename); while(parser->read()) handleEntry(); delete parser; parser = NULL; ++cursor; } //Try user config next parser = new ConfigParser(userConfigDirectory + "/" + configFilename); while(parser->read()) handleEntry(); delete parser; parser = NULL; #ifndef _WIN32 //Expand tilde in path if(cacheDirectory.length() > 0 && cacheDirectory[0] == '~') cacheDirectory.replace(0, 1, getenv("HOME")); #endif //If cache dir doesn't exist, create it path cacheDirectoryP(cacheDirectory); if(!is_directory(cacheDirectoryP)) { LOG(LOG_INFO, "Cache directory does not exist, trying to create"); try { create_directories(cacheDirectoryP); } catch(const filesystem_error& e) { LOG(LOG_INFO, _("Could not create cache directory, falling back to default cache directory: ") << defaultCacheDirectory); cacheDirectory = defaultCacheDirectory; } } /* If no audio backend was specified, use a default */ if(audioBackend == INVALID) { #ifdef _WIN32 audioBackend = WINMM; #else audioBackend = PULSEAUDIO; #endif } //Set the audio backend name audioBackendName = audioBackendNames[audioBackend]; #ifdef _WIN32 std::string regGnashPath = readRegistryEntry("GnashPath"); if(regGnashPath.empty()) { const char* s = getExectuablePath(); if(!s) LOG(LOG_ERROR,"Could not get executable path!"); else { path gnash_exec_path = s; if(is_regular_file(gnash_exec_path / "gtk-gnash.exe")) { LOG(LOG_INFO,"Found gnash at " << (gnash_exec_path / "gtk-gnash.exe")); gnashPath = (gnash_exec_path / "gtk-gnash.exe").string(); } else if(is_regular_file(gnash_exec_path / "sdl-gnash.exe")) { LOG(LOG_INFO,"Found gnash at " << (gnash_exec_path / "sdl-gnash.exe")); gnashPath = (gnash_exec_path / "sdl-gnash.exe").string(); } else LOG(LOG_ERROR, "Could not find gnash in " << gnash_exec_path); } } else { LOG(LOG_INFO, "Read gnash's path from registry: " << regGnashPath); gnashPath = regGnashPath; } #else # ifndef GNASH_PATH # error No GNASH_PATH defined # endif gnashPath = GNASH_PATH; #endif } Config::~Config() { if(parser != NULL) delete parser; } /* This is called by the parser for each entry in the configuration file */ void Config::handleEntry() { string group = parser->getGroup(); string key = parser->getKey(); string value = parser->getValue(); //Audio backend if(group == "audio" && key == "backend" && value == audioBackendNames[PULSEAUDIO]) audioBackend = PULSEAUDIO; else if(group == "audio" && key == "backend" && value == audioBackendNames[SDL]) audioBackend = SDL; else if(group == "audio" && key == "backend" && value == audioBackendNames[WINMM]) audioBackend = WINMM; //Rendering else if(group == "rendering" && key == "enabled") renderingEnabled = atoi(value.c_str()); //Cache directory else if(group == "cache" && key == "directory") cacheDirectory = value; //Cache prefix else if(group == "cache" && key == "prefix") cachePrefix = value; else throw ConfigException((string) _("Invalid entry encountered in configuration file") + ": '" + group + "/" + key + "'='" + value + "'"); } lightspark-0.7.2/src/backends/config.h000066400000000000000000000050711212105246600176510ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_CONFIG_H #define BACKENDS_CONFIG_H 1 #include "parsing/config.h" namespace lightspark { class Config { private: ConfigParser* parser; void handleEntry(); //-- CONFIGURATION FILENAME AND SEARCH DIRECTORIES const std::string configFilename; const char* const* systemConfigDirectories; std::string userConfigDirectory; //-- SETTINGS VALUES enum AUDIOBACKEND { PULSEAUDIO=0, SDL, WINMM, NUM_AUDIO_BACKENDS, INVALID=1024 }; std::string audioBackendNames[NUM_AUDIO_BACKENDS]; //-- SETTINGS //Specifies the default cache directory = "~/.cache/lightspark" std::string defaultCacheDirectory; //Specifies where files are cached (like downloaded data) std::string cacheDirectory; //Specifies what prefix the cache files should have, default="cache" std::string cachePrefix; //Specifies the filename including full path of the gnash executable std::string gnashPath; //Specifies what audio backend should, default=PULSEAUDIO AUDIOBACKEND audioBackend; std::string audioBackendName; //Specifies if rendering should be done bool renderingEnabled; Config(); ~Config(); public: /* Returns the singleton config object */ static Config* getConfig(); const std::string& getCacheDirectory() const { return cacheDirectory; } const std::string& getCachePrefix() const { return cachePrefix; } const std::string& getGnashPath() const { return gnashPath; } AUDIOBACKEND getAudioBackend() const { return audioBackend; } const std::string& getAudioBackendName() const { return audioBackendName; } bool isRenderingEnabled() const { return renderingEnabled; } }; } #endif /* BACKENDS_CONFIG_H */ lightspark-0.7.2/src/backends/decoder.cpp000077500000000000000000000472531212105246600203570ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "compat.h" #include #include "backends/decoder.h" #include "platforms/fastpaths.h" #include "swf.h" #include "backends/rendering.h" #if LIBAVUTIL_VERSION_MAJOR < 51 #define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO #define AVMEDIA_TYPE_AUDIO CODEC_TYPE_AUDIO #endif using namespace lightspark; using namespace std; bool VideoDecoder::setSize(uint32_t w, uint32_t h) { if(w!=frameWidth || h!=frameHeight) { frameWidth=w; frameHeight=h; LOG(LOG_INFO,_("VIDEO DEC: Video frame size ") << frameWidth << 'x' << frameHeight); resizeGLBuffers=true; videoTexture=getSys()->getRenderThread()->allocateTexture(frameWidth, frameHeight, true); return true; } else return false; } bool VideoDecoder::resizeIfNeeded(TextureChunk& tex) { if(!resizeGLBuffers) return false; //Chunks are at least aligned to 128, we need 16 assert_and_throw(tex.width==frameWidth && tex.height==frameHeight); resizeGLBuffers=false; return true; } void VideoDecoder::sizeNeeded(uint32_t& w, uint32_t& h) const { //Return the actual width aligned to 16, the SSE2 packer is advantaged by this //and it comes for free as the texture tiles are aligned to 128 w=(frameWidth+15)&0xfffffff0; h=frameHeight; } const TextureChunk& VideoDecoder::getTexture() { return videoTexture; } void VideoDecoder::uploadFence() { assert(fenceCount); ATOMIC_DECREMENT(fenceCount); } void VideoDecoder::waitForFencing() { ATOMIC_INCREMENT(fenceCount); } #ifdef ENABLE_LIBAVCODEC bool FFMpegVideoDecoder::fillDataAndCheckValidity() { if(frameRate==0 && codecContext->time_base.num!=0) { frameRate=codecContext->time_base.den; frameRate/=codecContext->time_base.num; if(videoCodec==H264) //H264 has half ticks (usually?) frameRate/=2; } else if(frameRate==0) return false; if(codecContext->width!=0 && codecContext->height!=0) setSize(codecContext->width, codecContext->height); else return false; return true; } FFMpegVideoDecoder::FFMpegVideoDecoder(LS_VIDEO_CODEC codecId, uint8_t* initdata, uint32_t datalen, double frameRateHint): ownedContext(true),curBuffer(0),codecContext(NULL),curBufferOffset(0) { //The tag is the header, initialize decoding #ifdef HAVE_AVCODEC_ALLOC_CONTEXT3 codecContext=avcodec_alloc_context3(NULL); #else codecContext=avcodec_alloc_context(); #endif //HAVE_AVCODEC_ALLOC_CONTEXT3 AVCodec* codec=NULL; videoCodec=codecId; if(codecId==H264) { //TODO: serialize access to avcodec_open const enum CodecID FFMPEGcodecId=CODEC_ID_H264; codec=avcodec_find_decoder(FFMPEGcodecId); assert(codec); //Ignore the frameRateHint as the rate is gathered from the video data } else if(codecId==H263) { //TODO: serialize access to avcodec_open const enum CodecID FFMPEGcodecId=CODEC_ID_FLV1; codec=avcodec_find_decoder(FFMPEGcodecId); assert(codec); //Exploit the frame rate information assert(frameRateHint!=0.0); frameRate=frameRateHint; } else if(codecId==VP6) { //TODO: serialize access to avcodec_open const enum CodecID FFMPEGcodecId=CODEC_ID_VP6F; codec=avcodec_find_decoder(FFMPEGcodecId); assert(codec); //Exploit the frame rate information assert(frameRateHint!=0.0); frameRate=frameRateHint; } if (initdata) { codecContext->extradata=initdata; codecContext->extradata_size=datalen; } #ifdef HAVE_AVCODEC_OPEN2 if(avcodec_open2(codecContext, codec, NULL)<0) #else if(avcodec_open(codecContext, codec)<0) #endif //HAVE_AVCODEC_ALLOC_CONTEXT3 throw RunTimeException("Cannot open decoder"); if(fillDataAndCheckValidity()) status=VALID; else status=INIT; frameIn=avcodec_alloc_frame(); } FFMpegVideoDecoder::FFMpegVideoDecoder(AVCodecContext* _c, double frameRateHint): ownedContext(false),curBuffer(0),codecContext(_c),curBufferOffset(0) { status=INIT; //The tag is the header, initialize decoding switch(codecContext->codec_id) { case CODEC_ID_H264: videoCodec=H264; break; case CODEC_ID_FLV1: videoCodec=H263; break; case CODEC_ID_VP6F: videoCodec=VP6; break; default: return; } AVCodec* codec=avcodec_find_decoder(codecContext->codec_id); #ifdef HAVE_AVCODEC_OPEN2 if(avcodec_open2(codecContext, codec, NULL)<0) #else if(avcodec_open(codecContext, codec)<0) #endif //HAVE_AVCODEC_ALLOC_CONTEXT3 return; frameRate=frameRateHint; if(fillDataAndCheckValidity()) status=VALID; frameIn=avcodec_alloc_frame(); } FFMpegVideoDecoder::~FFMpegVideoDecoder() { while(fenceCount); avcodec_close(codecContext); if(ownedContext) av_free(codecContext); av_free(frameIn); } //setSize is called from the routine that inserts new frames void FFMpegVideoDecoder::setSize(uint32_t w, uint32_t h) { if(VideoDecoder::setSize(w,h)) { //Discard all the frames while(discardFrame()); //As the size chaged, reset the buffer uint32_t bufferSize=frameWidth*frameHeight/**4*/; buffers.regen(YUVBufferGenerator(bufferSize)); } } void FFMpegVideoDecoder::skipUntil(uint32_t time) { while(1) { if(buffers.isEmpty()) break; if(buffers.front().time>=time) break; discardFrame(); } } void FFMpegVideoDecoder::skipAll() { while(!buffers.isEmpty()) discardFrame(); } bool FFMpegVideoDecoder::discardFrame() { Locker locker(mutex); //We don't want ot block if no frame is available bool ret=buffers.nonBlockingPopFront(); if(flushing && buffers.isEmpty()) //End of our work { status=FLUSHED; flushed.signal(); } return ret; } bool FFMpegVideoDecoder::decodeData(uint8_t* data, uint32_t datalen, uint32_t time) { if(datalen==0) return false; int frameOk=0; #if HAVE_AVCODEC_DECODE_VIDEO2 AVPacket pkt; av_init_packet(&pkt); pkt.data=data; pkt.size=datalen; int ret=avcodec_decode_video2(codecContext, frameIn, &frameOk, &pkt); #else int ret=avcodec_decode_video(codecContext, frameIn, &frameOk, data, datalen); #endif assert_and_throw(ret==(int)datalen); if(frameOk) { assert(codecContext->pix_fmt==PIX_FMT_YUV420P); if(status==INIT && fillDataAndCheckValidity()) status=VALID; assert(frameIn->pts==(int64_t)AV_NOPTS_VALUE || frameIn->pts==0); copyFrameToBuffers(frameIn, time); } return true; } bool FFMpegVideoDecoder::decodePacket(AVPacket* pkt, uint32_t time) { int frameOk=0; #if HAVE_AVCODEC_DECODE_VIDEO2 int ret=avcodec_decode_video2(codecContext, frameIn, &frameOk, pkt); #else int ret=avcodec_decode_video(codecContext, frameIn, &frameOk, pkt->data, pkt->size); #endif assert_and_throw(ret==(int)pkt->size); if(frameOk) { assert(codecContext->pix_fmt==PIX_FMT_YUV420P); if(status==INIT && fillDataAndCheckValidity()) status=VALID; assert(frameIn->pts==(int64_t)AV_NOPTS_VALUE || frameIn->pts==0); copyFrameToBuffers(frameIn, time); } return true; } void FFMpegVideoDecoder::copyFrameToBuffers(const AVFrame* frameIn, uint32_t time) { YUVBuffer& curTail=buffers.acquireLast(); //Only one thread may access the tail int offset[3]={0,0,0}; for(uint32_t y=0;ydata[0]+(y*frameIn->linesize[0]),frameWidth); offset[0]+=frameWidth; } for(uint32_t y=0;ydata[1]+(y*frameIn->linesize[1]),frameWidth/2); memcpy(curTail.ch[2]+offset[2],frameIn->data[2]+(y*frameIn->linesize[2]),frameWidth/2); offset[1]+=frameWidth/2; offset[2]+=frameWidth/2; } curTail.time=time; buffers.commitLast(); } void FFMpegVideoDecoder::upload(uint8_t* data, uint32_t w, uint32_t h) const { if(buffers.isEmpty()) return; //Verify that the size are right assert_and_throw(w==((frameWidth+15)&0xfffffff0) && h==frameHeight); //At least a frame is available const YUVBuffer& cur=buffers.front(); fastYUV420ChannelsToYUV0Buffer(cur.ch[0],cur.ch[1],cur.ch[2],data,frameWidth,frameHeight); } void FFMpegVideoDecoder::YUVBufferGenerator::init(YUVBuffer& buf) const { if(buf.ch[0]) { aligned_free(buf.ch[0]); aligned_free(buf.ch[1]); aligned_free(buf.ch[2]); } aligned_malloc((void**)&buf.ch[0], 16, bufferSize); aligned_malloc((void**)&buf.ch[1], 16, bufferSize/4); aligned_malloc((void**)&buf.ch[2], 16, bufferSize/4); } #endif //ENABLE_LIBAVCODEC void* AudioDecoder::operator new(size_t s) { void* retAddr; aligned_malloc(&retAddr, 16, s); return retAddr; } void AudioDecoder::operator delete(void* addr) { aligned_free(addr); } bool AudioDecoder::discardFrame() { //We don't want ot block if no frame is available bool ret=samplesBuffer.nonBlockingPopFront(); if(flushing && samplesBuffer.isEmpty()) //End of our work { status=FLUSHED; flushed.signal(); } return ret; } uint32_t AudioDecoder::copyFrame(int16_t* dest, uint32_t len) { assert(dest); if(samplesBuffer.isEmpty()) return 0; uint32_t frameSize=min(samplesBuffer.front().len,len); memcpy(dest,samplesBuffer.front().current,frameSize); samplesBuffer.front().len-=frameSize; assert(!(samplesBuffer.front().len&0x80000000)); if(samplesBuffer.front().len==0) { samplesBuffer.nonBlockingPopFront(); if(flushing && samplesBuffer.isEmpty()) //End of our work { status=FLUSHED; flushed.signal(); } } else { samplesBuffer.front().current+=frameSize/2; samplesBuffer.front().time+=frameSize/getBytesPerMSec(); } return frameSize; } uint32_t AudioDecoder::getFrontTime() const { assert(!samplesBuffer.isEmpty()); return samplesBuffer.front().time; } void AudioDecoder::skipUntil(uint32_t time, uint32_t usecs) { assert(isValid()); // while(1) //Should loop, but currently only usec adjustements are requested { if(samplesBuffer.isEmpty()) return; FrameSamples& cur=samplesBuffer.front(); assert(time==cur.time); if(usecs==0) //Nothing to skip return; //Check how many bytes are needed to fill the gap uint32_t bytesToDiscard=(time-cur.time)*getBytesPerMSec()+usecs*getBytesPerMSec()/1000; bytesToDiscard&=0xfffffffe; if(cur.len<=bytesToDiscard) //The whole frame is droppable discardFrame(); else { assert((bytesToDiscard%2)==0); cur.len-=bytesToDiscard; assert(!(cur.len&0x80000000)); cur.current+=(bytesToDiscard/2); cur.time=time; return; } } } void AudioDecoder::skipAll() { while(!samplesBuffer.isEmpty()) discardFrame(); } #ifdef ENABLE_LIBAVCODEC FFMpegAudioDecoder::FFMpegAudioDecoder(LS_AUDIO_CODEC audioCodec, uint8_t* initdata, uint32_t datalen):ownedContext(true) { CodecID codecId; switch(audioCodec) { case AAC: codecId=CODEC_ID_AAC; break; case MP3: codecId=CODEC_ID_MP3; break; default: ::abort(); } AVCodec* codec=avcodec_find_decoder(codecId); assert(codec); codecContext=avcodec_alloc_context3(codec); if(initdata) { codecContext->extradata=initdata; codecContext->extradata_size=datalen; } #ifdef HAVE_AVCODEC_OPEN2 if(avcodec_open2(codecContext, codec, NULL)<0) #else if(avcodec_open(codecContext, codec)<0) #endif //HAVE_AVCODEC_ALLOC_CONTEXT3 throw RunTimeException("Cannot open decoder"); if(fillDataAndCheckValidity()) status=VALID; else status=INIT; #if HAVE_AVCODEC_DECODE_AUDIO4 frameIn=avcodec_alloc_frame(); #endif } FFMpegAudioDecoder::FFMpegAudioDecoder(AVCodecContext* _c):codecContext(_c) { status=INIT; AVCodec* codec=avcodec_find_decoder(codecContext->codec_id); assert(codec); #ifdef HAVE_AVCODEC_OPEN2 if(avcodec_open2(codecContext, codec, NULL)<0) #else if(avcodec_open(codecContext, codec)<0) #endif //HAVE_AVCODEC_ALLOC_CONTEXT3 return; if(fillDataAndCheckValidity()) status=VALID; #if HAVE_AVCODEC_DECODE_AUDIO4 frameIn=avcodec_alloc_frame(); #endif } FFMpegAudioDecoder::~FFMpegAudioDecoder() { avcodec_close(codecContext); if(ownedContext) av_free(codecContext); #if HAVE_AVCODEC_DECODE_AUDIO4 av_free(frameIn); #endif } bool FFMpegAudioDecoder::fillDataAndCheckValidity() { if(codecContext->sample_rate!=0) { LOG(LOG_INFO,_("AUDIO DEC: Audio sample rate ") << codecContext->sample_rate); sampleRate=codecContext->sample_rate; } else return false; if(codecContext->channels!=0) { LOG(LOG_INFO, _("AUDIO DEC: Audio channels ") << codecContext->channels); channelCount=codecContext->channels; } else return false; if(initialTime==(uint32_t)-1 && !samplesBuffer.isEmpty()) { initialTime=getFrontTime(); LOG(LOG_INFO,_("AUDIO DEC: Initial timestamp ") << initialTime); } else return false; return true; } uint32_t FFMpegAudioDecoder::decodeData(uint8_t* data, int32_t datalen, uint32_t time) { FrameSamples& curTail=samplesBuffer.acquireLast(); int maxLen=AVCODEC_MAX_AUDIO_FRAME_SIZE; #if HAVE_AVCODEC_DECODE_AUDIO3 || HAVE_AVCODEC_DECODE_AUDIO4 AVPacket pkt; av_init_packet(&pkt); pkt.data=data; pkt.size=datalen; #if HAVE_AVCODEC_DECODE_AUDIO4 avcodec_get_frame_defaults(frameIn); int frameOk=0; int32_t ret=avcodec_decode_audio4(codecContext, frameIn, &frameOk, &pkt); if(frameOk==0) ret=-1; else { //This is suboptimal but equivalent to what libavcodec //does for the compatibility version of avcodec_decode_audio3 memcpy(curTail.samples, frameIn->extended_data[0], frameIn->linesize[0]); maxLen=frameIn->linesize[0]; } #else int32_t ret=avcodec_decode_audio3(codecContext, curTail.samples, &maxLen, &pkt); #endif #else int32_t ret=avcodec_decode_audio2(codecContext, curTail.samples, &maxLen, data, datalen); #endif assert_and_throw(ret==datalen); if(status==INIT && fillDataAndCheckValidity()) status=VALID; curTail.len=maxLen; assert(!(curTail.len&0x80000000)); assert(maxLen%2==0); curTail.current=curTail.samples; curTail.time=time; samplesBuffer.commitLast(); return maxLen; } uint32_t FFMpegAudioDecoder::decodePacket(AVPacket* pkt, uint32_t time) { FrameSamples& curTail=samplesBuffer.acquireLast(); int maxLen=AVCODEC_MAX_AUDIO_FRAME_SIZE; #if HAVE_AVCODEC_DECODE_AUDIO4 avcodec_get_frame_defaults(frameIn); int frameOk=0; int ret=avcodec_decode_audio4(codecContext, frameIn, &frameOk, pkt); if(frameOk==0) ret=-1; else { //This is suboptimal but equivalent to what libavcodec //does for the compatibility version of avcodec_decode_audio3 memcpy(curTail.samples, frameIn->extended_data[0], frameIn->linesize[0]); maxLen=frameIn->linesize[0]; } #elif HAVE_AVCODEC_DECODE_AUDIO3 int ret=avcodec_decode_audio3(codecContext, curTail.samples, &maxLen, pkt); #else int ret=avcodec_decode_audio2(codecContext, curTail.samples, &maxLen, pkt->data, pkt->size); #endif if(ret==-1) { //A decoding error occurred, create an empty sample buffer LOG(LOG_ERROR,_("Malformed audio packet")); curTail.len=0; curTail.current=curTail.samples; curTail.time=time; samplesBuffer.commitLast(); return maxLen; } assert_and_throw(ret==pkt->size); if(status==INIT && fillDataAndCheckValidity()) status=VALID; curTail.len=maxLen; assert(!(curTail.len&0x80000000)); assert(maxLen%2==0); curTail.current=curTail.samples; curTail.time=time; samplesBuffer.commitLast(); return maxLen; } #endif //ENABLE_LIBAVCODEC StreamDecoder::~StreamDecoder() { delete audioDecoder; delete videoDecoder; } #ifdef ENABLE_LIBAVCODEC FFMpegStreamDecoder::FFMpegStreamDecoder(std::istream& s) : audioFound(false),videoFound(false),stream(s),formatCtx(NULL),audioIndex(-1), videoIndex(-1),customAudioDecoder(NULL),customVideoDecoder(NULL),avioContext(NULL) { valid=false; #ifdef HAVE_AVIO_ALLOC_CONTEXT avioContext=avio_alloc_context(avioBuffer,4096,0,this,avioReadPacket,NULL,NULL); #else avioContext=av_alloc_put_byte(avioBuffer,4096,0,this,avioReadPacket,NULL,NULL); #endif if(avioContext==NULL) return; #if LIBAVFORMAT_VERSION_MAJOR > 52 || (LIBAVFORMAT_VERSION_MAJOR == 52 && LIBAVFORMAT_VERSION_MINOR > 64) avioContext->seekable = 0; #else avioContext->is_streamed=1; #endif //Probe the stream format. //NOTE: in FFMpeg 0.7 there is av_probe_input_buffer AVProbeData probeData; probeData.filename="lightspark_stream"; probeData.buf=new uint8_t[8192+AVPROBE_PADDING_SIZE]; memset(probeData.buf,0,8192+AVPROBE_PADDING_SIZE); stream.read((char*)probeData.buf,8192); int read=stream.gcount(); if(read!=8192) LOG(LOG_ERROR,_("Not sufficient data is available from the stream")); probeData.buf_size=read; stream.seekg(0); AVInputFormat* fmt; fmt=av_probe_input_format(&probeData,1); delete[] probeData.buf; if(fmt==NULL) return; #ifdef HAVE_AVIO_ALLOC_CONTEXT formatCtx=avformat_alloc_context(); formatCtx->pb = avioContext; int ret=avformat_open_input(&formatCtx, "lightspark_stream", fmt, NULL); #else int ret=av_open_input_stream(&formatCtx, avioContext, "lightspark_stream", fmt, NULL); #endif if(ret<0) return; #ifdef HAVE_AVFORMAT_FIND_STREAM_INFO ret=avformat_find_stream_info(formatCtx,NULL); #else ret=av_find_stream_info(formatCtx); #endif if(ret<0) return; LOG(LOG_CALLS,_("FFMpeg found ") << formatCtx->nb_streams << _(" streams")); for(uint32_t i=0;inb_streams;i++) { if(formatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO && videoFound==false) { videoFound=true; videoIndex=(int32_t)i; } else if(formatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO && formatCtx->streams[i]->codec->codec_id!=CODEC_ID_NONE && audioFound==false) { audioFound=true; audioIndex=(int32_t)i; } } if(videoFound) { //Pass the frame rate from the container, the once from the codec is often wrong double frameRate=av_q2d(formatCtx->streams[videoIndex]->r_frame_rate); customVideoDecoder=new FFMpegVideoDecoder(formatCtx->streams[videoIndex]->codec,frameRate); videoDecoder=customVideoDecoder; } if(audioFound) { customAudioDecoder=new FFMpegAudioDecoder(formatCtx->streams[audioIndex]->codec); audioDecoder=customAudioDecoder; } valid=true; } FFMpegStreamDecoder::~FFMpegStreamDecoder() { //Delete the decoders before deleting the input stream to avoid a crash in ffmpeg code delete audioDecoder; delete videoDecoder; audioDecoder=NULL; videoDecoder=NULL; if(formatCtx) { #ifdef HAVE_AVIO_ALLOC_CONTEXT #ifdef HAVE_AVFORMAT_CLOSE_INPUT avformat_close_input(&formatCtx); #else av_close_input_file(formatCtx); #endif #else av_close_input_stream(formatCtx); #endif } if(avioContext) av_free(avioContext); } bool FFMpegStreamDecoder::decodeNextFrame() { AVPacket pkt; int ret=av_read_frame(formatCtx, &pkt); if(ret<0) return false; auto time_base=formatCtx->streams[pkt.stream_index]->time_base; //Should use dts uint32_t mtime=pkt.dts*1000*time_base.num/time_base.den; if (pkt.stream_index==(int)audioIndex) { if (customAudioDecoder) customAudioDecoder->decodePacket(&pkt, mtime); } else { if (customVideoDecoder) customVideoDecoder->decodePacket(&pkt, mtime); } av_free_packet(&pkt); return true; } bool FFMpegStreamDecoder::getMetadataInteger(const char* name, uint32_t& ret) const { return false; } bool FFMpegStreamDecoder::getMetadataDouble(const char* name, double& ret) const { if( string(name) == "duration" ) { ret = double(formatCtx->duration) / double(AV_TIME_BASE); return true; } return false; } int FFMpegStreamDecoder::avioReadPacket(void* t, uint8_t* buf, int buf_size) { FFMpegStreamDecoder* th=static_cast(t); th->stream.read((char*)buf,buf_size); int ret=th->stream.gcount(); return ret; } #endif //ENABLE_LIBAVCODEC lightspark-0.7.2/src/backends/decoder.h000066400000000000000000000211201212105246600200020ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_DECODER_H #define BACKENDS_DECODER_H 1 #include "compat.h" #include "threading.h" #include "backends/graphics.h" #ifdef ENABLE_LIBAVCODEC extern "C" { #include #include #define MAX_AUDIO_FRAME_SIZE AVCODEC_MAX_AUDIO_FRAME_SIZE } #else // Correct size? 192000? // TODO: a real plugins system #define MAX_AUDIO_FRAME_SIZE 20 #endif namespace lightspark { enum LS_VIDEO_CODEC { H264=0, H263, VP6 }; enum LS_AUDIO_CODEC { LINEAR_PCM_PLATFORM_ENDIAN=0, ADPCM=1, MP3=2, LINEAR_PCM_LE=3, AAC=10 }; class Decoder { protected: Semaphore flushed; enum STATUS { PREINIT=0, INIT, VALID, FLUSHED}; STATUS status; bool flushing; public: Decoder():flushed(0),status(PREINIT),flushing(false){} virtual ~Decoder(){} bool isValid() const { return status>=VALID; } virtual void setFlushing()=0; void waitFlushed() { flushed.wait(); } }; class VideoDecoder: public Decoder, public ITextureUploadable { public: VideoDecoder():frameRate(0),frameWidth(0),frameHeight(0),fenceCount(0),resizeGLBuffers(false){} virtual ~VideoDecoder(){}; virtual bool decodeData(uint8_t* data, uint32_t datalen, uint32_t time)=0; virtual bool discardFrame()=0; virtual void skipUntil(uint32_t time)=0; virtual void skipAll()=0; uint32_t getWidth() { return frameWidth; } uint32_t getHeight() { return frameHeight; } double frameRate; /* Useful to avoid destruction of the object while a pending upload is waiting */ void waitForFencing(); //ITextureUploadable interface void sizeNeeded(uint32_t& w, uint32_t& h) const; const TextureChunk& getTexture(); void uploadFence(); protected: TextureChunk videoTexture; uint32_t frameWidth; uint32_t frameHeight; /* Derived classes must spinwaits on this to become false before deleting */ ATOMIC_INT32(fenceCount); bool setSize(uint32_t w, uint32_t h); bool resizeIfNeeded(TextureChunk& tex); LS_VIDEO_CODEC videoCodec; private: bool resizeGLBuffers; }; class NullVideoDecoder: public VideoDecoder { public: NullVideoDecoder() {status=VALID;} ~NullVideoDecoder() { while(fenceCount); } bool decodeData(uint8_t* data, uint32_t datalen, uint32_t time){return false;} bool discardFrame(){return false;} void skipUntil(uint32_t time){} void skipAll(){} void setFlushing() { flushing=true; } //ITextureUploadable interface void upload(uint8_t* data, uint32_t w, uint32_t h) const { } }; #ifdef ENABLE_LIBAVCODEC class FFMpegVideoDecoder: public VideoDecoder { private: class YUVBuffer { YUVBuffer(const YUVBuffer&); /* no impl */ YUVBuffer& operator=(const YUVBuffer&); /* no impl */ public: uint8_t* ch[3]; uint32_t time; YUVBuffer():time(0){ch[0]=NULL;ch[1]=NULL;ch[2]=NULL;} ~YUVBuffer() { if(ch[0]) { aligned_free(ch[0]); aligned_free(ch[1]); aligned_free(ch[2]); } } }; class YUVBufferGenerator { private: uint32_t bufferSize; public: YUVBufferGenerator(uint32_t b):bufferSize(b){} void init(YUVBuffer& buf) const; }; bool ownedContext; uint32_t curBuffer; AVCodecContext* codecContext; BlockingCircularQueue buffers; Mutex mutex; AVFrame* frameIn; void copyFrameToBuffers(const AVFrame* frameIn, uint32_t time); void setSize(uint32_t w, uint32_t h); bool fillDataAndCheckValidity(); uint32_t curBufferOffset; public: FFMpegVideoDecoder(LS_VIDEO_CODEC codec, uint8_t* initdata, uint32_t datalen, double frameRateHint); /* Specialized constructor used by FFMpegStreamDecoder */ FFMpegVideoDecoder(AVCodecContext* codecContext, double frameRateHint); ~FFMpegVideoDecoder(); /* Specialized decoding used by FFMpegStreamDecoder */ bool decodePacket(AVPacket* pkt, uint32_t time); bool decodeData(uint8_t* data, uint32_t datalen, uint32_t time); bool discardFrame(); void skipUntil(uint32_t time); void skipAll(); void setFlushing() { flushing=true; if(buffers.isEmpty()) { status=FLUSHED; flushed.signal(); } } //ITextureUploadable interface void upload(uint8_t* data, uint32_t w, uint32_t h) const; }; #endif class AudioDecoder: public Decoder { protected: class FrameSamples { public: int16_t samples[MAX_AUDIO_FRAME_SIZE/2]; __attribute__ ((aligned (16))) int16_t* current; uint32_t len; uint32_t time; FrameSamples():current(samples),len(0),time(0){} }; class FrameSamplesGenerator { public: void init(FrameSamples& f) const {f.len=0;} }; public: uint32_t sampleRate; protected: BlockingCircularQueue samplesBuffer; public: /** The AudioDecoder contains audio buffers that must be aligned to 16 bytes, so we redefine the allocator */ void* operator new(size_t); void operator delete(void*); AudioDecoder():sampleRate(0),channelCount(0),initialTime(-1){} virtual ~AudioDecoder(){}; virtual uint32_t decodeData(uint8_t* data, int32_t datalen, uint32_t time)=0; bool hasDecodedFrames() const { return !samplesBuffer.isEmpty(); } uint32_t getFrontTime() const; uint32_t getBytesPerMSec() const { return sampleRate*channelCount*2/1000; } uint32_t copyFrame(int16_t* dest, uint32_t len) DLL_PUBLIC; /** Skip samples until the given time @param time the desired time in millisecond @param a fractional time in microseconds */ void skipUntil(uint32_t time, uint32_t usecs); /** Skip all the samples */ void skipAll() DLL_PUBLIC; bool discardFrame(); void setFlushing() { flushing=true; if(samplesBuffer.isEmpty()) { status=FLUSHED; flushed.signal(); } } uint32_t channelCount; //Saves the timestamp of the first decoded frame uint32_t initialTime; }; class NullAudioDecoder: public AudioDecoder { public: NullAudioDecoder() { status=VALID; sampleRate=44100; channelCount=2; } uint32_t decodeData(uint8_t* data, int32_t datalen, uint32_t time){return 0;} }; #ifdef ENABLE_LIBAVCODEC class FFMpegAudioDecoder: public AudioDecoder { private: bool ownedContext; AVCodecContext* codecContext; bool fillDataAndCheckValidity(); #if HAVE_AVCODEC_DECODE_AUDIO4 AVFrame* frameIn; #endif public: FFMpegAudioDecoder(LS_AUDIO_CODEC codec, uint8_t* initdata, uint32_t datalen); /* Specialized constructor used by FFMpegStreamDecoder */ FFMpegAudioDecoder(AVCodecContext* codecContext); ~FFMpegAudioDecoder(); /* Specialized decoding used by FFMpegStreamDecoder */ uint32_t decodePacket(AVPacket* pkt, uint32_t time); uint32_t decodeData(uint8_t* data, int32_t datalen, uint32_t time); }; #endif class StreamDecoder { public: StreamDecoder():audioDecoder(NULL),videoDecoder(NULL),valid(false){} virtual ~StreamDecoder(); virtual bool decodeNextFrame() = 0; virtual bool getMetadataInteger(const char* name, uint32_t& ret) const=0; virtual bool getMetadataDouble(const char* name, double& ret) const=0; bool isValid() const { return valid; } AudioDecoder* audioDecoder; VideoDecoder* videoDecoder; protected: bool valid; }; #ifdef ENABLE_LIBAVCODEC class FFMpegStreamDecoder: public StreamDecoder { private: bool audioFound; bool videoFound; std::istream& stream; AVFormatContext* formatCtx; int32_t audioIndex; int32_t videoIndex; //We use our own copy of these to have access of the ffmpeg specific methods FFMpegAudioDecoder* customAudioDecoder; FFMpegVideoDecoder* customVideoDecoder; //Helpers for custom I/O of libavformat uint8_t avioBuffer[4096]; static int avioReadPacket(void* t, uint8_t* buf, int buf_size); //NOTE: this will become AVIOContext in FFMpeg 0.7 #if LIBAVUTIL_VERSION_MAJOR < 51 ByteIOContext* avioContext; #else AVIOContext* avioContext; #endif public: FFMpegStreamDecoder(std::istream& s); ~FFMpegStreamDecoder(); bool decodeNextFrame(); bool getMetadataInteger(const char* name, uint32_t& ret) const; bool getMetadataDouble(const char* name, double& ret) const; }; #endif }; #endif /* BACKENDS_DECODER */ lightspark-0.7.2/src/backends/extscriptobject.cpp000066400000000000000000000317611212105246600221600ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2010-2012 Timon Van Overveldt (timonvo@gmail.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include #include #include "asobject.h" #include "compat.h" #include "scripting/abc.h" #include "scripting/class.h" #include "scripting/toplevel/Array.h" #include "scripting/toplevel/ASString.h" #include "backends/extscriptobject.h" using namespace lightspark; using namespace std; /* -- ExtIdentifier -- */ // Constructors ExtIdentifier::ExtIdentifier() : strValue(""), intValue(0), type(EI_STRING) { } ExtIdentifier::ExtIdentifier(const std::string& value) : strValue(value), intValue(0), type(EI_STRING) { stringToInt(); } ExtIdentifier::ExtIdentifier(const char* value) : strValue(value), intValue(0), type(EI_STRING) { stringToInt(); } ExtIdentifier::ExtIdentifier(int32_t value) : strValue(""), intValue(value), type(EI_INT32) { } ExtIdentifier::ExtIdentifier(const ExtIdentifier& other) { *this=other; } ExtIdentifier& ExtIdentifier::operator=(const ExtIdentifier& other) { type = other.getType(); strValue = other.getString(); intValue = other.getInt(); return *this; } // Convert integer string identifiers to integer identifiers void ExtIdentifier::stringToInt() { char* endptr; intValue = strtol(strValue.c_str(), &endptr, 10); if(*endptr == '\0') type = EI_INT32; } // Comparator bool ExtIdentifier::operator<(const ExtIdentifier& other) const { if(getType() == EI_STRING && other.getType() == EI_STRING) return getString() < other.getString(); else if(getType() == EI_INT32 && other.getType() == EI_INT32) return getInt() < other.getInt(); else if(getType() == EI_INT32 && other.getType() == EI_STRING) return true; return false; } /* -- ExtObject -- */ // Constructors ExtObject::ExtObject() : type(EO_OBJECT) { } ExtObject::ExtObject(const ExtObject& other) { type = other.getType(); other.copy(properties); } // Copying ExtObject& ExtObject::operator=(const ExtObject& other) { setType(other.getType()); other.copy(properties); return *this; } void ExtObject::copy(std::map& dest) const { dest = properties; } // Properties bool ExtObject::hasProperty(const ExtIdentifier& id) const { return properties.find(id) != properties.end(); } const ExtVariant& ExtObject::getProperty(const ExtIdentifier& id) const { std::map::const_iterator it = properties.find(id); assert(it != properties.end()); return it->second; } void ExtObject::setProperty(const ExtIdentifier& id, const ExtVariant& value) { properties[id] = value; } bool ExtObject::removeProperty(const ExtIdentifier& id) { std::map::iterator it = properties.find(id); if(it == properties.end()) return false; properties.erase(it); return true; } bool ExtObject::enumerate(ExtIdentifier*** ids, uint32_t* count) const { *count = properties.size(); *ids = new ExtIdentifier*[properties.size()]; std::map::const_iterator it; int i = 0; for(it = properties.begin(); it != properties.end(); ++it) { (*ids)[i] = new ExtIdentifier(it->first); i++; } return true; } /* -- ExtVariant -- */ // Constructors ExtVariant::ExtVariant() : strValue(""), doubleValue(0), intValue(0), type(EV_VOID), booleanValue(false) { } ExtVariant::ExtVariant(const std::string& value) : strValue(value), doubleValue(0), intValue(0), type(EV_STRING), booleanValue(false) { } ExtVariant::ExtVariant(const char* value) : strValue(value), doubleValue(0), intValue(0), type(EV_STRING), booleanValue(false) { } ExtVariant::ExtVariant(int32_t value) : strValue(""), doubleValue(0), intValue(value), type(EV_INT32), booleanValue(false) { } ExtVariant::ExtVariant(double value) : strValue(""), doubleValue(value), intValue(0), type(EV_DOUBLE), booleanValue(false) { } ExtVariant::ExtVariant(bool value) : strValue(""), doubleValue(0), intValue(0), type(EV_BOOLEAN), booleanValue(value) { } ExtVariant::ExtVariant(std::map>& objectsMap, _R other) : strValue(""), doubleValue(0), intValue(0), booleanValue(false) { switch(other->getObjectType()) { case T_STRING: strValue = other->toString().raw_buf(); type = EV_STRING; break; case T_INTEGER: intValue = other->toInt(); type = EV_INT32; break; case T_NUMBER: doubleValue = other->toNumber(); type = EV_DOUBLE; break; case T_BOOLEAN: booleanValue = Boolean_concrete(other.getPtr()); type = EV_BOOLEAN; break; case T_ARRAY: case T_OBJECT: { type = EV_OBJECT; auto it=objectsMap.find(other.getPtr()); if(it!=objectsMap.end()) { objectValue = it->second.get(); break; } objectValue = new ExtObject(); bool allNumericProperties = true; objectsMap[other.getPtr()] = move(unique_ptr(objectValue)); unsigned int index = 0; while((index=other->nextNameIndex(index))!=0) { _R nextName=other->nextName(index); _R nextValue=other->nextValue(index); if(nextName->getObjectType() == T_INTEGER) objectValue->setProperty(nextName->toInt(), ExtVariant(objectsMap, nextValue)); else { allNumericProperties = false; objectValue->setProperty(nextName->toString().raw_buf(), ExtVariant(objectsMap, nextValue)); } } if(other->getObjectType()==T_ARRAY && allNumericProperties) { objectValue->setType(ExtObject::EO_ARRAY); } } break; case T_NULL: type = EV_NULL; break; case T_UNDEFINED: default: type = EV_VOID; break; } } // Conversion to ASObject ASObject* ExtVariant::getASObject(std::map& objectsMap) const { ASObject* asobj; switch(getType()) { case EV_STRING: asobj = Class::getInstanceS(getString().c_str()); break; case EV_INT32: asobj = abstract_i(getInt()); break; case EV_DOUBLE: asobj = abstract_d(getDouble()); break; case EV_BOOLEAN: asobj = abstract_b(getBoolean()); break; case EV_OBJECT: { ExtObject* objValue = getObject(); auto it=objectsMap.find(objValue); if(it!=objectsMap.end()) { it->second->incRef(); return it->second; } uint32_t count; // We are converting an array, so lets set indexes if(objValue->getType() == ExtObject::EO_ARRAY) { asobj = Class::getInstanceS(); objectsMap[objValue] = asobj; count = objValue->getLength(); static_cast(asobj)->resize(count); for(uint32_t i = 0; i < count; i++) { const ExtVariant& property = objValue->getProperty(i); static_cast(asobj)->set(i, _MR(property.getASObject(objectsMap))); } } // We are converting an object, so lets set variables else { asobj = Class::getInstanceS(); objectsMap[objValue] = asobj; ExtIdentifier** ids; uint32_t count; std::stringstream conv; if(objValue->enumerate(&ids, &count)) { for(uint32_t i = 0; i < count; i++) { const ExtVariant& property = objValue->getProperty(*ids[i]); if(ids[i]->getType() == ExtIdentifier::EI_STRING) { asobj->setVariableByQName(ids[i]->getString(), "", property.getASObject(objectsMap), DYNAMIC_TRAIT); } else { conv.str(""); conv << ids[i]->getInt(); if(asobj->hasPropertyByMultiname(QName(conv.str(),""),true,true)) { LOG(LOG_NOT_IMPLEMENTED,"ExtVariant::getASObject: duplicate property " << conv.str()); continue; } asobj->setVariableByQName(conv.str().c_str(), "", property.getASObject(objectsMap), DYNAMIC_TRAIT); } delete ids[i]; } } delete[] ids; } } break; case EV_NULL: asobj = getSys()->getNullRef(); break; case EV_VOID: default: asobj = getSys()->getUndefinedRef(); break; } return asobj; } /* -- ExtASCallback -- */ ExtASCallback::~ExtASCallback() { func->decRef(); if(asArgs) delete[] asArgs; } void ExtASCallback::call(const ExtScriptObject& so, const ExtIdentifier& id, const ExtVariant** args, uint32_t argc, bool synchronous) { assert(funcEvent == NullRef); // Explanation for argument "synchronous": // Take a callback which (indirectly) calls another callback, while running in the VM thread. // The parent waits for the result of the second. (hence, the VM is suspended) // If the second callback would also try to execute in the VM thread, it would only // get executed when the parent had completed, since the event/function queue is FIFO. // This would result in a deadlock. Therefore, we run the function straight away. // The caller indicated the VM isn't currently suspended, // so add a FunctionEvent to the VM event queue. // Convert ExtVariant arguments to ASObjects assert(!asArgs); asArgs = new ASObject*[argc]; std::map objectsMap; for(uint32_t i = 0; i < argc; i++) asArgs[i] = args[i]->getASObject(objectsMap); if(!synchronous) { func->incRef(); funcEvent = _MR(new (getSys()->unaccountedMemory) ExternalCallEvent(_MR(func), asArgs, argc, &result, &exceptionThrown, &exception)); // Add the callback function event to the VM event queue funcWasCalled=getVm()->addEvent(NullRef,funcEvent); if(!funcWasCalled) funcEvent = NullRef; } // The caller indicated the VM is currently suspended, so call synchronously. else { try { /* TODO: shouldn't we pass some global object instead of Null? */ result = func->call(getSys()->getNullRef(), asArgs, argc); } // Catch AS exceptions and pass them on catch(ASObject* _exception) { exception = _exception->toString(); } // Catch LS exceptions and report them catch(LightsparkException& e) { LOG(LOG_ERROR, "LightsparkException caught in external callback, cause: " << e.what()); getSys()->setError(e.cause); } funcWasCalled = true; delete[] asArgs; asArgs = NULL; } } void ExtASCallback::wait() { if(!funcEvent.isNull()) funcEvent->done.wait(); } void ExtASCallback::wakeUp() { if(!funcEvent.isNull()) funcEvent->done.signal(); } bool ExtASCallback::getResult(std::map>& objectsMap, const ExtScriptObject& so, const ExtVariant** _result) { funcEvent = NullRef; // Did the callback throw an AS exception? if(exceptionThrown) { if(result != NULL) { result->decRef(); result = NULL; } // Pass on the exception to the container through the script object so.setException(exception.raw_buf()); LOG(LOG_ERROR, "ASObject exception caught in external callback"); success = false; } // There was an error executing the function else if(!funcWasCalled) { success = false; } // Did the callback return a non-NULL result? else if(result != NULL) { // Convert the result *_result = new ExtVariant(objectsMap, _MR(result)); success = true; } // No exception but also no result, still a success else success = true; // Clean up pointers result = NULL; exceptionThrown = false; exception = ""; if (asArgs) { // The references have been consumed by the called // function. We only delete the array. delete[] asArgs; asArgs = NULL; } return success; } /* -- ExtBuiltinCallback -- */ void ExtBuiltinCallback::call(const ExtScriptObject& so, const ExtIdentifier& id, const ExtVariant** args, uint32_t argc, bool synchronous) { try { // We expect the builtin callback to handle main <--> VM thread synchronization by itself success = func(so, id, args, argc, &result); } // Catch AS exceptions and pass them on catch(ASObject* _exception) { exceptionThrown = true; exception = _exception->toString(); _exception->decRef(); } // Catch LS exceptions and report them catch(LightsparkException& e) { LOG(LOG_ERROR, "LightsparkException caught in external callback, cause: " << e.what()); getSys()->setError(e.cause); success = false; } } void ExtBuiltinCallback::wait() { } void ExtBuiltinCallback::wakeUp() { } bool ExtBuiltinCallback::getResult(std::map>& objectsMap, const ExtScriptObject& so, const ExtVariant** _result) { // Set the result *_result = result; // Did the callback throw an AS exception? if(exceptionThrown) { so.setException(exception.raw_buf()); LOG(LOG_ERROR, "ASObject exception caught in external callback"); return false; } return success; } lightspark-0.7.2/src/backends/extscriptobject.h000066400000000000000000000230721212105246600216210ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2010-2012 Timon Van Overveldt (timonvo@gmail.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_EXTSCRIPTOBJECT_H #define BACKENDS_EXTSCRIPTOBJECT_H 1 #include #include #include #include "asobject.h" #include "compat.h" #include "scripting/flash/events/flashevents.h" namespace lightspark { /** * ExtIdentifiers are the basic identifiers for interfacing with an external container. * They can represent: int & string datatypes. * They are used to name properties of objects throughout ExtScriptObject. * * This class can be extended to fit a specific interface (e.g.: NPIdentifierObject & NPRuntime). * These subclasses should provide a means to convert an ExtIdentifier. * This way, subclasses of ExtIdentifiers can transparently work with different subclasses of ExtIdentifier. */ class DLL_PUBLIC ExtIdentifier { public: ExtIdentifier(); ExtIdentifier(const std::string& value); ExtIdentifier(const char* value); ExtIdentifier(int32_t value); ExtIdentifier(const ExtIdentifier& other); virtual ~ExtIdentifier() {} // Since these objects get used as keys in std::maps, they need to be comparable. virtual bool operator<(const ExtIdentifier& other) const; // Since this class is used as keys in property maps // it must implement a proper copy operator that must // deal with any subclass by acquiring the contents in // the internal data structures ExtIdentifier& operator=(const ExtIdentifier& other); enum EI_TYPE { EI_STRING, EI_INT32 }; virtual EI_TYPE getType() const { return type; } // These methods return the value of the ExtIdentifier. // Returned values for non-matching types are undefined. virtual std::string getString() const { return strValue; } virtual int32_t getInt() const { return intValue; } private: std::string strValue; int32_t intValue; EI_TYPE type; void stringToInt(); }; class ExtVariant; /** * This class represents an object containing key-value pairs * of ExtIdentifiers & ExtVariants. */ class DLL_PUBLIC ExtObject { public: ExtObject(); ExtObject(const ExtObject& other); virtual ~ExtObject() {} ExtObject& operator=(const ExtObject& other); void copy(std::map& dest) const; bool hasProperty(const ExtIdentifier& id) const; /* * NOTE: The caller must make sure that the property exists * using hasProperty */ const ExtVariant& getProperty(const ExtIdentifier& id) const; void setProperty(const ExtIdentifier& id, const ExtVariant& value); bool removeProperty(const ExtIdentifier& id); bool enumerate(ExtIdentifier*** ids, uint32_t* count) const; uint32_t getLength() const { return properties.size(); } enum EO_TYPE { EO_OBJECT, EO_ARRAY }; EO_TYPE getType() const { return type; } void setType(EO_TYPE _type) { type = _type; } protected: std::map properties; EO_TYPE type; }; /** * ExtVariants are the basic datatype for interfacing with an external container. * They can represent: void, null, string, int32, double & boolean datatypes. * They are used throughout the ExtScriptObject to pass & return data. * * This class can be extended to fit a specific interface (e.g.: NPVariantObject & NPRuntime). * These subclasses should provide a means to convert an ExtVariant. * This way, subclasses of ExtScriptObject can transparently * work with different subclasses of ExtVariant. * This class is also able to convert an ASObject* to an ExtVariant and the other way around. */ class DLL_PUBLIC ExtVariant { public: ExtVariant(); ExtVariant(const std::string& value); ExtVariant(const char* value); ExtVariant(int32_t value); ExtVariant(double value); ExtVariant(bool value); ExtVariant(std::map>& objectsMap, _R other); ~ExtVariant() {} enum EV_TYPE { EV_STRING, EV_INT32, EV_DOUBLE, EV_BOOLEAN, EV_OBJECT, EV_NULL, EV_VOID }; EV_TYPE getType() const { return type; } // These methods return the value of the ExtVariant. // Returned values for non-matching types are undefined. // As such, don't get a string value for an integer ExtVariant std::string getString() const { return strValue; } int32_t getInt() const { return intValue; } double getDouble() const { return doubleValue; } bool getBoolean() const { return booleanValue; } /* * ExtObject instances are always owned by the objectMaps */ ExtObject* getObject() const { return objectValue; } ASObject* getASObject(std::map& objectsMap) const; protected: std::string strValue; ExtObject* objectValue; double doubleValue; int32_t intValue; EV_TYPE type; bool booleanValue; }; class ExtScriptObject; /** * This class provides an interface to use for external callback functions. */ class DLL_PUBLIC ExtCallback { public: ExtCallback() : success(false), exceptionThrown(false) {} virtual ~ExtCallback() {} // Don't forget to delete this copy after use virtual ExtCallback* copy()=0; virtual void call(const ExtScriptObject& so, const ExtIdentifier& id, const ExtVariant** args, uint32_t argc, bool synchronous)=0; virtual void wait()=0; virtual void wakeUp()=0; // The result variable should be "delete"d by the caller after use. virtual bool getResult(std::map>& objectsMap, const ExtScriptObject& so, const ExtVariant** result)=0; protected: tiny_string exception; bool success; bool exceptionThrown; }; class ExternalCallEvent; /** * ExtCallback specialization for IFunctions */ class DLL_PUBLIC ExtASCallback : public ExtCallback { private: bool funcWasCalled; IFunction* func; _NR funcEvent; ASObject* result; ASObject** asArgs; public: ExtASCallback(IFunction* _func) :funcWasCalled(false), func(_func), result(NULL), asArgs(NULL) { func->incRef(); } ~ExtASCallback(); // Don't forget to delete this copy after use ExtASCallback* copy() { return new ExtASCallback(func); } void call(const ExtScriptObject& so, const ExtIdentifier& id, const ExtVariant** args, uint32_t argc, bool synchronous); void wait(); void wakeUp(); // The result variable should be "delete"d by the caller after use. bool getResult(std::map>& objectsMap, const ExtScriptObject& so, const ExtVariant** _result); }; /** * ExtCallback specialization for builtin functions */ class DLL_PUBLIC ExtBuiltinCallback : public ExtCallback { public: // The signature for a hard-coded callback function. typedef bool (*funcPtr)(const ExtScriptObject& so, const ExtIdentifier& id, const ExtVariant** args, uint32_t argc, const ExtVariant** result); ExtBuiltinCallback(funcPtr _func) : func(_func), result(NULL) {} ~ExtBuiltinCallback() {} // Don't forget to delete this copy after use ExtBuiltinCallback* copy() { return new ExtBuiltinCallback(func); } void call(const ExtScriptObject& so, const ExtIdentifier& id, const ExtVariant** args, uint32_t argc, bool synchronous); void wait(); void wakeUp(); // The result variable should be "delete"d by the caller after use. bool getResult(std::map>& objectsMap, const ExtScriptObject& so, const ExtVariant** _result); private: funcPtr func; const ExtVariant* result; }; /** * An ExtScriptObject represents the interface LS presents to the external container. * There should be a 1-to-1 relationship between LS instances & ExtScriptObjects. * * ExtScriptObjects can present properties & methods to the external container. * Both are identified by an ExtIdentifier (or an object of a derived class). * Properties have a value of type ExtVariant (or a derived type). */ class DLL_PUBLIC ExtScriptObject { public: virtual ~ExtScriptObject() {}; virtual bool hasMethod(const ExtIdentifier& id) const = 0; // There currently is no way to invoke the set methods. There's no need for it anyway. virtual void setMethod(const ExtIdentifier& id, ExtCallback* func) = 0; virtual bool removeMethod(const ExtIdentifier& id) = 0; virtual bool hasProperty(const ExtIdentifier& id) const = 0; /* * NOTE: The caller must make sure that the property exists * using hasProperty */ virtual const ExtVariant& getProperty(const ExtIdentifier& id) const = 0; virtual void setProperty(const ExtIdentifier& id, const ExtVariant& value) = 0; virtual bool removeProperty(const ExtIdentifier& id) = 0; virtual bool enumerate(ExtIdentifier*** ids, uint32_t* count) const = 0; virtual bool callExternal(const ExtIdentifier& id, const ExtVariant** args, uint32_t argc, ASObject** result) = 0; virtual void setException(const std::string& message) const = 0; virtual void setMarshallExceptions(bool marshall) = 0; virtual bool getMarshallExceptions() const = 0; }; }; #endif /* BACKENDS_EXTSCRIPTOBJECT_H */ lightspark-0.7.2/src/backends/geometry.cpp000066400000000000000000000157711212105246600206020ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include #include #include #include "swftypes.h" #include "logger.h" #include "backends/geometry.h" #include "compat.h" #include "scripting/flash/display/flashdisplay.h" #include "scripting/flash/display/BitmapData.h" using namespace std; using namespace lightspark; bool ShapesBuilder::isOutlineEmpty(const std::vector& outline) { return outline.empty(); } void ShapesBuilder::clear() { filledShapesMap.clear(); strokeShapesMap.clear(); } void ShapesBuilder::joinOutlines() { map< unsigned int, vector< vector > >::iterator it=filledShapesMap.begin(); for(;it!=filledShapesMap.end();++it) { vector< vector >& outlinesForColor=it->second; //Repack outlines of the same color, avoiding excessive copying for(int i=0;i=2); //Already closed paths are ok if(outlinesForColor[i].front()==outlinesForColor[i].back()) continue; for(int j=outlinesForColor.size()-1;j>=0;j--) { if(j==i || outlinesForColor[j].empty()) continue; if(outlinesForColor[i].front()==outlinesForColor[j].back()) { //Copy all the vertex but the origin in this one outlinesForColor[j].insert(outlinesForColor[j].end(), outlinesForColor[i].begin()+1, outlinesForColor[i].end()); //Invalidate the origin, but not the high level vector outlinesForColor[i].clear(); break; } else if(outlinesForColor[i].back()==outlinesForColor[j].back()) { //CHECK: this works for adjacent shapes of the same color? //Copy all the vertex but the origin in this one for (int k = outlinesForColor[i].size()-2; k >= 0; k--) outlinesForColor[j].emplace_back(ShapePathSegment(outlinesForColor[i][k+1].type, outlinesForColor[i][k].i)); //Invalidate the origin, but not the high level vector outlinesForColor[i].clear(); break; } } } //Kill all the empty outlines outlinesForColor.erase(remove_if(outlinesForColor.begin(),outlinesForColor.end(), isOutlineEmpty), outlinesForColor.end()); } } unsigned int ShapesBuilder::makeVertex(const Vector2& v) { map::const_iterator it=verticesMap.find(v); if(it!=verticesMap.end()) return it->second; unsigned int i = verticesMap.size(); verticesMap.insert(make_pair(v, i)); return i; } void ShapesBuilder::extendFilledOutlineForColor(unsigned int color, const Vector2& v1, const Vector2& v2) { assert_and_throw(color); //Find the indices of the vertex unsigned int v1Index = makeVertex(v1); unsigned int v2Index = makeVertex(v2); vector< vector >& outlinesForColor=filledShapesMap[color]; //Search a suitable outline to attach this new vertex for(unsigned int i=0;i=2); if(outlinesForColor[i].front()==outlinesForColor[i].back()) continue; if(outlinesForColor[i].back().i==v1Index) { outlinesForColor[i].push_back(ShapePathSegment(PATH_STRAIGHT, v2Index)); return; } } //No suitable outline found, create one vector vertices; vertices.reserve(2); vertices.push_back(ShapePathSegment(PATH_START, v1Index)); vertices.push_back(ShapePathSegment(PATH_STRAIGHT, v2Index)); outlinesForColor.push_back(vertices); } void ShapesBuilder::extendFilledOutlineForColorCurve(unsigned int color, const Vector2& v1, const Vector2& v2, const Vector2& v3) { assert_and_throw(color); //Find the indices of the vertex unsigned int v1Index = makeVertex(v1); unsigned int v2Index = makeVertex(v2); unsigned int v3Index = makeVertex(v3); vector< vector >& outlinesForColor=filledShapesMap[color]; //Search a suitable outline to attach this new vertex for(unsigned int i=0;i=2); if(outlinesForColor[i].front()==outlinesForColor[i].back()) continue; if(outlinesForColor[i].back().i==v1Index) { outlinesForColor[i].emplace_back(ShapePathSegment(PATH_CURVE_QUADRATIC, v2Index)); outlinesForColor[i].emplace_back(ShapePathSegment(PATH_CURVE_QUADRATIC, v3Index)); return; } } //No suitable outline found, create one vector vertices; vertices.reserve(2); vertices.emplace_back(ShapePathSegment(PATH_START, v1Index)); vertices.emplace_back(ShapePathSegment(PATH_CURVE_QUADRATIC, v2Index)); vertices.emplace_back(ShapePathSegment(PATH_CURVE_QUADRATIC, v3Index)); outlinesForColor.push_back(vertices); } const Vector2& ShapesBuilder::getVertex(unsigned int index) { //Linear lookup map::const_iterator it=verticesMap.begin(); for(;it!=verticesMap.end();++it) { if(it->second==index) return it->first; } ::abort(); } void ShapesBuilder::outputTokens(const std::list& styles, tokensVector& tokens) { joinOutlines(); //Try to greedily condense as much as possible the output map< unsigned int, vector< vector > >::iterator it=filledShapesMap.begin(); //For each color for(;it!=filledShapesMap.end();++it) { assert(!it->second.empty()); //Find the style given the index std::list::const_iterator stylesIt=styles.begin(); assert(it->first); for(unsigned int i=0;ifirst-1;i++) { ++stylesIt; assert(stylesIt!=styles.end()); } //Set the fill style tokens.emplace_back(GeomToken(SET_FILL,*stylesIt)); vector >& outlinesForColor=it->second; for(unsigned int i=0;i& segments=outlinesForColor[i]; assert (segments[0].type == PATH_START); tokens.push_back(GeomToken(MOVE, getVertex(segments[0].i))); for(unsigned int j=1;j. **************************************************************************/ #ifndef BACKENDS_GEOMETRY_H #define BACKENDS_GEOMETRY_H 1 #include "compat.h" #include "swftypes.h" #include #include #include namespace lightspark { template class Vector2Tmpl { public: T x,y; Vector2Tmpl(T a=0, T b=0):x(a),y(b){} /* conversion Vector2 -> Vector2f is implicit */ Vector2Tmpl(const Vector2Tmpl& o) : x(o.x),y(o.y) {} /* conversion Vector2f -> Vector2 is explicit */ Vector2Tmpl round() const { return Vector2Tmpl(x,y); } bool operator==(const Vector2Tmpl& v)const{return v.x==x && v.y==y;} bool operator!=(const Vector2Tmpl& v)const{return v.x!=x || v.y!=y;} bool operator<(const Vector2Tmpl& v) const {return (y==v.y)?(x < v.x):(y < v.y);} Vector2Tmpl operator-() const { return Vector2Tmpl(-x,-y); } Vector2Tmpl operator-(const Vector2Tmpl& v)const { return Vector2Tmpl(x-v.x,y-v.y);} Vector2Tmpl operator+(const Vector2Tmpl& v)const { return Vector2Tmpl(x+v.x,y+v.y);} Vector2Tmpl& operator+=(const Vector2Tmpl& v){ x+=v.x; y+=v.y; return *this;} Vector2Tmpl operator*(int p)const { return Vector2Tmpl(x*p,y*p);} Vector2Tmpl& operator/=(T v) { x/=v; y/=v; return *this;} int dot(const Vector2Tmpl& r) const { return x*r.x+y*r.y;} Vector2Tmpl projectInto(const RECT& r) const { Vector2Tmpl out; out.x = maxTmpl(minTmpl(x,r.Xmax),r.Xmin); out.y = maxTmpl(minTmpl(y,r.Ymax),r.Ymin); return out; } std::ostream& operator<<(std::ostream& s) { s << "{ "<< x << ',' << y << " }"; return s; } }; enum GEOM_TOKEN_TYPE { STRAIGHT=0, CURVE_QUADRATIC, MOVE, SET_FILL, SET_STROKE, CLEAR_FILL, CLEAR_STROKE, CURVE_CUBIC, FILL_KEEP_SOURCE, FILL_TRANSFORM_TEXTURE }; class GeomToken { public: FILLSTYLE fillStyle; LINESTYLE2 lineStyle; MATRIX textureTransform; GEOM_TOKEN_TYPE type; Vector2 p1; Vector2 p2; Vector2 p3; GeomToken(GEOM_TOKEN_TYPE _t):fillStyle(0xff),lineStyle(0xff),type(_t),p1(0,0),p2(0,0),p3(0,0){} GeomToken(GEOM_TOKEN_TYPE _t, const Vector2& _p):fillStyle(0xff),lineStyle(0xff),type(_t),p1(_p),p2(0,0),p3(0,0){} GeomToken(GEOM_TOKEN_TYPE _t, const Vector2& _p1, const Vector2& _p2):fillStyle(0xff),lineStyle(0xff),type(_t),p1(_p1),p2(_p2),p3(0,0){} GeomToken(GEOM_TOKEN_TYPE _t, const Vector2& _p1, const Vector2& _p2, const Vector2& _p3):fillStyle(0xff),lineStyle(0xff),type(_t), p1(_p1),p2(_p2),p3(_p3){} GeomToken(GEOM_TOKEN_TYPE _t, const FILLSTYLE _f):fillStyle(_f),lineStyle(0xff),type(_t),p1(0,0),p2(0,0),p3(0,0){} GeomToken(GEOM_TOKEN_TYPE _t, const LINESTYLE2 _s):fillStyle(0xff),lineStyle(_s),type(_t),p1(0,0),p2(0,0),p3(0,0){} GeomToken(GEOM_TOKEN_TYPE _t, const MATRIX _m):fillStyle(0xff),lineStyle(0xff),textureTransform(_m),type(_t),p1(0,0),p2(0,0),p3(0,0){} }; typedef std::vector> tokensVector; enum SHAPE_PATH_SEGMENT_TYPE { PATH_START=0, PATH_STRAIGHT, PATH_CURVE_QUADRATIC }; class ShapePathSegment { public: SHAPE_PATH_SEGMENT_TYPE type; unsigned int i; ShapePathSegment(SHAPE_PATH_SEGMENT_TYPE _t, unsigned int _i):type(_t),i(_i){} bool operator==(const ShapePathSegment& v)const{return v.i == i;} }; class ShapesBuilder { private: std::map< Vector2, unsigned int > verticesMap; std::map< unsigned int, std::vector< std::vector > > filledShapesMap; std::map< unsigned int, std::vector< std::vector > > strokeShapesMap; void joinOutlines(); static bool isOutlineEmpty(const std::vector& outline); static void extendOutlineForColor(std::map< unsigned int, std::vector< std::vector > >& map); unsigned int makeVertex(const Vector2& v); const Vector2& getVertex(unsigned int index); public: void extendFilledOutlineForColor(unsigned int fillColor, const Vector2& v1, const Vector2& v2); void extendFilledOutlineForColorCurve(unsigned int color, const Vector2& start, const Vector2& control, const Vector2& end); void extendStrokeOutlineForColor(unsigned int stroke, const Vector2& v1, const Vector2& v2); /** Generate a sequence of cachable tokens that defines the geomtries @param styles This list is supposed to survive until as long as the returned tokens array @param tokens A vector that will be filled with tokens */ void outputTokens(const std::list& styles, tokensVector& tokens); void clear(); }; std::ostream& operator<<(std::ostream& s, const Vector2& p); }; #endif /* BACKENDS_GEOMETRY_H */ lightspark-0.7.2/src/backends/graphics.cpp000066400000000000000000000637651212105246600205550ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include #include "swf.h" #include "backends/graphics.h" #include "logger.h" #include "exceptions.h" #include "backends/rendering.h" #include "backends/config.h" #include "compat.h" #include "scripting/flash/text/flashtext.h" #include "scripting/flash/display/BitmapData.h" using namespace lightspark; void TextureBuffer::setAllocSize(uint32_t w, uint32_t h) { if(getRenderThread()->hasNPOTTextures) { allocWidth=w; allocHeight=h; //Now adjust for the requested alignment if((allocWidth%horizontalAlignment)) { allocWidth+=horizontalAlignment; allocWidth-=(allocWidth%horizontalAlignment); } if((allocHeight%verticalAlignment)) { allocHeight+=verticalAlignment; allocHeight-=(allocHeight%verticalAlignment); } } else { allocWidth=nearestPOT(w); allocHeight=nearestPOT(h); //Assert that the requested alignment is satisfied assert((allocWidth%horizontalAlignment)==0); assert((allocHeight%verticalAlignment)==0); } } uint32_t TextureBuffer::nearestPOT(uint32_t a) const { if(a==0) return 0; uint32_t ret=1; while(retallocWidth || h>allocHeight) //Destination texture should be reallocated { glBindTexture(GL_TEXTURE_2D,texId); LOG(LOG_CALLS,_("Reallocating texture to size ") << w << 'x' << h); setAllocSize(w,h); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, allocWidth, allocHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0); if(GLRenderContext::handleGLErrors()) { LOG(LOG_ERROR,_("OpenGL error in TextureBuffer::resize")); throw RunTimeException("OpenGL error in TextureBuffer::resize"); } } width=w; height=h; } } void TextureBuffer::setRequestedAlignment(uint32_t w, uint32_t h) { assert(w && h); horizontalAlignment=w; verticalAlignment=h; } void TextureBuffer::setTexScale(GLuint uniformLocation) { float v1=width; float v2=height; v1/=allocWidth; v2/=allocHeight; glUniform2f(uniformLocation,v1,v2); } void TextureBuffer::bind() { glBindTexture(GL_TEXTURE_2D,texId); } void TextureBuffer::unbind() { glBindTexture(GL_TEXTURE_2D,0); } void TextureBuffer::shutdown() { if(inited) { glDeleteTextures(1,&texId); inited=false; } } TextureBuffer::~TextureBuffer() { shutdown(); } TextureChunk::TextureChunk(uint32_t w, uint32_t h) { width=w; height=h; if(w==0 || h==0) { chunks=NULL; return; } const uint32_t blocksW=(w+CHUNKSIZE-1)/CHUNKSIZE; const uint32_t blocksH=(h+CHUNKSIZE-1)/CHUNKSIZE; chunks=new uint32_t[blocksW*blocksH]; } TextureChunk::TextureChunk(const TextureChunk& r):chunks(NULL),texId(0),width(r.width),height(r.height) { *this = r; return; } TextureChunk& TextureChunk::operator=(const TextureChunk& r) { if(chunks) { //We were already initialized, so first clean up getSys()->getRenderThread()->releaseTexture(*this); delete[] chunks; } width=r.width; height=r.height; uint32_t blocksW=(width+CHUNKSIZE-1)/CHUNKSIZE; uint32_t blocksH=(height+CHUNKSIZE-1)/CHUNKSIZE; texId=r.texId; if(r.chunks) { chunks=new uint32_t[blocksW*blocksH]; memcpy(chunks, r.chunks, blocksW*blocksH*4); } else chunks=NULL; return *this; } TextureChunk::~TextureChunk() { delete[] chunks; } void TextureChunk::makeEmpty() { width=0; height=0; texId=0; delete[] chunks; chunks=NULL; } bool TextureChunk::resizeIfLargeEnough(uint32_t w, uint32_t h) { if(w==0 || h==0) { //The texture collapsed, release the resources getSys()->getRenderThread()->releaseTexture(*this); delete[] chunks; chunks=NULL; width=w; height=h; return true; } const uint32_t blocksW=(width+CHUNKSIZE-1)/CHUNKSIZE; const uint32_t blocksH=(height+CHUNKSIZE-1)/CHUNKSIZE; if(w<=blocksW*CHUNKSIZE && h<=blocksH*CHUNKSIZE) { width=w; height=h; return true; } return false; } CairoRenderer::CairoRenderer(const MATRIX& _m, int32_t _x, int32_t _y, int32_t _w, int32_t _h, float _s, float _a, const std::vector& _ms) : IDrawable(_w, _h, _x, _y, _a, _ms), scaleFactor(_s), matrix(_m) { } void CairoTokenRenderer::quadraticBezier(cairo_t* cr, double control_x, double control_y, double end_x, double end_y) { double start_x, start_y; cairo_get_current_point(cr, &start_x, &start_y); double control_1x = control_x*(2.0/3.0) + start_x*(1.0/3.0); double control_1y = control_y*(2.0/3.0) + start_y*(1.0/3.0); double control_2x = control_x*(2.0/3.0) + end_x*(1.0/3.0); double control_2y = control_y*(2.0/3.0) + end_y*(1.0/3.0); cairo_curve_to(cr, control_1x, control_1y, control_2x, control_2y, end_x, end_y); } cairo_pattern_t* CairoTokenRenderer::FILLSTYLEToCairo(const FILLSTYLE& style, double scaleCorrection) { cairo_pattern_t* pattern = NULL; switch(style.FillStyleType) { case SOLID_FILL: { const RGBA& color = style.Color; pattern = cairo_pattern_create_rgba(color.rf(), color.gf(), color.bf(), color.af()); break; } case LINEAR_GRADIENT: case RADIAL_GRADIENT: { const GRADIENT& grad = style.Gradient; // We want an opaque black background... a gradient with no stops // in cairo will give us transparency. if (grad.GradientRecords.size() == 0) { pattern = cairo_pattern_create_rgb(0, 0, 0); return pattern; } MATRIX tmp=style.Matrix; tmp.x0/=scaleCorrection; tmp.y0/=scaleCorrection; // The dimensions of the pattern space are specified in SWF specs // as a 32768x32768 box centered at (0,0) if (style.FillStyleType == LINEAR_GRADIENT) { double x0,y0,x1,y1; tmp.multiply2D(-16384.0, 0,x0,y0); tmp.multiply2D(16384.0, 0,x1,y1); pattern = cairo_pattern_create_linear(x0,y0,x1,y1); } else { double x0,y0; //Center of the circles double x1,y1; //Point on the circle edge at 0° tmp.multiply2D(0, 0,x0,y0); tmp.multiply2D(16384.0, 0,x1,y1); double radius=sqrt(x1*x1+y1*y1); pattern = cairo_pattern_create_radial(x0, y0, 0, x0, y0, radius); } if (grad.SpreadMode == 0) // PAD cairo_pattern_set_extend(pattern, CAIRO_EXTEND_PAD); else if (grad.SpreadMode == 1) // REFLECT cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REFLECT); else if (grad.SpreadMode == 2) // REPEAT cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); for(uint32_t i=0;i bm(style.bitmap); if(bm.isNull()) return NULL; //Do an explicit cast, the data will not be modified cairo_surface_t* surface = cairo_image_surface_create_for_data ((uint8_t*)bm->getData(), CAIRO_FORMAT_ARGB32, bm->getWidth(), bm->getHeight(), cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, bm->getWidth())); pattern = cairo_pattern_create_for_surface(surface); cairo_surface_destroy(surface); //Make a copy to invert it cairo_matrix_t mat=style.Matrix; cairo_status_t st = cairo_matrix_invert(&mat); assert(st == CAIRO_STATUS_SUCCESS); (void)st; // silence warning about unused variable mat.x0 /= scaleCorrection; mat.y0 /= scaleCorrection; cairo_pattern_set_matrix (pattern, &mat); assert(cairo_pattern_status(pattern) == CAIRO_STATUS_SUCCESS); if(style.FillStyleType == NON_SMOOTHED_REPEATING_BITMAP || style.FillStyleType == REPEATING_BITMAP) cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); else cairo_pattern_set_extend(pattern, CAIRO_EXTEND_PAD); if(style.FillStyleType == NON_SMOOTHED_REPEATING_BITMAP || style.FillStyleType == NON_SMOOTHED_CLIPPED_BITMAP) cairo_pattern_set_filter(pattern, CAIRO_FILTER_NEAREST); else cairo_pattern_set_filter(pattern, CAIRO_FILTER_BILINEAR); break; } default: LOG(LOG_NOT_IMPLEMENTED, "Unsupported fill style " << (int)style.FillStyleType); return NULL; } return pattern; } bool CairoTokenRenderer::cairoPathFromTokens(cairo_t* cr, const std::vector& tokens, double scaleCorrection, bool skipPaint) { cairo_scale(cr, scaleCorrection, scaleCorrection); bool empty=true; cairo_t *stroke_cr = cairo_create(cairo_get_group_target(cr)); cairo_push_group(stroke_cr); // Make sure not to draw anything until a fill is set. cairo_set_operator(stroke_cr, CAIRO_OPERATOR_DEST); cairo_set_operator(cr, CAIRO_OPERATOR_DEST); #define PATH(operation, args...) \ operation(cr, ## args); \ operation(stroke_cr, ## args); for(uint32_t i=0;iisRenderingEnabled()) return NULL; int32_t windowWidth=getSys()->getRenderThread()->windowWidth; int32_t windowHeight=getSys()->getRenderThread()->windowHeight; //Discard stuff that it's outside the visible part if(xOffset >= windowWidth || yOffset >= windowHeight || xOffset + width <= 0 || yOffset + height <= 0) { width=0; height=0; return NULL; } if(xOffset<0) { width+=xOffset; xOffset=0; } if(yOffset<0) { height+=yOffset; yOffset=0; } //Clip the size to the screen borders if((xOffset>0) && (width+xOffset) > windowWidth) width=windowWidth-xOffset; if((yOffset>0) && (height+yOffset) > windowHeight) height=windowHeight-yOffset; uint8_t* ret=NULL; cairo_surface_t* cairoSurface=allocateSurface(ret); cairo_t* cr=cairo_create(cairoSurface); cairo_surface_destroy(cairoSurface); /* cr has an reference to it */ cairoClean(cr); //Make sure the rendering starts at 0,0 in surface coordinates //This also guarantees that all the shape fills in width/height pixels //We don't translate for negative offsets as we don't want to see what's in negative coords if(xOffset >= 0) matrix.x0-=xOffset; if(yOffset >= 0) matrix.y0-=yOffset; //Apply all the masks to clip the drawn part for(uint32_t i=0;iapplyCairoMask(cr,xOffset,yOffset); } cairo_set_matrix(cr, &matrix); executeDraw(cr); cairo_surface_t* maskSurface = NULL; uint8_t* maskRawData = NULL; cairo_t* maskCr = NULL; int32_t maskXOffset = 0; int32_t maskYOffset = 0; //Also apply the soft masks for(uint32_t i=0;igetPixelBuffer(); if(maskData==NULL) continue; cairo_surface_t* tmp = cairo_image_surface_create_for_data(maskData,CAIRO_FORMAT_ARGB32, masks[i].m->getWidth(),masks[i].m->getHeight(),masks[i].m->getWidth()*4); if(maskSurface==NULL) { maskSurface = tmp; maskRawData = maskData; maskCr = cairo_create(maskSurface); maskXOffset = masks[i].m->getXOffset(); maskYOffset = masks[i].m->getYOffset(); } else { //We only care about alpha here, DEST_IN multiplies the two alphas cairo_set_operator(maskCr, CAIRO_OPERATOR_DEST_IN); //TODO: consider offsets cairo_set_source_surface(maskCr, tmp, masks[i].m->getXOffset()-maskXOffset, masks[i].m->getYOffset()-maskYOffset); //cairo_set_source_surface(maskCr, tmp, 0, 0); cairo_paint(maskCr); cairo_surface_destroy(tmp); delete[] maskData; } } if(maskCr) { cairo_destroy(maskCr); //Do a last paint with DEST_IN to apply mask cairo_set_operator(cr, CAIRO_OPERATOR_DEST_IN); cairo_set_source_surface(cr, maskSurface, maskXOffset-getXOffset(), maskYOffset-getYOffset()); cairo_paint(cr); cairo_surface_destroy(maskSurface); delete[] maskRawData; } cairo_destroy(cr); return ret; } bool CairoTokenRenderer::hitTest(const std::vector& tokens, float scaleFactor, number_t x, number_t y) { cairo_surface_t* cairoSurface=cairo_image_surface_create_for_data(NULL, CAIRO_FORMAT_ARGB32, 0, 0, 0); cairo_t *cr=cairo_create(cairoSurface); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); bool empty=cairoPathFromTokens(cr, tokens, scaleFactor, true); bool ret=false; if(!empty) { /* reset the matrix so x and y are not scaled * by the current cairo transformation */ cairo_identity_matrix(cr); ret=cairo_in_fill(cr, x, y); } cairo_destroy(cr); cairo_surface_destroy(cairoSurface); return ret; } void CairoTokenRenderer::applyCairoMask(cairo_t* cr,int32_t xOffset,int32_t yOffset) const { cairo_matrix_t tmp=matrix; tmp.x0-=xOffset; tmp.y0-=yOffset; cairo_set_matrix(cr, &tmp); cairoPathFromTokens(cr, tokens, scaleFactor, true); cairo_clip(cr); } void CairoRenderer::convertBitmapWithAlphaToCairo(std::vector>& data, uint8_t* inData, uint32_t width, uint32_t height, size_t* dataSize, size_t* stride) { *stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); *dataSize = *stride * height; data.resize(*dataSize, 0); uint8_t* outData=&data[0]; uint32_t* inData32 = (uint32_t*)inData; for(uint32_t i = 0; i < height; i++) { for(uint32_t j = 0; j < width; j++) { uint32_t* outDataPos = (uint32_t*)(outData+i*(*stride)) + j; *outDataPos = GINT32_FROM_BE( *(inData32+(i*width+j)) ); } } } inline void CairoRenderer::copyRGB15To24(uint8_t* dest, uint8_t* src) { // highest bit is ignored uint8_t r = (src[0] & 0x7C) >> 2; uint8_t g = ((src[0] & 0x03) << 3) + (src[1] & 0xE0 >> 5); uint8_t b = src[1] & 0x1F; r = r*255/31; g = g*255/31; b = b*255/31; dest[0] = r; dest[1] = g; dest[2] = b; } inline void CairoRenderer::copyRGB24To24(uint8_t* dest, uint8_t* src) { memcpy(dest, src, 3); } void CairoRenderer::convertBitmapToCairo(std::vector>& data, uint8_t* inData, uint32_t width, uint32_t height, size_t* dataSize, size_t* stride, bool rgb15) { *stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); *dataSize = *stride * height; data.resize(*dataSize, 0); uint8_t* outData = &data[0]; for(uint32_t i = 0; i < height; i++) { for(uint32_t j = 0; j < width; j++) { uint32_t* outDataPos = (uint32_t*)(outData+i*(*stride)) + j; uint32_t pdata = 0xFF; /* the alpha channel is set to opaque above */ uint8_t* rgbData = ((uint8_t*)&pdata)+1; /* copy the RGB bytes to rgbData */ if(rgb15) copyRGB15To24(rgbData, inData+(i*width+j)*2); else copyRGB24To24(rgbData, inData+(i*width+j)*3); /* cairo needs this in host endianess */ *outDataPos = GINT32_FROM_BE(pdata); } } } #ifdef HAVE_NEW_GLIBMM_THREAD_API StaticMutex CairoPangoRenderer::pangoMutex; #else StaticMutex CairoPangoRenderer::pangoMutex = GLIBMM_STATIC_MUTEX_INIT; #endif void CairoPangoRenderer::pangoLayoutFromData(PangoLayout* layout, const TextData& tData) { PangoFontDescription* desc; pango_layout_set_text(layout, tData.text.raw_buf(), -1); /* setup alignment */ PangoAlignment alignment; switch(tData.autoSize) { case TextData::AUTO_SIZE::AS_NONE://TODO:check case TextData::AUTO_SIZE::AS_LEFT: { alignment = PANGO_ALIGN_LEFT; break; } case TextData::AUTO_SIZE::AS_RIGHT: { alignment = PANGO_ALIGN_RIGHT; break; } case TextData::AUTO_SIZE::AS_CENTER: { alignment = PANGO_ALIGN_CENTER; break; } default: assert(false); return; // silence warning about uninitialised alignment } pango_layout_set_alignment(layout,alignment); //In case wordWrap is true, we already have the right width if(tData.wordWrap == true) { pango_layout_set_width(layout,PANGO_SCALE*tData.width); pango_layout_set_wrap(layout,PANGO_WRAP_WORD);//I think this is what Adobe does } //In case autoSize is NONE, we also have the height if(tData.autoSize == TextData::AUTO_SIZE::AS_NONE) { pango_layout_set_width(layout,PANGO_SCALE*tData.width); pango_layout_set_height(layout,PANGO_SCALE*tData.height);//TODO:Not sure what Pango does if the text is too long to fit } /* setup font description */ desc = pango_font_description_new(); pango_font_description_set_family(desc, tData.font.raw_buf()); pango_font_description_set_size(desc, PANGO_SCALE*tData.fontSize); pango_layout_set_font_description(layout, desc); pango_font_description_free(desc); } void CairoPangoRenderer::executeDraw(cairo_t* cr) { /* TODO: pango is not fully thread-safe, * but we may be able to use finer grained locking. */ Locker l(pangoMutex); PangoLayout* layout; layout = pango_cairo_create_layout(cr); pangoLayoutFromData(layout, textData); if(textData.background) { cairo_set_source_rgb (cr, textData.backgroundColor.Red/255., textData.backgroundColor.Green/255., textData.backgroundColor.Blue/255.); cairo_paint(cr); } /* draw the text */ cairo_set_source_rgb (cr, textData.textColor.Red/255., textData.textColor.Green/255., textData.textColor.Blue/255.); pango_cairo_show_layout(cr, layout); if(textData.border) { cairo_set_source_rgb(cr, textData.borderColor.Red/255., textData.borderColor.Green/255., textData.borderColor.Blue/255.); cairo_set_line_width(cr, 1); cairo_rectangle(cr, 0, 0, textData.width, textData.height); cairo_stroke_preserve(cr); } g_object_unref(layout); } bool CairoPangoRenderer::getBounds(const TextData& _textData, uint32_t& w, uint32_t& h, uint32_t& tw, uint32_t& th) { //TODO:check locking Locker l(pangoMutex); cairo_surface_t* cairoSurface=cairo_image_surface_create_for_data(NULL, CAIRO_FORMAT_ARGB32, 0, 0, 0); cairo_t *cr=cairo_create(cairoSurface); PangoLayout* layout; layout = pango_cairo_create_layout(cr); pangoLayoutFromData(layout, _textData); PangoRectangle ink_rect, logical_rect; pango_layout_get_pixel_extents(layout,&ink_rect,&logical_rect);//TODO: check the rounding during pango conversion g_object_unref(layout); cairo_destroy(cr); cairo_surface_destroy(cairoSurface); //This should be safe check precision tw = ink_rect.width; th = ink_rect.height; if(_textData.autoSize != TextData::AUTO_SIZE::AS_NONE) { h = logical_rect.height; if(!_textData.wordWrap) w = logical_rect.width; } return (h!=0) && (w!=0); } void CairoPangoRenderer::applyCairoMask(cairo_t* cr, int32_t xOffset, int32_t yOffset) const { assert(false); } AsyncDrawJob::AsyncDrawJob(IDrawable* d, _R o):drawable(d),owner(o),surfaceBytes(NULL),uploadNeeded(false) { } AsyncDrawJob::~AsyncDrawJob() { delete drawable; delete[] surfaceBytes; } void AsyncDrawJob::execute() { surfaceBytes=drawable->getPixelBuffer(); if(surfaceBytes) uploadNeeded=true; } void AsyncDrawJob::threadAbort() { //Nothing special to be done } void AsyncDrawJob::jobFence() { //If the data must be uploaded (there were no errors) the Job add itself to the upload queue. //Otherwise it destroys itself if(uploadNeeded) getSys()->getRenderThread()->addUploadJob(this); else delete this; } void AsyncDrawJob::upload(uint8_t* data, uint32_t w, uint32_t h) const { assert(surfaceBytes); memcpy(data, surfaceBytes, w*h*4); } void AsyncDrawJob::sizeNeeded(uint32_t& w, uint32_t& h) const { w=drawable->getWidth(); h=drawable->getHeight(); } const TextureChunk& AsyncDrawJob::getTexture() { /* This is called in the render thread, * so we need no locking for surface */ CachedSurface& surface=owner->cachedSurface; uint32_t width=drawable->getWidth(); uint32_t height=drawable->getHeight(); //Verify that the texture is large enough if(!surface.tex.resizeIfLargeEnough(width, height)) surface.tex=getSys()->getRenderThread()->allocateTexture(width, height,false); surface.xOffset=drawable->getXOffset(); surface.yOffset=drawable->getYOffset(); surface.alpha=drawable->getAlpha(); return surface.tex; } void AsyncDrawJob::uploadFence() { delete this; } void SoftwareInvalidateQueue::addToInvalidateQueue(_R d) { queue.emplace_back(d); } lightspark-0.7.2/src/backends/graphics.h000066400000000000000000000306251212105246600202070ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_GRAPHICS_H #define BACKENDS_GRAPHICS_H 1 #define CHUNKSIZE 128 #include "compat.h" #include "backends/lsopengl.h" #include #include "swftypes.h" #include "threading.h" #include #include #include "backends/geometry.h" #include "memory_support.h" namespace lightspark { class DisplayObject; class InvalidateQueue; class TextureBuffer { private: GLuint texId; GLenum filtering; uint32_t allocWidth; uint32_t allocHeight; uint32_t width; uint32_t height; uint32_t horizontalAlignment; uint32_t verticalAlignment; bool inited; uint32_t nearestPOT(uint32_t a) const; void setAllocSize(uint32_t w, uint32_t h); public: /** TextureBuffer constructor @param initNow Create right now the texture (can be true only if created inside the Render Thread) @param width The requested width @param height The requested height @param filtering The requested texture filtering from OpenGL enumeration */ TextureBuffer(bool initNow, uint32_t width=0, uint32_t height=0, GLenum filtering=GL_NEAREST); /** TextureBuffer destructor Destroys the GL resources allocated for this texture @pre Should be run inside the RenderThread or shutdown should be already run */ ~TextureBuffer(); /** Return the texture id @ret The OpenGL texture id */ GLuint getId() {return texId;} /** Initialize the texture using new values @param width The requested width @param height The requested height @param filtering The requested texture filtering from OpenGL enumeration @pre Running inside the RenderThread */ void init(uint32_t width, uint32_t height, GLenum filtering=GL_NEAREST); /** Frees the GL resources @pre Running inside the RenderThread */ void shutdown(); /** Bind as the current texture @pre Running inside the RenderThread */ void bind(); /** Unbind the current texture @pre Running inside the RenderThread */ void unbind(); /** Set the given uniform with the coordinate scale of the current texture @pre Running inside the RenderThread */ void setTexScale(GLuint uniformLocation); void resize(uint32_t width, uint32_t height); /** Request a minimum alignment for width and height */ void setRequestedAlignment(uint32_t w, uint32_t h); uint32_t getAllocWidth() const { return allocWidth;} uint32_t getAllocHeight() const { return allocHeight;} }; class TextureChunk { friend class GLRenderContext; friend class CairoRenderContext; friend class RenderThread; private: /* * For GLRenderContext texId is an OpenGL texture id and chunks is an array of used * chunks inside such texture. * For CairoRenderContext texId is an arbitrary id for the texture and chunks is * not used. */ uint32_t* chunks; uint32_t texId; TextureChunk(uint32_t w, uint32_t h); public: TextureChunk():chunks(NULL),texId(0),width(0),height(0){} TextureChunk(const TextureChunk& r); TextureChunk& operator=(const TextureChunk& r); ~TextureChunk(); bool resizeIfLargeEnough(uint32_t w, uint32_t h); uint32_t getNumberOfChunks() const { return ((width+CHUNKSIZE-1)/CHUNKSIZE)*((height+CHUNKSIZE-1)/CHUNKSIZE); } bool isValid() const { return chunks; } void makeEmpty(); uint32_t width; uint32_t height; }; class CachedSurface { public: CachedSurface():xOffset(0),yOffset(0),alpha(1.0){} TextureChunk tex; int32_t xOffset; int32_t yOffset; float alpha; }; class ITextureUploadable { protected: ~ITextureUploadable(){} public: virtual void sizeNeeded(uint32_t& w, uint32_t& h) const=0; /* Upload data to memory mapped to the graphics card (note: size is guaranteed to be enough */ virtual void upload(uint8_t* data, uint32_t w, uint32_t h) const=0; virtual const TextureChunk& getTexture()=0; /* Signal the completion of the upload to the texture NOTE: fence may be called on shutdown even if the upload has not happen, so be ready for this event */ virtual void uploadFence()=0; }; class IDrawable { public: enum MASK_MODE { HARD_MASK = 0, SOFT_MASK }; struct MaskData { IDrawable* m; MASK_MODE maskMode; MaskData(IDrawable* _m, MASK_MODE _mm):m(_m),maskMode(_mm){} }; protected: /* * The masks to be applied */ std::vector masks; int32_t width; int32_t height; /* The minimal x coordinate for all the points being drawn, in local coordinates */ int32_t xOffset; /* The minimal y coordinate for all the points being drawn, in local coordinates */ int32_t yOffset; float alpha; public: IDrawable(int32_t w, int32_t h, int32_t x, int32_t y, float a, const std::vector& m): masks(m),width(w),height(h),xOffset(x),yOffset(y),alpha(a){} virtual ~IDrawable(){} /* * This method returns a raster buffer of the image * The various implementation are responsible for applying the * masks */ virtual uint8_t* getPixelBuffer()=0; /* * This method creates a cairo path that can be used as a mask for * another object */ virtual void applyCairoMask(cairo_t* cr, int32_t offsetX, int32_t offsetY) const = 0; int32_t getWidth() const { return width; } int32_t getHeight() const { return height; } int32_t getXOffset() const { return xOffset; } int32_t getYOffset() const { return yOffset; } float getAlpha() const { return alpha; } }; class AsyncDrawJob: public IThreadJob, public ITextureUploadable { private: IDrawable* drawable; /** * The DisplayObject owning this render request. We incRef/decRef it * in our constructor/destructor to make sure that it does not go away */ _R owner; uint8_t* surfaceBytes; bool uploadNeeded; public: /* * @param o The DisplayObject that is being rendered. It is a reference to * make sure the object survives until the end of the rendering * @param d IDrawable to be rendered asynchronously. The pointer is now * owned by this instance */ AsyncDrawJob(IDrawable* d, _R o); ~AsyncDrawJob(); //IThreadJob interface void execute(); void threadAbort(); void jobFence(); //ITextureUploadable interface void upload(uint8_t* data, uint32_t w, uint32_t h) const; void sizeNeeded(uint32_t& w, uint32_t& h) const; const TextureChunk& getTexture(); void uploadFence(); }; /** The base class for render jobs based on cairo Stores an internal copy of the data to be rendered */ class CairoRenderer: public IDrawable { protected: /* The scale to be applied in both the x and y axis. Useful to adapt points defined in pixels and twips (1/20 of pixel) */ const float scaleFactor; /** The whole transformation matrix that is applied to the rendered object */ MATRIX matrix; /* * There are reports (http://lists.freedesktop.org/archives/cairo/2011-September/022247.html) * that cairo is not threadsafe, and I have encountered some spurious crashes, too. * So we use a global lock for all cairo calls until this issue is sorted out. * TODO: CairoRenderes are enqueued as IThreadJobs, therefore this mutex * will serialize the thread pool when all thread pool workers are executing CairoRenderers! */ static StaticRecMutex cairoMutex; static void cairoClean(cairo_t* cr); cairo_surface_t* allocateSurface(uint8_t*& buf); virtual void executeDraw(cairo_t* cr)=0; static void copyRGB15To24(uint8_t* dest, uint8_t* src); static void copyRGB24To24(uint8_t* dest, uint8_t* src); public: CairoRenderer(const MATRIX& _m, int32_t _x, int32_t _y, int32_t _w, int32_t _h, float _s, float _a, const std::vector& m); //IDrawable interface uint8_t* getPixelBuffer(); /* * Converts data (which is in RGB format) to the format internally used by cairo. */ static void convertBitmapToCairo(std::vector>& data, uint8_t* inData, uint32_t width, uint32_t height, size_t* dataSize, size_t* stride, bool rgb15); /* * Converts data (which is in ARGB format) to the format internally used by cairo. */ static void convertBitmapWithAlphaToCairo(std::vector>& data, uint8_t* inData, uint32_t width, uint32_t height, size_t* dataSize, size_t* stride); }; class CairoTokenRenderer : public CairoRenderer { private: static cairo_pattern_t* FILLSTYLEToCairo(const FILLSTYLE& style, double scaleCorrection); static bool cairoPathFromTokens(cairo_t* cr, const std::vector& tokens, double scaleCorrection, bool skipFill); static void quadraticBezier(cairo_t* cr, double control_x, double control_y, double end_x, double end_y); /* The tokens to be drawn */ const std::vector tokens; /* * This is run by CairoRenderer::execute() */ void executeDraw(cairo_t* cr); void applyCairoMask(cairo_t* cr, int32_t offsetX, int32_t offsetY) const; public: /* CairoTokenRenderer constructor @param _o Owner of the surface _t. See comments on 'owner' member. @param _t GL surface where the final drawing will be uploaded @param _g The tokens to be drawn. This is copied internally. @param _m The whole transformation matrix @param _s The scale factor to be applied in both the x and y axis @param _a The alpha factor to be applied @param _ms The masks that must be applied */ CairoTokenRenderer(const std::vector& _g, const MATRIX& _m, int32_t _x, int32_t _y, int32_t _w, int32_t _h, float _s, float _a, const std::vector& _ms) : CairoRenderer(_m,_x,_y,_w,_h,_s,_a,_ms),tokens(_g){} /* Hit testing helper. Uses cairo to find if a point in inside the shape @param tokens The tokens of the shape being tested @param scaleFactor The scale factor to be applied @param x The X in local coordinates @param y The Y in local coordinates */ static bool hitTest(const std::vector& tokens, float scaleFactor, number_t x, number_t y); }; class TextData { public: /* the default values are from the spec for flash.text.TextField and flash.text.TextFormat */ TextData() : width(100), height(100), textWidth(0), textHeight(0), font("Times New Roman"), background(false), backgroundColor(0xFFFFFF), border(false), borderColor(0x000000), multiline(false), textColor(0x000000), autoSize(AS_NONE), fontSize(12), wordWrap(false) {} uint32_t width; uint32_t height; uint32_t textWidth; uint32_t textHeight; tiny_string text; tiny_string font; bool background; RGB backgroundColor; bool border; RGB borderColor; bool multiline; RGB textColor; enum AUTO_SIZE {AS_NONE = 0, AS_LEFT, AS_RIGHT, AS_CENTER }; AUTO_SIZE autoSize; uint32_t fontSize; bool wordWrap; }; class CairoPangoRenderer : public CairoRenderer { static StaticMutex pangoMutex; /* * This is run by CairoRenderer::execute() */ void executeDraw(cairo_t* cr); TextData textData; static void pangoLayoutFromData(PangoLayout* layout, const TextData& tData); void applyCairoMask(cairo_t* cr, int32_t offsetX, int32_t offsetY) const; public: CairoPangoRenderer(const TextData& _textData, const MATRIX& _m, int32_t _x, int32_t _y, int32_t _w, int32_t _h, float _s, float _a, const std::vector& _ms) : CairoRenderer(_m,_x,_y,_w,_h,_s,_a,_ms), textData(_textData) {} /** Helper. Uses Pango to find the size of the textdata @param _texttData The textData being tested @param w,h,tw,th are the (text)width and (text)height of the textData. */ static bool getBounds(const TextData& _textData, uint32_t& w, uint32_t& h, uint32_t& tw, uint32_t& th); }; class InvalidateQueue { public: virtual ~InvalidateQueue(){}; //Invalidation queue management virtual void addToInvalidateQueue(_R d) = 0; }; class SoftwareInvalidateQueue: public InvalidateQueue { public: std::list<_R> queue; void addToInvalidateQueue(_R d); }; }; #endif /* BACKENDS_GRAPHICS_H */ lightspark-0.7.2/src/backends/image.cpp000066400000000000000000000267601212105246600200310ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2011-2013 Matthias Gehre (M.Gehre@gmx.de) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include #include #include "logger.h" extern "C" { #include #include } #include #include "backends/image.h" namespace lightspark { struct istream_source_mgr : public jpeg_source_mgr { istream_source_mgr(std::istream& str) : input(str), data(NULL), capacity(0) {} std::istream& input; char* data; int capacity; }; static void init_source_nop(j_decompress_ptr cinfo) { //do nothing } static boolean fill_input_buffer(j_decompress_ptr cinfo) { return FALSE; } static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) { jpeg_source_mgr *src = cinfo->src; src->next_input_byte = (const JOCTET*)((const char*)src->next_input_byte + num_bytes); src->bytes_in_buffer -= num_bytes; } static boolean resync_to_restart(j_decompress_ptr cinfo, int desired) { return TRUE; } static void term_source(j_decompress_ptr /*cinfo*/) {} static void init_source_istream(j_decompress_ptr cinfo) { istream_source_mgr* src = static_cast(cinfo->src); src->bytes_in_buffer=0; } static boolean fill_input_buffer_istream(j_decompress_ptr cinfo) { istream_source_mgr* src = static_cast(cinfo->src); src->next_input_byte=(const JOCTET*)src->data; try { src->input.read(src->data, src->capacity); } catch(std::ios_base::failure& exc) { if(!src->input.eof()) throw; } src->bytes_in_buffer=src->input.gcount(); if(src->bytes_in_buffer==0) { // EOI marker src->data[0]=(char)0xff; src->data[1]=(char)0xd9; src->bytes_in_buffer=2; } return TRUE; } static void skip_input_data_istream(j_decompress_ptr cinfo, long num_bytes) { istream_source_mgr* src = static_cast(cinfo->src); if(num_bytes<=0) return; if(num_bytes<=(long)src->bytes_in_buffer) { src->next_input_byte += num_bytes; src->bytes_in_buffer -= num_bytes; } else { try { src->input.seekg(num_bytes-src->bytes_in_buffer, std::ios_base::cur); } catch(std::ios_base::failure& exc) { if(!src->input.eof()) throw; } src->bytes_in_buffer=0; } } struct error_mgr : jpeg_error_mgr { jmp_buf jmpBuf; }; void error_exit(j_common_ptr cinfo) { error_mgr* error = static_cast(cinfo->err); (*error->output_message) (cinfo); /* Let the memory manager delete any temp files before we die */ jpeg_destroy(cinfo); longjmp(error->jmpBuf, -1); } uint8_t* ImageDecoder::decodeJPEG(uint8_t* inData, int len, const uint8_t* tablesData, int tablesLen, uint32_t* width, uint32_t* height, bool* hasAlpha) { struct jpeg_source_mgr src; src.next_input_byte = (const JOCTET*)inData; src.bytes_in_buffer = len; src.init_source = init_source_nop; src.fill_input_buffer = fill_input_buffer; src.skip_input_data = skip_input_data; src.resync_to_restart = resync_to_restart; src.term_source = term_source; struct jpeg_source_mgr *tablesSrc; if (tablesData) { tablesSrc = new jpeg_source_mgr(); tablesSrc->next_input_byte = (const JOCTET*)tablesData; tablesSrc->bytes_in_buffer = tablesLen; tablesSrc->init_source = init_source_nop; tablesSrc->fill_input_buffer = fill_input_buffer; tablesSrc->skip_input_data = skip_input_data; tablesSrc->resync_to_restart = resync_to_restart; tablesSrc->term_source = term_source; } else { tablesSrc = NULL; } *width = 0; *height = 0; uint8_t* decoded = decodeJPEGImpl(&src, tablesSrc, width, height, hasAlpha); delete tablesSrc; return decoded; } uint8_t* ImageDecoder::decodeJPEG(std::istream& str, uint32_t* width, uint32_t* height, bool* hasAlpha) { struct istream_source_mgr src(str); src.capacity=4096; src.data=new char[src.capacity]; src.init_source = init_source_istream; src.fill_input_buffer = fill_input_buffer_istream; src.skip_input_data = skip_input_data_istream; src.resync_to_restart = jpeg_resync_to_restart; src.term_source = term_source; uint8_t* res=decodeJPEGImpl(&src, NULL, width, height, hasAlpha); delete[] src.data; return res; } uint8_t* ImageDecoder::decodeJPEGImpl(jpeg_source_mgr *src, jpeg_source_mgr *headerTables, uint32_t* width, uint32_t* height, bool* hasAlpha) { struct jpeg_decompress_struct cinfo; struct error_mgr err; cinfo.err = jpeg_std_error(&err); err.error_exit = error_exit; if (setjmp(err.jmpBuf)) { return NULL; } jpeg_create_decompress(&cinfo); if (headerTables) cinfo.src = headerTables; else cinfo.src = src; //DefineBits tag may contain "abbreviated datastreams" (as //they are called in the libjpeg documentation), i.e. streams //with only compression tables and no image data. The first //jpeg_read_header accepts table-only streams. int headerStatus = jpeg_read_header(&cinfo, FALSE); if (headerTables) { // Must call init_source manually after switching src // Check this. Doesn't jpeg_read_header call // init_source anyway? cinfo.src = src; src->init_source(&cinfo); } //If the first jpeg_read_header got tables-only datastream, //a second call is needed to read the real image header. if (headerStatus == JPEG_HEADER_TABLES_ONLY) jpeg_read_header(&cinfo, TRUE); #ifdef JCS_EXTENSIONS //JCS_EXT_XRGB is a fast decoder that outputs alpha channel, //but is only available on libjpeg-turbo cinfo.out_color_space = JCS_EXT_XRGB; cinfo.output_components = 4; #endif jpeg_start_decompress(&cinfo); *width = cinfo.output_width; *height = cinfo.output_height; if(cinfo.num_components != 3) { LOG(LOG_NOT_IMPLEMENTED,"Only RGB JPEG's are supported"); /* TODO: is this the right thing for aborting? */ jpeg_abort_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); return NULL; } assert(cinfo.output_components == 3 || cinfo.output_components == 4); *hasAlpha = (cinfo.output_components == 4); int rowstride = cinfo.output_width * cinfo.output_components; JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, rowstride, 1); uint8_t* outData = new uint8_t[cinfo.output_height * rowstride]; /* read one scanline at a time */ int y=0; while (cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines(&cinfo, buffer, 1); memcpy(&outData[y*rowstride], buffer[0], rowstride); y++; } jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); return outData; } /* PNG handling */ struct png_image_buffer { uint8_t* data; int curpos; }; static void ReadPNGDataFromStream(png_structp pngPtr, png_bytep data, png_size_t length) { png_voidp a = png_get_io_ptr(pngPtr); ((std::istream*)a)->read((char*)data, length); } static void ReadPNGDataFromBuffer(png_structp pngPtr, png_bytep data, png_size_t length) { png_image_buffer* a = reinterpret_cast(png_get_io_ptr(pngPtr)); memcpy(data,(void*)(a->data+a->curpos),length); a->curpos+= length; } uint8_t* ImageDecoder::decodePNG(uint8_t* inData, int len, uint32_t* width, uint32_t* height) { png_structp pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!pngPtr) { LOG(LOG_ERROR,"Couldn't initialize png read struct"); return NULL; } png_set_read_fn(pngPtr,(void*)inData, ReadPNGDataFromBuffer); return decodePNGImpl(pngPtr, width, height); } uint8_t* ImageDecoder::decodePNG(std::istream& str, uint32_t* width, uint32_t* height) { png_structp pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!pngPtr) { LOG(LOG_ERROR,"Couldn't initialize png read struct"); return NULL; } png_set_read_fn(pngPtr,(void*)&str, ReadPNGDataFromStream); return decodePNGImpl(pngPtr, width, height); } uint8_t* ImageDecoder::decodePNGImpl(png_structp pngPtr, uint32_t* width, uint32_t* height) { png_bytep* rowPtrs = NULL; uint8_t* outData = NULL; png_infop infoPtr = png_create_info_struct(pngPtr); if (!infoPtr) { LOG(LOG_ERROR,"Couldn't initialize png info struct"); png_destroy_read_struct(&pngPtr, (png_infopp)0, (png_infopp)0); return NULL; } if (setjmp(png_jmpbuf(pngPtr))) { png_destroy_read_struct(&pngPtr, &infoPtr,(png_infopp)0); if (rowPtrs != NULL) delete [] rowPtrs; if (outData != NULL) delete [] outData; LOG(LOG_ERROR,"error during reading of the png file"); return NULL; } png_read_info(pngPtr, infoPtr); *width = png_get_image_width(pngPtr, infoPtr); *height = png_get_image_height(pngPtr, infoPtr); //bits per CHANNEL! note: not per pixel! png_uint_32 bitdepth = png_get_bit_depth(pngPtr, infoPtr); //Number of channels png_uint_32 channels = png_get_channels(pngPtr, infoPtr); //Color type. (RGB, RGBA, Luminance, luminance alpha... palette... etc) png_uint_32 color_type = png_get_color_type(pngPtr, infoPtr); // Transform everything into 24 bit RGB switch (color_type) { case PNG_COLOR_TYPE_PALETTE: png_set_palette_to_rgb(pngPtr); // png_set_palette_to_rgb wil convert into 32 // bit, but we don't want the alpha png_set_strip_alpha(pngPtr); break; case PNG_COLOR_TYPE_GRAY: if (bitdepth < 8) png_set_gray_to_rgb(pngPtr); break; } if (bitdepth == 16) { png_set_strip_16(pngPtr); } if (channels > 3) { LOG(LOG_NOT_IMPLEMENTED, "Alpha channel not supported in PNG"); png_set_strip_alpha(pngPtr); } // Update the infoPtr to reflect the transformations set // above. Read new values by calling png_get_* again. png_read_update_info(pngPtr, infoPtr); //bitdepth = png_get_bit_depth(pngPtr, infoPtr); //color_type = png_get_color_type(pngPtr, infoPtr); channels = png_get_channels(pngPtr, infoPtr); if (channels != 3) { // Should never get here because of the // transformations LOG(LOG_NOT_IMPLEMENTED, "Unexpected number of channels in PNG!"); png_destroy_read_struct(&pngPtr, &infoPtr,(png_infopp)0); return NULL; } const unsigned int stride = png_get_rowbytes(pngPtr, infoPtr); outData = new uint8_t[(*height) * stride]; rowPtrs = new png_bytep[(*height)]; for (size_t i = 0; i < (*height); i++) { rowPtrs[i] = (png_bytep)outData + i* stride; } png_read_image(pngPtr, rowPtrs); png_read_end(pngPtr, NULL); png_destroy_read_struct(&pngPtr, &infoPtr,(png_infopp)0); delete[] (png_bytep)rowPtrs; return outData; } uint8_t* ImageDecoder::decodePalette(uint8_t* pixels, uint32_t width, uint32_t height, uint32_t stride, uint8_t* palette, unsigned int numColors, unsigned int paletteBPP) { if (numColors == 0) return NULL; assert(stride >= width); assert(paletteBPP==3 || paletteBPP==4); uint8_t* outData = new uint8_t[3*width*height]; for (size_t y=0; y= numColors) { // Invalid palette index paletteIndex = 0; } uint8_t *dest = outData + 3*(y*width + x); memcpy(dest, &palette[paletteBPP*paletteIndex], 3); } } return outData; } } lightspark-0.7.2/src/backends/image.h000066400000000000000000000045731212105246600174740ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2011-2013 Matthias Gehre (M.Gehre@gmx.de) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_IMAGE_H #define BACKENDS_IMAGE_H 1 #include #include extern "C" { #include #define PNG_SKIP_SETJMP_CHECK #include } namespace lightspark { class ImageDecoder { private: static uint8_t* decodeJPEGImpl(jpeg_source_mgr *src, jpeg_source_mgr* headerTables, uint32_t* width, uint32_t* height, bool* hasAlpha); static uint8_t* decodePNGImpl(png_structp pngPtr, uint32_t* width, uint32_t* height); public: /* * Returns a new[]'ed array of decompressed data and sets width, height and format * Return NULL on error */ static uint8_t* decodeJPEG(uint8_t* inData, int len, const uint8_t* tablesData, int tablesLen, uint32_t* width, uint32_t* height, bool* hasAlpha); static uint8_t* decodeJPEG(std::istream& str, uint32_t* width, uint32_t* height, bool* hasAlpha); static uint8_t* decodePNG(uint8_t* inData, int len, uint32_t* width, uint32_t* height); static uint8_t* decodePNG(std::istream& str, uint32_t* width, uint32_t* height); /* Convert paletted image into new[]'ed 24bit RGB image. * pixels array contains indexes to the palette, 1 byte per * index. Palette has numColors RGB(A) values, paletteBPP (== * 3 or 4) bytes per color. The alpha channel (present if * paletteBPP == 4) is ignored. */ static uint8_t* decodePalette(uint8_t* pixels, uint32_t width, uint32_t height, uint32_t stride, uint8_t* palette, unsigned int numColors, unsigned int paletteBPP); }; } #endif /* BACKENDS_IMAGE_H */ lightspark-0.7.2/src/backends/input.cpp000066400000000000000000000301261212105246600200750ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "scripting/abc.h" #include "backends/audio.h" #include "backends/input.h" #include "backends/rendering.h" #include "compat.h" #include "scripting/flash/ui/keycodes.h" #if GTK_CHECK_VERSION (2,21,8) #include #else #include #endif using namespace lightspark; using namespace std; InputThread::InputThread(SystemState* s):m_sys(s),engineData(NULL),terminated(false),threaded(false), curDragged(),currentMouseOver(),lastMouseDownTarget(), dragLimit(NULL) { LOG(LOG_INFO,_("Creating input thread")); } void InputThread::start(EngineData* e) { initKeyTable(); engineData = e; engineData->setInputHandler(sigc::mem_fun(this, &InputThread::worker)); } InputThread::~InputThread() { if(engineData) engineData->removeInputHandler(); wait(); } void InputThread::wait() { if(terminated) return; if(threaded) t->join(); terminated=true; } //This is guarded gdk_threads_enter/leave bool InputThread::worker(GdkEvent *event) { //Set sys to this SystemState setTLSSys(m_sys); gboolean ret=FALSE; switch(event->type) { case GDK_KEY_PRESS: { bool handled = handleKeyboardShortcuts(&event->key); if (!handled) sendKeyEvent(&event->key); ret=TRUE; break; } case GDK_KEY_RELEASE: { sendKeyEvent(&event->key); ret=TRUE; break; } case GDK_EXPOSE: { //Signal the renderThread m_sys->getRenderThread()->draw(false); ret=TRUE; break; } case GDK_BUTTON_PRESS: { if(event->button.button == 1) { //Grab focus, to receive keypresses engineData->grabFocus(); int stageX, stageY; m_sys->windowToStageCoordinates(event->button.x,event->button.y,stageX,stageY); handleMouseDown(stageX,stageY,event->button.state); } ret=TRUE; break; } case GDK_2BUTTON_PRESS: { if(event->button.button == 1) { int stageX, stageY; m_sys->windowToStageCoordinates(event->button.x,event->button.y,stageX,stageY); handleMouseDoubleClick(stageX,stageY,event->button.state); } ret=TRUE; break; } case GDK_BUTTON_RELEASE: { int stageX, stageY; m_sys->windowToStageCoordinates(event->button.x,event->button.y,stageX,stageY); handleMouseUp(stageX,stageY,event->button.state); ret=TRUE; break; } case GDK_MOTION_NOTIFY: { int stageX, stageY; m_sys->windowToStageCoordinates(event->motion.x,event->motion.y,stageX,stageY); handleMouseMove(stageX,stageY,event->button.state); ret=TRUE; break; } case GDK_SCROLL: { int stageX, stageY; m_sys->windowToStageCoordinates(event->scroll.x,event->scroll.y,stageX,stageY); handleScrollEvent(stageX,stageY,event->scroll.direction,event->scroll.state); ret=TRUE; break; } default: //#ifdef EXPENSIVE_DEBUG // LOG(LOG_INFO, "GDKTYPE " << event->type); //#endif break; } return ret; } _NR InputThread::getMouseTarget(uint32_t x, uint32_t y, DisplayObject::HIT_TYPE type) { _NR selected = NullRef; try { _NR dispobj=m_sys->mainClip->getStage()->hitTest(NullRef,x,y, type); if(!dispobj.isNull() && dispobj->is()) { dispobj->incRef(); selected=_MNR(dispobj->as()); } } catch(LightsparkException& e) { LOG(LOG_ERROR,_("Error in input handling ") << e.cause); m_sys->setError(e.cause); return NullRef; } assert(selected); /* atleast we hit the stage */ assert_and_throw(selected->getClass()->isSubClass(Class::getClass())); return selected; } void InputThread::handleMouseDown(uint32_t x, uint32_t y, unsigned int buttonState) { if(m_sys->currentVm == NULL) return; Locker locker(mutexListeners); _NR selected = getMouseTarget(x, y, DisplayObject::MOUSE_CLICK); number_t localX, localY; selected->globalToLocal(x,y,localX,localY); m_sys->currentVm->addEvent(selected, _MR(Class::getInstanceS("mouseDown",localX,localY,true,buttonState))); lastMouseDownTarget=selected; } void InputThread::handleMouseDoubleClick(uint32_t x, uint32_t y, unsigned int buttonState) { if(m_sys->currentVm == NULL) return; Locker locker(mutexListeners); _NR selected = getMouseTarget(x, y, DisplayObject::DOUBLE_CLICK); number_t localX, localY; selected->globalToLocal(x,y,localX,localY); m_sys->currentVm->addEvent(selected, _MR(Class::getInstanceS("doubleClick",localX,localY,true,buttonState))); } void InputThread::handleMouseUp(uint32_t x, uint32_t y, unsigned int buttonState) { if(m_sys->currentVm == NULL) return; Locker locker(mutexListeners); _NR selected = getMouseTarget(x, y, DisplayObject::MOUSE_CLICK); number_t localX, localY; selected->globalToLocal(x,y,localX,localY); m_sys->currentVm->addEvent(selected, _MR(Class::getInstanceS("mouseUp",localX,localY,true,buttonState))); if(lastMouseDownTarget==selected) { //Also send the click event m_sys->currentVm->addEvent(selected, _MR(Class::getInstanceS("click",localX,localY,true,buttonState))); } lastMouseDownTarget=NullRef; } void InputThread::handleMouseMove(uint32_t x, uint32_t y, unsigned int buttonState) { if(m_sys->currentVm == NULL) return; SpinlockLocker locker(inputDataSpinlock); mousePos = Vector2(x,y); Locker locker2(mutexDragged); // Handle current drag operation if(curDragged) { Vector2f local; _NR parent = curDragged->getParent(); if(!parent) { stopDrag(curDragged.getPtr()); return; } local = parent->getConcatenatedMatrix().getInverted().multiply2D(mousePos); local += dragOffset; if(dragLimit) local = local.projectInto(*dragLimit); curDragged->setX(local.x); curDragged->setY(local.y); } // Handle non-drag mouse movement else { _NR selected = getMouseTarget(x, y, DisplayObject::MOUSE_CLICK); number_t localX, localY; selected->globalToLocal(x,y,localX,localY); if(currentMouseOver == selected) m_sys->currentVm->addEvent(selected, _MR(Class::getInstanceS("mouseMove",localX,localY,true,buttonState))); else { if(!currentMouseOver.isNull()) { number_t clocalX, clocalY; currentMouseOver->globalToLocal(x,y,clocalX,clocalY); m_sys->currentVm->addEvent(currentMouseOver, _MR(Class::getInstanceS("mouseOut",clocalX,clocalY,true,buttonState,selected))); m_sys->currentVm->addEvent(currentMouseOver, _MR(Class::getInstanceS("rollOut",clocalX,clocalY,true,buttonState,selected))); } m_sys->currentVm->addEvent(selected, _MR(Class::getInstanceS("mouseOver",localX,localY,true,buttonState,currentMouseOver))); m_sys->currentVm->addEvent(selected, _MR(Class::getInstanceS("rollOver",localX,localY,true,buttonState,currentMouseOver))); currentMouseOver = selected; } } } void InputThread::handleScrollEvent(uint32_t x, uint32_t y, GdkScrollDirection direction, unsigned int buttonState) { if(m_sys->currentVm == NULL) return; int delta; if(direction==GDK_SCROLL_UP) delta = 1; else if(direction==GDK_SCROLL_DOWN) delta = -1; else return; Locker locker(mutexListeners); _NR selected = getMouseTarget(x, y, DisplayObject::MOUSE_CLICK); number_t localX, localY; selected->globalToLocal(x,y,localX,localY); m_sys->currentVm->addEvent(selected, _MR(Class::getInstanceS("mouseWheel",localX,localY,true,buttonState,NullRef,delta))); } void InputThread::initKeyTable() { int i = 0; while (hardwareKeycodes[i].keyname) { // Map GDK keyvals to hardware keycodes. // // NOTE: The keycodes returned by GDK are different // from the keycodes in the Flash documentation. // Should add mapping from GDK codes to Flash codes // for AS files that use raw numerical values instead // of Keyboard.* constants. GdkKeymapKey *keys; int keys_len; const char *keyname = hardwareKeycodes[i].keyname; unsigned keyval = hardwareKeycodes[i].gdkKeyval; if (gdk_keymap_get_entries_for_keyval(NULL, keyval, &keys, &keys_len)) { KeyNameCodePair key; key.keyname = keyname; key.keycode = keys[0].keycode; keyNamesAndCodes.push_back(key); g_free(keys); } i++; } } const std::vector& InputThread::getKeyNamesAndCodes() { // No locking needed, because keyNamesAndCodes is not modified // after being initialized return keyNamesAndCodes; } bool InputThread::handleKeyboardShortcuts(const GdkEventKey *keyevent) { bool handled = false; if ((keyevent->state & GDK_MODIFIER_MASK) != GDK_CONTROL_MASK) return handled; switch(keyevent->keyval) { case GDK_q: handled = true; if(m_sys->standalone) m_sys->setShutdownFlag(); break; case GDK_p: handled = true; m_sys->showProfilingData=!m_sys->showProfilingData; break; case GDK_m: handled = true; if (!m_sys->audioManager->pluginLoaded()) break; m_sys->audioManager->toggleMuteAll(); if(m_sys->audioManager->allMuted()) LOG(LOG_INFO, "All sounds muted"); else LOG(LOG_INFO, "All sounds unmuted"); break; case GDK_c: handled = true; if(m_sys->hasError()) { GtkClipboard *clipboard; clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); gtk_clipboard_set_text(clipboard, m_sys->getErrorCause().c_str(), m_sys->getErrorCause().size()); clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); gtk_clipboard_set_text(clipboard, m_sys->getErrorCause().c_str(), m_sys->getErrorCause().size()); LOG(LOG_INFO, "Copied error to clipboard"); } else LOG(LOG_INFO, "No error to be copied to clipboard"); break; default: break; } return handled; } void InputThread::sendKeyEvent(const GdkEventKey *keyevent) { if(m_sys->currentVm == NULL) return; Locker locker(mutexListeners); _NR target = m_sys->mainClip->getStage()->getFocusTarget(); if (target.isNull()) return; tiny_string type; if (keyevent->type == GDK_KEY_PRESS) type = "keyDown"; else type = "keyUp"; uint32_t charcode = keyevent->keyval; if (keyevent->is_modifier) charcode = 0; m_sys->currentVm->addEvent(target, _MR(Class::getInstanceS(type, charcode, keyevent->hardware_keycode, keyevent->state))); } void InputThread::addListener(InteractiveObject* ob) { Locker locker(mutexListeners); assert(ob); #ifndef NDEBUG vector::const_iterator it=find(listeners.begin(),listeners.end(),ob); //Object is already register, should not happen if(it != listeners.end()) { LOG(LOG_ERROR, "Trying to addListener an InteractiveObject that's already added."); return; } #endif //Register the listener listeners.push_back(ob); } void InputThread::removeListener(InteractiveObject* ob) { Locker locker(mutexListeners); vector::iterator it=find(listeners.begin(),listeners.end(),ob); if(it==listeners.end()) //Listener not found return; //Unregister the listener listeners.erase(it); } void InputThread::startDrag(_R s, const lightspark::RECT* limit, Vector2f offset) { Locker locker(mutexDragged); if(s==curDragged) return; curDragged=s; dragLimit=limit; dragOffset=offset; } void InputThread::stopDrag(Sprite* s) { Locker locker(mutexDragged); if(curDragged == s) { curDragged = NullRef; delete dragLimit; dragLimit = 0; } } lightspark-0.7.2/src/backends/input.h000066400000000000000000000060721212105246600175450ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_INPUT_H #define BACKENDS_INPUT_H 1 #include "compat.h" #include "backends/geometry.h" #include "threading.h" #include "platforms/engineutils.h" #include "swftypes.h" #include "smartrefs.h" #include #include "scripting/class.h" namespace lightspark { class SystemState; class DisplayObject; class InteractiveObject; class Sprite; class MouseEvent; struct KeyNameCodePair { const char *keyname; unsigned int keycode; }; class InputThread { private: SystemState* m_sys; EngineData* engineData; Thread* t; bool terminated; bool threaded; bool worker(GdkEvent *event); std::vector listeners; Mutex mutexListeners; Mutex mutexDragged; std::vector keyNamesAndCodes; _NR curDragged; _NR currentMouseOver; _NR lastMouseDownTarget; const RECT* dragLimit; Vector2f dragOffset; class MaskData { public: DisplayObject* d; MATRIX m; MaskData(DisplayObject* _d, const MATRIX& _m):d(_d),m(_m){} }; _NR getMouseTarget(uint32_t x, uint32_t y, DisplayObject::HIT_TYPE type); void handleMouseDown(uint32_t x, uint32_t y, unsigned int buttonState); void handleMouseDoubleClick(uint32_t x, uint32_t y, unsigned int buttonState); void handleMouseUp(uint32_t x, uint32_t y, unsigned int buttonState); void handleMouseMove(uint32_t x, uint32_t y, unsigned int buttonState); void handleScrollEvent(uint32_t x, uint32_t y, GdkScrollDirection direction, unsigned int buttonState); void initKeyTable(); bool handleKeyboardShortcuts(const GdkEventKey *keyevent); void sendKeyEvent(const GdkEventKey *keyevent); Spinlock inputDataSpinlock; Vector2 mousePos; public: InputThread(SystemState* s); ~InputThread(); void wait(); void start(EngineData* data); void addListener(InteractiveObject* ob); void removeListener(InteractiveObject* ob); void startDrag(_R s, const RECT* limit, Vector2f dragOffset); void stopDrag(Sprite* s); const std::vector& getKeyNamesAndCodes(); Vector2 getMousePos() { SpinlockLocker locker(inputDataSpinlock); return mousePos; } }; }; #endif /* BACKENDS_INPUT_H */ lightspark-0.7.2/src/backends/interfaces/000077500000000000000000000000001212105246600203535ustar00rootroot00000000000000lightspark-0.7.2/src/backends/interfaces/CMakeLists.txt000066400000000000000000000022141212105246600231120ustar00rootroot00000000000000#************************************************************************** # Lightspark, a free flash player implementation # # Copyright (C) 2010-2012 Alessandro Pignotti # Copyright (C) 2010 Giacomo Spigler # Copyright (C) 2010 Alexandre Demers # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . #************************************************************************** include_directories(".") INCLUDE_DIRECTORIES("..") add_subdirectory(audio) lightspark-0.7.2/src/backends/interfaces/IPlugin.cpp000066400000000000000000000027031212105246600224300ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2010 Alexandre Demers (papouta@hotmail.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "backends/interfaces/IPlugin.h" IPlugin::IPlugin ( PLUGIN_TYPES plugin_type, std::string plugin_name, std::string backend_name ) : pluginName ( plugin_name ), backendName ( backend_name ), pluginType ( plugin_type ) { } const std::string IPlugin::get_pluginName() { return pluginName; } PLUGIN_TYPES IPlugin::get_pluginType() { return pluginType; } const std::string IPlugin::get_backendName() { return backendName; } IPlugin::~IPlugin() { } lightspark-0.7.2/src/backends/interfaces/IPlugin.h000066400000000000000000000040031212105246600220700ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2010 Alexandre Demers (papouta@hotmail.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_INTERFACES_IPLUGIN_H #define BACKENDS_INTERFACES_IPLUGIN_H 1 #include #include "compat.h" enum PLUGIN_TYPES { UNDEFINED = 0, AUDIO, VIDEO, DECODER, ENCODER }; class IPlugin { public: virtual const std::string get_pluginName(); virtual PLUGIN_TYPES get_pluginType(); virtual const std::string get_backendName(); virtual ~IPlugin(); protected: std::string pluginName; //name of the plugin std::string backendName; //backend supported by the plugin PLUGIN_TYPES pluginType; //type of plugin of PLUGIN_TYPES IPlugin ( PLUGIN_TYPES plugin_type, std::string plugin_name, std::string backend_name ); }; /************************* Extern "C" functions that each plugin must implement in order to be recognized as a plugin by us. It allows us to share a common interface between plugins and the application. Plugin factory function extern "C" IPlugin* create(); Plugin cleanup function extern "C" void release(IPlugin* p_plugin); ***************************/ #endif /* BACKENDS_INTERFACES_IPLUGIN_H */ lightspark-0.7.2/src/backends/interfaces/audio/000077500000000000000000000000001212105246600214545ustar00rootroot00000000000000lightspark-0.7.2/src/backends/interfaces/audio/CMakeLists.txt000066400000000000000000000027461212105246600242250ustar00rootroot00000000000000#************************************************************************** # Lightspark, a free flash player implementation # # Copyright (C) 2010-2012 Alessandro Pignotti # Copyright (C) 2010 Giacomo Spigler # Copyright (C) 2010 Alexandre Demers # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . #************************************************************************** include_directories(".") INCLUDE_DIRECTORIES("..") #Export symbols IF(WIN32) ADD_DEFINITIONS("-DDLL_PUBLIC=__declspec(dllexport)") ENDIF() IF(${AUDIO_BACKEND} MATCHES "pulse") add_subdirectory(pulse) ENDIF(${AUDIO_BACKEND} MATCHES "pulse") IF(${AUDIO_BACKEND} MATCHES "winmm") add_subdirectory(winmm) ENDIF() IF(${AUDIO_BACKEND} MATCHES "sdl") add_subdirectory(sdl) ENDIF(${AUDIO_BACKEND} MATCHES "sdl") lightspark-0.7.2/src/backends/interfaces/audio/IAudioPlugin.cpp000066400000000000000000000035051212105246600245140ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2010 Alexandre Demers (papouta@hotmail.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "backends/interfaces/audio/IAudioPlugin.h" #include using namespace std; IAudioPlugin::IAudioPlugin ( string plugin_name, string backend_name, bool init_stopped ): IPlugin(AUDIO, plugin_name, backend_name), stopped(init_stopped), muteAllStreams(false) { } string IAudioPlugin::get_device ( DEVICE_TYPES desiredType ) { if ( PLAYBACK ) { return playbackDeviceName; } else if ( CAPTURE ) { return captureDeviceName; } else { return NULL; } } vector< string* > *IAudioPlugin::get_devicesList ( DEVICE_TYPES desiredType ) { if ( desiredType == PLAYBACK ) { return &playbackDevicesList; } else if ( desiredType == CAPTURE ) { return &captureDevicesList; } else { return NULL; } } IAudioPlugin::~IAudioPlugin() { } AudioStream::AudioStream ( lightspark::AudioDecoder* dec ): decoder(dec) { } lightspark-0.7.2/src/backends/interfaces/audio/IAudioPlugin.h000066400000000000000000000057321212105246600241650ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2010 Alexandre Demers (papouta@hotmail.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_INTERFACES_AUDIO_IAUDIOPLUGIN_H #define BACKENDS_INTERFACES_AUDIO_IAUDIOPLUGIN_H 1 #include "compat.h" #include "backends/decoder.h" #include "backends/interfaces/IPlugin.h" #include class AudioStream { protected: AudioStream(lightspark::AudioDecoder *dec = NULL); public: lightspark::AudioDecoder *decoder; virtual bool ispaused() = 0; //Is the stream paused? (corked) virtual bool isValid() = 0; //Is the stream alive, fully working? virtual void pause() = 0; virtual void resume() = 0; virtual uint32_t getPlayedTime() = 0; virtual ~AudioStream() {}; virtual void setVolume(double volume) {LOG(LOG_NOT_IMPLEMENTED,"setVolume not implemented in plugin");} }; /********************** Abstract class for audio plugin implementation ***********************/ class IAudioPlugin : public IPlugin { protected: bool stopped; bool muteAllStreams; volatile bool contextReady; volatile bool noServer; std::string playbackDeviceName; std::string captureDeviceName; std::vector playbackDevicesList; std::vector captureDevicesList; std::list streams; typedef std::list::iterator stream_iterator; IAudioPlugin ( std::string plugin_name, std::string backend_name, bool init_stopped = false ); public: enum DEVICE_TYPES { PLAYBACK, CAPTURE }; virtual std::vector *get_devicesList ( DEVICE_TYPES desiredType ); virtual void set_device ( std::string desiredDevice, DEVICE_TYPES desiredType ) = 0; virtual std::string get_device ( DEVICE_TYPES desiredType ); virtual AudioStream *createStream ( lightspark::AudioDecoder *decoder ) = 0; virtual bool isTimingAvailable() const = 0; virtual void muteAll() { muteAllStreams = true; } virtual void unmuteAll() { muteAllStreams = false; } virtual void toggleMuteAll() { muteAllStreams ? unmuteAll() : muteAll(); } virtual bool allMuted() { return muteAllStreams; } virtual ~IAudioPlugin(); }; #endif /* BACKENDS_INTERFACES_AUDIO_IAUDIOPLUGIN */ lightspark-0.7.2/src/backends/interfaces/audio/pulse/000077500000000000000000000000001212105246600226045ustar00rootroot00000000000000lightspark-0.7.2/src/backends/interfaces/audio/pulse/CMakeLists.txt000066400000000000000000000051051212105246600253450ustar00rootroot00000000000000#************************************************************************** # Lightspark, a free flash player implementation # # Copyright (C) 2010-2012 Alessandro Pignotti # Copyright (C) 2010 Giacomo Spigler # Copyright (C) 2010 Alexandre Demers # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . #************************************************************************** ## Compiler defaults flags for different profiles #SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wnon-virtual-dtor -Woverloaded-virtual -pipe -fvisibility=hidden -fvisibility-inlines-hidden -std=c++0x") # #SET(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -DEXPENSIVE_DEBUG") #SET(CMAKE_CXX_FLAGS_PROFILE "-g -pg -O2") #SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") #SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -O2 -DNDEBUG") #SET(CMAKE_CXX_FLAGS_DEBIAN "-O2 -DNDEBUG") #SET(CMAKE_CXX_FLAGS_LEANDEBUG "-g -O2") INCLUDE_DIRECTORIES(".") INCLUDE_DIRECTORIES("..") pkg_check_modules(PULSE_LIBS REQUIRED libpulse) INCLUDE_DIRECTORIES(${PULSE_LIBS_INCLUDE_DIRS}) if(!Boost_FOUND) find_package(Boost COMPONENTS filesystem system regex) if(Boost_FOUND) INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) endif(Boost_FOUND) endif(!Boost_FOUND) ADD_DEFINITIONS(-DPULSE_BACKEND=TRUE) SET(PULSEPLUGIN_SOURCES PulsePlugin.cpp ../../IPlugin.cpp ../IAudioPlugin.cpp) # liblightsparkpulseplugin.so target ADD_LIBRARY(pulseplugin MODULE ${PULSEPLUGIN_SOURCES}) TARGET_LINK_LIBRARIES(pulseplugin spark) #Need to link some functions with the decoders TARGET_LINK_LIBRARIES(pulseplugin ${PULSE_LIBS_LIBRARIES} ${Boost_LIBRARIES}) SET_TARGET_PROPERTIES(pulseplugin PROPERTIES OUTPUT_NAME lightsparkpulseplugin) #SET_TARGET_PROPERTIES(pulseplugin PROPERTIES VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}") #SET_TARGET_PROPERTIES(pulseplugin PROPERTIES SOVERSION "${MAJOR_VERSION}.${MINOR_VERSION}") INSTALL(TARGETS pulseplugin LIBRARY DESTINATION ${PLUGINSDIR}) lightspark-0.7.2/src/backends/interfaces/audio/pulse/PulsePlugin.cpp000066400000000000000000000275301212105246600255660ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2010 Alexandre Demers (papouta@hotmail.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include #include "backends/interfaces/audio/pulse/PulsePlugin.h" #include "compat.h" #include "backends/decoder.h" #include #include #define _(STRING) gettext(STRING) using namespace lightspark; using namespace std; PulsePlugin::PulsePlugin (string init_Name, string init_audiobackend, bool init_contextReady, bool init_noServer, bool init_stopped ) : IAudioPlugin ( init_Name, init_audiobackend, init_stopped ) { contextReady = init_contextReady; noServer = init_noServer; stopped = init_stopped; start(); } void PulsePlugin::start() { mainLoop = pa_threaded_mainloop_new(); pa_threaded_mainloop_start ( mainLoop ); pulseLock(); context = pa_context_new ( pa_threaded_mainloop_get_api ( mainLoop ), "Lightspark" ); pa_context_set_state_callback ( context, ( pa_context_notify_cb_t ) contextStatusCB, this ); pa_context_connect ( context, NULL, PA_CONTEXT_NOFLAGS, NULL ); pulseUnlock(); } void PulsePlugin::set_device ( string desiredDevice, DEVICE_TYPES desiredType ) { playbackDeviceName = desiredDevice; pulseLock(); if(desiredType == PLAYBACK) { //Add code to change playback device } else if(desiredType == CAPTURE) { //Add code to change capture device } pulseUnlock(); } void PulsePlugin::generateDevicesList ( vector< string* >* devicesList, DEVICE_TYPES desiredType ) { pulseLock(); if(desiredType == PLAYBACK) { pa_context_get_sink_info_list ( context, playbackListCB, &playbackDevicesList ); } else if(desiredType == CAPTURE) { pa_context_get_source_info_list ( context, captureListCB, &captureDevicesList ); } pulseUnlock(); } void PulsePlugin::captureListCB ( pa_context* context, const pa_source_info* list, int eol, void *th ) { PulsePlugin *oPlugin = ( PulsePlugin * ) th; string deviceName ( list->name ); if ( !eol && list ) //Device found { oPlugin->captureDevicesList.push_back( new string (deviceName)); } } void PulsePlugin::playbackListCB ( pa_context* context, const pa_sink_info* list, int eol, void *th ) { PulsePlugin *oPlugin = ( PulsePlugin * ) th; string deviceName ( list->name ); if ( !eol && list ) //Device found { oPlugin->playbackDevicesList.push_back( new string (deviceName) ); } } void PulsePlugin::streamStatusCB ( pa_stream *stream, PulseAudioStream *th ) { if ( pa_stream_get_state ( stream ) == PA_STREAM_READY ) { th->streamStatus = PulseAudioStream::STREAM_READY; if ( th->decoder->hasDecodedFrames() ) { //Now that the stream is ready fill it size_t availableSize = pa_stream_writable_size ( th->stream ); th->fillStream( availableSize ); } } else if ( pa_stream_get_state ( stream ) == PA_STREAM_TERMINATED || pa_stream_get_state ( stream ) == PA_STREAM_FAILED ) { assert ( stream == th->stream ); th->streamStatus = PulseAudioStream::STREAM_DEAD; } } void PulsePlugin::streamWriteCB ( pa_stream *stream, size_t askedData, PulseAudioStream *th ) { th->fillStream(askedData); } bool PulsePlugin::isTimingAvailable() const { return serverAvailable(); } PulseAudioStream::~PulseAudioStream() { manager->pulseLock(); if( manager->serverAvailable() ) pa_stream_disconnect( stream ); //Do not delete the stream now, let's wait termination. However, removing it from the list. manager->streams.remove(this); manager->pulseUnlock(); while( streamStatus != PulseAudioStream::STREAM_DEAD ); manager->pulseLock(); if( stream ) pa_stream_unref ( stream ); manager->pulseUnlock(); } void PulsePlugin::streamOverflowCB( pa_stream *p, void *userdata ) { LOG(LOG_INFO, "AUDIO BACKEND: Stream overflow"); } void PulsePlugin::streamUnderflowCB( pa_stream *p, void *userdata ) { LOG(LOG_INFO, "AUDIO BACKEND: Stream underflow"); } void PulsePlugin::streamStartedCB( pa_stream *p, void *userdata ) { LOG(LOG_INFO, "AUDIO BACKEND: Stream started"); } AudioStream *PulsePlugin::createStream ( AudioDecoder *decoder ) { PulseAudioStream *audioStream = new PulseAudioStream( this ); streams.push_back( audioStream ); //Create new SoundStream if ( serverAvailable() ) { while ( !contextReady ); pulseLock(); assert ( decoder->isValid() ); audioStream->decoder = decoder; pa_sample_spec ss; ss.format = PA_SAMPLE_S16LE; ss.rate = decoder->sampleRate; ss.channels = decoder->channelCount; pa_buffer_attr attrs; attrs.maxlength = ( uint32_t ) - 1; attrs.prebuf = 0; attrs.tlength = ( uint32_t ) - 1; attrs.fragsize = ( uint32_t ) - 1; attrs.minreq = ( uint32_t ) - 1; audioStream->stream = pa_stream_new ( context, "AudioStream", &ss, NULL ); pa_stream_set_state_callback ( audioStream->stream, ( pa_stream_notify_cb_t ) streamStatusCB, audioStream ); pa_stream_set_write_callback ( audioStream->stream, ( pa_stream_request_cb_t ) streamWriteCB, audioStream ); pa_stream_set_underflow_callback ( audioStream->stream, ( pa_stream_notify_cb_t ) streamUnderflowCB, NULL ); pa_stream_set_overflow_callback ( audioStream->stream, ( pa_stream_notify_cb_t ) streamOverflowCB, NULL ); pa_stream_set_started_callback ( audioStream->stream, ( pa_stream_notify_cb_t ) streamStartedCB, NULL ); pa_stream_flags flags = (pa_stream_flags) PA_STREAM_START_CORKED; if(muteAllStreams) flags = (pa_stream_flags) (flags | PA_STREAM_START_MUTED); pa_stream_connect_playback ( audioStream->stream, NULL, &attrs, flags, NULL, NULL ); pulseUnlock(); } else { //Create the stream as dead audioStream->streamStatus = PulseAudioStream::STREAM_DEAD; } return audioStream; } void PulsePlugin::contextStatusCB ( pa_context *context, PulsePlugin *th ) { switch ( pa_context_get_state ( context ) ) { case PA_CONTEXT_READY: th->noServer = false; //In case something went wrong and the context is not correctly set th->contextReady = true; break; case PA_CONTEXT_FAILED: LOG(LOG_ERROR,_("AUDIO BACKEND: Connection to PulseAudio server failed")); case PA_CONTEXT_TERMINATED: th->noServer = true; th->contextReady = false; //In case something went wrong and the context is not correctly set th->stop(); //It should stop if the context can't be set break; default: break; } } void PulseAudioStream::pause() { if(isValid() && !ispaused()) { pa_stream_cork(stream, 1, NULL, NULL); //This will stop the stream's time from running paused=true; } } void PulseAudioStream::resume() { if(isValid() && ispaused()) { pa_stream_cork(stream, 0, NULL, NULL); //This will restart time paused=false; } } void PulsePlugin::pulseLock() { pa_threaded_mainloop_lock(mainLoop);; } void PulsePlugin::pulseUnlock() { pa_threaded_mainloop_unlock(mainLoop); } bool PulsePlugin::serverAvailable() const { return !noServer; } PulsePlugin::~PulsePlugin() { stop(); } void PulsePlugin::stop() { if ( !stopped ) { stopped = true; for ( stream_iterator it = streams.begin();it != streams.end(); ++it ) { delete *it; } if(serverAvailable()) { pulseLock(); pa_context_disconnect ( context ); pa_context_unref ( context ); pulseUnlock(); pa_threaded_mainloop_stop ( mainLoop ); pa_threaded_mainloop_free ( mainLoop ); } } } void PulsePlugin::muteAll() { IAudioPlugin::muteAll(); for ( stream_iterator it = streams.begin();it != streams.end(); ++it ) { ((PulseAudioStream*) (*it))->mute(); } } void PulsePlugin::unmuteAll() { IAudioPlugin::unmuteAll(); for ( stream_iterator it = streams.begin();it != streams.end(); ++it ) { ((PulseAudioStream*) (*it))->unmute(); } } /**************************** Stream's functions ****************************/ PulseAudioStream::PulseAudioStream ( PulsePlugin* m ) : AudioStream(NULL), paused(false), stream ( NULL ), manager ( m ), streamStatus ( STREAM_STARTING ), streamVolume(0.0) { } uint32_t PulseAudioStream::getPlayedTime ( ) { if ( streamStatus != STREAM_READY ) //The stream is not yet ready, delay upload return 0; manager->pulseLock(); //Request updated timing info pa_operation* timeUpdate = pa_stream_update_timing_info ( stream, NULL, NULL ); manager->pulseUnlock(); while ( pa_operation_get_state ( timeUpdate ) != PA_OPERATION_DONE ); manager->pulseLock(); pa_operation_unref ( timeUpdate ); pa_usec_t time; pa_stream_get_time ( stream, &time ); manager->pulseUnlock(); return time / 1000; } void PulseAudioStream::fillStream(size_t toSend) { /* Write data until we have space on the server and we have data available. * pa_stream_begin_write will return maximum 65472 bytes, but toSend is usually much bigger * so we loop until it is filled or we have no more decoded data */ while(toSend) { int16_t *dest; uint32_t totalWritten = 0; size_t frameSize = toSend; int ret = pa_stream_begin_write ( stream, ( void** ) &dest, &frameSize ); (void)ret; // silence warning about unused variable assert(!ret); toSend -= frameSize; if (frameSize == 0) break; /* copy frames from the decoder until the buffer is full */ do { uint32_t retSize = decoder->copyFrame ( dest + ( totalWritten / 2 ), frameSize ); if ( retSize == 0 ) //There is no more data break; totalWritten += retSize; frameSize -= retSize; } while ( frameSize ); if ( totalWritten ) { pa_stream_write ( stream, dest, totalWritten, NULL, 0, PA_SEEK_RELATIVE ); } else { //there was not any decoded data available pa_stream_cancel_write ( stream ); break; } } if(!paused && pa_stream_is_corked(stream)) pa_stream_cork ( stream, 0, NULL, NULL ); //Start the stream, just in case it's still stopped } bool PulseAudioStream::ispaused() { assert_and_throw(isValid()); return pa_stream_is_corked(stream); } bool PulseAudioStream::isValid() { return streamStatus != STREAM_DEAD; } void PulseAudioStream::mute() { pa_context_set_sink_input_mute( pa_stream_get_context(stream), pa_stream_get_index(stream), 1, NULL, NULL ); } void PulseAudioStream::unmute() { pa_context_set_sink_input_mute( pa_stream_get_context(stream), pa_stream_get_index(stream), 0, NULL, NULL ); } void PulseAudioStream::sinkInfoForSettingVolumeCB(pa_context* context, const pa_sink_info* i, int eol, PulseAudioStream* stream) { if(eol) { //The callback is called multiple times even if querying a single device return; } struct pa_cvolume volume; pa_sw_cvolume_multiply_scalar(&volume, &i->volume, stream->streamVolume*PA_VOLUME_NORM); pa_context_set_sink_input_volume( context, pa_stream_get_index(stream->stream), &volume, NULL, NULL ); } void PulseAudioStream::setVolume(double vol) { if(vol==streamVolume) return; streamVolume=vol; uint32_t deviceIndex = pa_stream_get_device_index(stream); pa_operation* op=pa_context_get_sink_info_by_index( pa_stream_get_context(stream), deviceIndex, (pa_sink_info_cb_t)sinkInfoForSettingVolumeCB, this); pa_operation_unref(op); } // Plugin factory function extern "C" DLL_PUBLIC IPlugin *create() { return new PulsePlugin(); } // Plugin cleanup function extern "C" DLL_PUBLIC void release ( IPlugin *p_plugin ) { //delete the previously created object delete p_plugin; } lightspark-0.7.2/src/backends/interfaces/audio/pulse/PulsePlugin.h000066400000000000000000000067241212105246600252350ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2010 Alexandre Demers (papouta@hotmail.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_INTERFACES_AUDIO_PULSEPLUGIN_H #define BACKENDS_INTERFACES_AUDIO_PULSEPLUGIN_H 1 #include #include "backends/interfaces/audio/IAudioPlugin.h" #include "backends/decoder.h" #include "compat.h" #include class PulseAudioStream; //Early declaration class PulsePlugin : public IAudioPlugin { friend class PulseAudioStream; private: pa_threaded_mainloop *mainLoop; pa_context *context; static void contextStatusCB ( pa_context *context, PulsePlugin *th ); void start(); void stop(); static void playbackListCB ( pa_context *context, const pa_sink_info *list, int eol, void *th ); static void captureListCB ( pa_context *context, const pa_source_info *list, int eol, void *th ); //To populate the devices lists, devicesType must be playback or capture void generateDevicesList ( std::vector *devicesList, DEVICE_TYPES desiredType ); static void streamStatusCB ( pa_stream *stream, PulseAudioStream *th ); static void streamWriteCB ( pa_stream *stream, size_t nbytes, PulseAudioStream *th ); static void streamStartedCB ( pa_stream *p, void *userdata ); static void streamUnderflowCB ( pa_stream *p, void *userdata ); static void streamOverflowCB ( pa_stream *p, void *userdata ); bool contextReady; bool noServer; public: PulsePlugin ( std::string init_Name = "Pulse plugin output only", std::string init_audiobackend = "pulseaudio", bool init_contextReady = false, bool init_noServer = false, bool init_stopped = false ); void set_device ( std::string desiredDevice, DEVICE_TYPES desiredType ); AudioStream *createStream ( lightspark::AudioDecoder *decoder ); bool isTimingAvailable() const; void pulseLock(); void pulseUnlock(); bool serverAvailable() const; void muteAll(); void unmuteAll(); ~PulsePlugin(); }; class PulseAudioStream: public AudioStream { friend class PulsePlugin; public: enum STREAM_STATUS { STREAM_STARTING = 0, STREAM_READY = 1, STREAM_DEAD = 2 }; PulseAudioStream ( PulsePlugin *m ); uint32_t getPlayedTime (); bool ispaused(); bool isValid(); void pause(); void resume(); static void sinkInfoForSettingVolumeCB(pa_context* context, const pa_sink_info* i, int eol, PulseAudioStream* stream); ~PulseAudioStream(); private: bool paused; pa_stream *stream; PulsePlugin *manager; volatile STREAM_STATUS streamStatus; double streamVolume; void mute(); void unmute(); void setVolume(double volume); void fillStream(size_t frameSize); }; #endif /* BACKENDS_INTERFACES_AUDIO_PULSEPLUGIN_H */ lightspark-0.7.2/src/backends/interfaces/audio/sdl/000077500000000000000000000000001212105246600222365ustar00rootroot00000000000000lightspark-0.7.2/src/backends/interfaces/audio/sdl/CMakeLists.txt000066400000000000000000000045041212105246600250010ustar00rootroot00000000000000#************************************************************************** # Lightspark, a free flash player implementation # # Copyright (C) 2010-2012 Alessandro Pignotti # Copyright (C) 2010 Giacomo Spigler # Copyright (C) 2010 Alexandre Demers # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . #************************************************************************** ## Compiler defaults flags for different profiles #SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wnon-virtual-dtor -Woverloaded-virtual -pipe -fvisibility=hidden -fvisibility-inlines-hidden -std=c++0x") # #SET(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -DEXPENSIVE_DEBUG") #SET(CMAKE_CXX_FLAGS_PROFILE "-g -pg -O2") #SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") #SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -O2 -DNDEBUG") #SET(CMAKE_CXX_FLAGS_DEBIAN "-O2 -DNDEBUG") #SET(CMAKE_CXX_FLAGS_LEANDEBUG "-g -O2") INCLUDE_DIRECTORIES(".") INCLUDE_DIRECTORIES("..") pkg_check_modules(SDL REQUIRED sdl) INCLUDE_DIRECTORIES(${SDL_INCLUDE_DIRS}) if(!Boost_FOUND) find_package(Boost COMPONENTS filesystem system regex) if(Boost_FOUND) INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) endif(Boost_FOUND) endif(!Boost_FOUND) ADD_DEFINITIONS(-DSDL_BACKEND=TRUE) SET(SDLPLUGIN_SOURCES SDLPlugin.cpp ../../IPlugin.cpp ../IAudioPlugin.cpp) # liblightsparkSDLplugin.so target ADD_LIBRARY(sdlplugin MODULE ${SDLPLUGIN_SOURCES}) TARGET_LINK_LIBRARIES(sdlplugin spark) #Need to link some functions with the decoders TARGET_LINK_LIBRARIES(sdlplugin ${SDL_LIBRARIES} ${Boost_LIBRARIES}) SET_TARGET_PROPERTIES(sdlplugin PROPERTIES OUTPUT_NAME lightsparksdlplugin) INSTALL(TARGETS sdlplugin DESTINATION ${PLUGINSDIR}) lightspark-0.7.2/src/backends/interfaces/audio/sdl/SDLPlugin.cpp000066400000000000000000000115501212105246600245450ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2011-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2011 Ludger Krämer (dbluelle@blau-weissoedingen.de) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "backends/interfaces/audio/sdl/SDLPlugin.h" #include #include using lightspark::AudioDecoder; using namespace std; SDLPlugin::SDLPlugin(string init_Name, string init_audiobackend, bool init_stopped ) : IAudioPlugin ( init_Name, init_audiobackend, init_stopped ) { sdl_available = 0; if (SDL_WasInit(0)) // some part of SDL already was initialized sdl_available = !SDL_InitSubSystem ( SDL_INIT_AUDIO ); else sdl_available = !SDL_Init ( SDL_INIT_AUDIO ); /* We use SDL_OpenAudio/SDL_CloseAudio in SDLAudioStream's constructor/destructor * to access the device directly. We _should_ use SDL_mixer instead. */ LOG(LOG_NOT_IMPLEMENTED,"The SDL audio plugin does only support one concurrent stream!"); } void SDLPlugin::set_device(std::string desiredDevice, IAudioPlugin::DEVICE_TYPES desiredType) { /* not yet implemented */ } AudioStream* SDLPlugin::createStream(AudioDecoder* decoder) { if (!sdl_available) return NULL; SDLAudioStream *stream = new SDLAudioStream(this); stream->decoder = decoder; if (!stream->init()) { delete stream; return NULL; } streams.push_back(stream); return stream; } SDLPlugin::~SDLPlugin() { for (stream_iterator it = streams.begin(); it != streams.end(); ++it) { delete *it; } if (sdl_available) { SDL_QuitSubSystem ( SDL_INIT_AUDIO ); if (!SDL_WasInit(0)) SDL_Quit (); } } bool SDLPlugin::isTimingAvailable() const { return true; } void SDLPlugin::muteAll() { IAudioPlugin::muteAll(); for ( stream_iterator it = streams.begin();it != streams.end(); ++it ) { ((SDLAudioStream*) (*it))->mute(); } } void SDLPlugin::unmuteAll() { IAudioPlugin::unmuteAll(); for ( stream_iterator it = streams.begin();it != streams.end(); ++it ) { ((SDLAudioStream*) (*it))->unmute(); } } /**************************** Stream's functions ****************************/ uint32_t SDLAudioStream::getPlayedTime() { uint32_t ret; struct timeval now; gettimeofday(&now, NULL); ret = playedtime + (now.tv_sec * 1000 + now.tv_usec / 1000) - (starttime.tv_sec * 1000 + starttime.tv_usec / 1000); return ret; } bool SDLAudioStream::init() { SDL_AudioSpec fmt; fmt.freq = decoder->sampleRate; fmt.format = AUDIO_S16; fmt.channels = decoder->channelCount; fmt.samples = 4096; fmt.callback = async_callback; fmt.userdata = this; if ( SDL_OpenAudio(&fmt, NULL) < 0 ) { LOG(LOG_ERROR, "Unable to open SDL audio:" << SDL_GetError()); return false; } unmutevolume = curvolume = SDL_MIX_MAXVOLUME; playedtime = 0; gettimeofday(&starttime, NULL); SDL_PauseAudio(0); return true; } void SDLAudioStream::async_callback(void *unused, uint8_t *stream, int len) { SDLAudioStream *s = static_cast(unused); if (!s->decoder->hasDecodedFrames()) return; uint8_t *buf = new uint8_t[len]; int readcount = 0; while (readcount < len) { if (!s->decoder->hasDecodedFrames()) break; uint32_t ret = s->decoder->copyFrame((int16_t *)(buf+readcount), len-readcount); if (!ret) break; readcount += ret; } SDL_LockAudio(); SDL_MixAudio(stream, buf, readcount, s->curvolume); SDL_UnlockAudio(); delete[] buf; } void SDLAudioStream::SetPause(bool pause_on) { if (pause_on) { playedtime = getPlayedTime(); } else { gettimeofday(&starttime, NULL); } SDL_PauseAudio(pause_on); } bool SDLAudioStream::ispaused() { return SDL_GetAudioStatus() != SDL_AUDIO_PLAYING; } bool SDLAudioStream::isValid() { return true; } void SDLAudioStream::mute() { unmutevolume = curvolume; curvolume = 0; } void SDLAudioStream::unmute() { curvolume = unmutevolume; } void SDLAudioStream::setVolume(double volume) { curvolume = SDL_MIX_MAXVOLUME * volume; } SDLAudioStream::~SDLAudioStream() { manager->streams.remove(this); SDL_CloseAudio(); } extern "C" DLL_PUBLIC IPlugin *create() { return new SDLPlugin(); } extern "C" DLL_PUBLIC void release(IPlugin *plugin) { delete plugin; } lightspark-0.7.2/src/backends/interfaces/audio/sdl/SDLPlugin.h000066400000000000000000000045051212105246600242140ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2011-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2011 Ludger Krämer (dbluelle@blau-weissoedingen.de) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_INTERFACES_AUDIO_SDL_SDLPLUGIN_H #define BACKENDS_INTERFACES_AUDIO_SDL_SDLPLUGIN_H 1 #include "backends/interfaces/audio/IAudioPlugin.h" #include "backends/decoder.h" #include "compat.h" #include using lightspark::AudioDecoder; class SDLAudioStream; class SDLPlugin : public IAudioPlugin { friend class SDLAudioStream; private: int sdl_available; public: SDLPlugin ( std::string init_Name = "SDL plugin", std::string init_audiobackend = "sdl", bool init_stopped = false ); void set_device(std::string desiredDevice, IAudioPlugin::DEVICE_TYPES desiredType); AudioStream *createStream(AudioDecoder *decoder); void muteAll(); void unmuteAll(); bool isTimingAvailable() const; ~SDLPlugin(); }; class SDLAudioStream: public AudioStream { private: SDLPlugin* manager; int curvolume; int unmutevolume; uint32_t playedtime; struct timeval starttime; static void async_callback(void *unused, uint8_t *stream, int len); public: bool init(); SDLAudioStream(SDLPlugin* _manager) : manager(_manager) { } void SetPause(bool pause_on); uint32_t getPlayedTime(); bool ispaused(); bool isValid(); void mute(); void unmute(); void pause() { SetPause(true); } void resume() { SetPause(false); } void setVolume(double volume); ~SDLAudioStream(); }; #endif /* BACKENDS_INTERFACES_AUDIO_SDL_SDLPLUGIN_H */ lightspark-0.7.2/src/backends/interfaces/audio/winmm/000077500000000000000000000000001212105246600226035ustar00rootroot00000000000000lightspark-0.7.2/src/backends/interfaces/audio/winmm/CMakeLists.txt000066400000000000000000000026121212105246600253440ustar00rootroot00000000000000#************************************************************************** # Lightspark, a free flash player implementation # # Copyright (C) 2010-2012 Alessandro Pignotti # Copyright (C) 2010 Giacomo Spigler # Copyright (C) 2010 Alexandre Demers # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . #************************************************************************** INCLUDE_DIRECTORIES(".") INCLUDE_DIRECTORIES("..") ADD_LIBRARY(winmmplugin MODULE WinMMPlugin.cpp ../../IPlugin.cpp ../IAudioPlugin.cpp) SET_TARGET_PROPERTIES(winmmplugin PROPERTIES OUTPUT_NAME lightsparkwinmmplugin) TARGET_LINK_LIBRARIES(winmmplugin spark winmm) INSTALL(TARGETS winmmplugin LIBRARY DESTINATION ${PLUGINSDIR}) lightspark-0.7.2/src/backends/interfaces/audio/winmm/WinMMPlugin.cpp000066400000000000000000000153301212105246600254570ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2010 Alexandre Demers (papouta@hotmail.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include #include "backends/interfaces/audio/winmm/WinMMPlugin.h" #include "compat.h" #include "backends/decoder.h" using namespace lightspark; using namespace std; WinMMPlugin::WinMMPlugin() : IAudioPlugin( "Windows WaveOut plugin", "winmm" ) { } void WinMMPlugin::set_device( std::string desiredDevice, DEVICE_TYPES desiredType ) { } AudioStream *WinMMPlugin::createStream ( AudioDecoder *decoder ) { WinMMStream *audioStream = new WinMMStream( decoder, this ); streams.push_back( audioStream ); //Create new SoundStream return audioStream; } WinMMPlugin::~WinMMPlugin() { while(!streams.empty()) delete streams.front(); } /**************************** Stream's functions ****************************/ WinMMStream::WinMMStream( AudioDecoder* d, WinMMPlugin* m ) : AudioStream(d), manager(m), freeBuffers(NUM_BUFFERS), curBuffer(0), threadAborting(false), paused(false) { assert(decoder->sampleRate > 0); /* 1/10 seconds per buffer * This should not cause any a/v-desync, * as getPlayedTime() returns the actual playhead * position, not the time we have buffered. */ bufferSize = decoder->sampleRate * 2 / 10; WAVEFORMATEX wfx; wfx.nSamplesPerSec = decoder->sampleRate; /* sample rate */ wfx.wBitsPerSample = 16; /* sample size */ wfx.nChannels = decoder->channelCount; /* channels*/ wfx.cbSize = 0; /* size of _extra_ info */ wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nBlockAlign = (wfx.wBitsPerSample >> 3) * wfx.nChannels; wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec; if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfx, (DWORD_PTR)&waveOutProc, (DWORD_PTR)this, CALLBACK_FUNCTION) != MMSYSERR_NOERROR) LOG(LOG_ERROR,"unable to open WAVE_MAPPER device"); if(waveOutSetVolume(hWaveOut, 0xFFFFFFFF) != MMSYSERR_NOERROR) LOG(LOG_ERROR,"waveOutSetVolume failed"); memset(buffer, 0, sizeof(buffer)); for(uint32_t i=0; i < NUM_BUFFERS; ++i) { aligned_malloc((void**)&buffer[i].lpData, wfx.nBlockAlign, bufferSize); buffer[i].dwBufferLength = bufferSize; } #ifdef HAVE_NEW_GLIBMM_THREAD_API workerThread = Thread::create(sigc::mem_fun(this,&WinMMStream::worker)); #else workerThread = Thread::create(sigc::mem_fun(this,&WinMMStream::worker), true); #endif } WinMMStream::~WinMMStream() { Mutex::Lock l(mutex); manager->streams.remove(this); threadAborting = true; /* wake up worker() */ freeBuffers.signal(); workerThread->join(); /* Stop playing */ if(waveOutReset(hWaveOut) != MMSYSERR_NOERROR) LOG(LOG_ERROR,"waveOutReset failed"); /* Close handle */ if(waveOutClose(hWaveOut) != MMSYSERR_NOERROR) LOG(LOG_ERROR,"waveOutClose failed"); for(uint32_t i=0; i < NUM_BUFFERS; ++i) aligned_free(buffer[i].lpData); } void CALLBACK WinMMStream::waveOutProc(HWAVEOUT hWaveOut, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) { if(uMsg != WOM_DONE) return; WinMMStream* stream = (WinMMStream*)dwInstance; stream->freeBuffers.signal(); } void WinMMStream::worker() { while(!threadAborting) { freeBuffers.wait(); if(threadAborting) return; Mutex::Lock l(mutex); /* Unprepare previous data */ if(buffer[curBuffer].dwFlags & WHDR_PREPARED && waveOutUnprepareHeader(hWaveOut, &buffer[curBuffer], sizeof(WAVEHDR)) != MMSYSERR_NOERROR) LOG(LOG_ERROR,"waveOutUnprepareHeader failed"); /* Copy data from decoder */ uint32_t freeSize = bufferSize; int8_t* curBufPos = (int8_t*)buffer[curBuffer].lpData; while(freeSize && !threadAborting) { /* copy min(freeSize,available) to buffer */ uint32_t retSize = decoder->copyFrame ( (int16_t*)curBufPos, freeSize ); freeSize -= retSize; curBufPos += retSize; } buffer[curBuffer].dwBufferLength = bufferSize; buffer[curBuffer].dwFlags = 0; /* Prepare current data */ if(waveOutPrepareHeader(hWaveOut, &buffer[curBuffer], sizeof(WAVEHDR)) != MMSYSERR_NOERROR) LOG(LOG_ERROR,"waveOutPrepareHeader failed"); /* Write it to the device */ if(waveOutWrite(hWaveOut, &buffer[curBuffer], sizeof(WAVEHDR)) != MMSYSERR_NOERROR) LOG(LOG_ERROR,"waveOutWrite failed"); curBuffer = (curBuffer + 1) % NUM_BUFFERS; } } void WinMMStream::pause() { Mutex::Lock l(mutex); /* nop if already paused */ waveOutPause(hWaveOut); paused = true; } void WinMMStream::resume() { Mutex::Lock l(mutex); /* nop if not paused */ waveOutRestart(hWaveOut); paused = false; } uint32_t WinMMStream::getPlayedTime( ) { Mutex::Lock l(mutex); MMTIME mmtime; /* TIME_MS does not work with every driver */ mmtime.wType = TIME_SAMPLES; if(waveOutGetPosition(hWaveOut, &mmtime, sizeof(mmtime)) != MMSYSERR_NOERROR) { LOG(LOG_ERROR,"waveOutGetPosition failed"); return 0; } if(mmtime.wType != TIME_SAMPLES) { LOG(LOG_ERROR,"Could not obtain playback time correct format, is " << mmtime.wType); return 0; } return (double)mmtime.u.sample / (double)decoder->sampleRate * 1000.0; } bool WinMMStream::ispaused() { return paused; } bool WinMMStream::isValid() { return true; } void WinMMStream::mute() { Mutex::Lock l(mutex); DWORD curVolume; waveOutGetVolume(hWaveOut, &curVolume); if(curVolume != 0) { waveOutSetVolume(hWaveOut, 0); preMuteVolume = curVolume; } } void WinMMStream::unmute() { Mutex::Lock l(mutex); DWORD curVolume; waveOutGetVolume(hWaveOut, &curVolume); if(curVolume == 0) waveOutSetVolume(hWaveOut, preMuteVolume); } void WinMMStream::setVolume(double vol) { Mutex::Lock l(mutex); /* map vol = 0.0 to 0x0000 and vol = 1.0 to 0xFFFF, * lower word is left channel, higher word is right channel */ DWORD dwvol = MAKELPARAM(0xFFFF*vol, 0xFFFF*vol); waveOutSetVolume(hWaveOut, dwvol); } // Plugin factory function extern "C" DLL_PUBLIC IPlugin *create() { return new WinMMPlugin(); } // Plugin cleanup function extern "C" DLL_PUBLIC void release ( IPlugin *p_plugin ) { //delete the previously created object delete p_plugin; } lightspark-0.7.2/src/backends/interfaces/audio/winmm/WinMMPlugin.h000066400000000000000000000046671212105246600251370ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2010 Alexandre Demers (papouta@hotmail.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_INTERFACES_AUDIO_WINMM_WINMMPLUGIN_H #define BACKENDS_INTERFACES_AUDIO_WINMM_WINMMPLUGIN_H 1 #include #include #undef RGB //conflicts with swftypes.h #include #include "backends/interfaces/audio/IAudioPlugin.h" #include "backends/decoder.h" #include "compat.h" #include "threading.h" namespace lightspark { class WinMMStream; //Early declaration #define NUM_BUFFERS (4) class WinMMPlugin : public IAudioPlugin { friend class WinMMStream; private: public: WinMMPlugin(); void set_device( std::string desiredDevice, DEVICE_TYPES desiredType ); AudioStream *createStream( lightspark::AudioDecoder *decoder ); bool isTimingAvailable() const { return true; }; ~WinMMPlugin(); }; class WinMMStream: public AudioStream { friend class WinMMPlugin; private: WinMMPlugin* manager; Semaphore freeBuffers; WAVEHDR buffer[NUM_BUFFERS]; uint32_t curBuffer; Thread* workerThread; volatile bool threadAborting; DWORD preMuteVolume; bool paused; HWAVEOUT hWaveOut; uint32_t bufferSize; Mutex mutex; void worker(); static void CALLBACK waveOutProc(HWAVEOUT hWaveOut, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); public: WinMMStream(AudioDecoder* d, WinMMPlugin* m ); uint32_t getPlayedTime(); bool ispaused(); bool isValid(); void pause(); void resume(); void mute(); void unmute(); void setVolume(double); ~WinMMStream(); }; } #endif /* BACKENDS_INTERFACES_AUDIO_WINMM_WINMMPLUGIN_H */ lightspark-0.7.2/src/backends/lsopengl.h000066400000000000000000000033571212105246600202340ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2011-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_LSOPENGL_H #define BACKENDS_LSOPENGL_H 1 #ifdef ENABLE_GLES2 #define SUPPORT_X11 1 //Needed for SGX/OMAP GL stack #include #include #include //Texture formats #ifdef GL_EXT_texture_format_BGRA8888 #define GL_RGBA8 GL_RGBA #define GL_BGRA GL_RGBA #else #error GL_EXT_texture_format_BGRA8888 extension needed #endif //there are no multiple buffers in GLES 2.0 #define glDrawBuffer(x) #define glBindBuffer(...) #define glBufferData(...) #define glPixelStorei(...) #else //GLEW_NO_GLU tells glew.h to not include glu.h. Required to //compile on systems without glu.h. #define GLEW_NO_GLU #include #ifndef _WIN32 #include #endif #undef None // conflicts with libxml++ headers #endif #endif /* BACKENDS_LSOPENGL_H */ lightspark-0.7.2/src/backends/netutils.cpp000066400000000000000000001151161212105246600206100ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2010-2012 Timon Van Overveldt (timonvo@gmail.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "backends/security.h" #include "scripting/abc.h" #include "swf.h" #include "backends/config.h" #include "backends/netutils.h" #include "backends/rtmputils.h" #include "compat.h" #include #include #include #include #include #ifdef ENABLE_CURL #include #endif using namespace lightspark; /** * \brief Download manager constructor * * Can only be called from within a derived class */ DownloadManager::DownloadManager() { } /** * \brief Download manager destructor */ DownloadManager::~DownloadManager() { } /** * \brief Stops all the currently running downloaders */ void DownloadManager::stopAll() { Mutex::Lock l(mutex); std::list::iterator it=downloaders.begin(); for(;it!=downloaders.end();++it) (*it)->stop(); } /** * \brief Destroyes all the pending downloads, must be called in the destructor of each derived class * * Traverses the list of active downloaders, calling \c stop() and \c destroy() on all of them. * If the downloader is already destroyed, destroy() won't do anything (no double delete). * Waits for the mutex before proceeding. * \see Downloader::stop() * \see Downloader::destroy() */ void DownloadManager::cleanUp() { Mutex::Lock l(mutex); while(!downloaders.empty()) { std::list::iterator it=downloaders.begin(); //cleanUp should only happen after stopAll has been called assert((*it)->hasFinished()); l.release(); destroy(*it); l.acquire(); } } /** * \brief Destroy a Downloader. * * Destroy a given \c Downloader. * \param downloader A pointer to the \c Downloader to be destroyed. * \see DownloadManager::download() */ void StandaloneDownloadManager::destroy(Downloader* downloader) { //If the downloader was still in the active-downloader list, delete it if(removeDownloader(downloader)) { downloader->waitForTermination(); ThreadedDownloader* thd=dynamic_cast(downloader); if(thd) thd->waitFencing(); delete downloader; } } /** * \brief Add a Downloader to the active downloads list * * Waits for the mutex at start and releases the mutex when finished. */ void DownloadManager::addDownloader(Downloader* downloader) { Mutex::Lock l(mutex); downloaders.push_back(downloader); } /** * \brief Remove a Downloader from the active downloads list * * Waits for the mutex at start and releases the mutex when finished. */ bool DownloadManager::removeDownloader(Downloader* downloader) { Mutex::Lock l(mutex); for(std::list::iterator it=downloaders.begin(); it!=downloaders.end(); ++it) { if((*it) == downloader) { downloaders.erase(it); return true; } } return false; } /** * \brief Standalone download manager constructor. * * The standalone download manager produces \c ThreadedDownloader-type \c Downloaders. * It should only be used in the standalone version of LS. */ StandaloneDownloadManager::StandaloneDownloadManager() { type = STANDALONE; } StandaloneDownloadManager::~StandaloneDownloadManager() { cleanUp(); } /** * \brief Create a Downloader for an URL. * * Returns a pointer to a newly created \c Downloader for the given URL. * \param[in] url The URL (as a \c URLInfo) the \c Downloader is requested for * \param[in] cached Whether or not to disk-cache the download (default=false) * \return A pointer to a newly created \c Downloader for the given URL. * \see DownloadManager::destroy() */ Downloader* StandaloneDownloadManager::download(const URLInfo& url, bool cached, ILoadable* owner) { LOG(LOG_INFO, _("NET: STANDALONE: DownloadManager::download '") << url.getParsedURL() << "'" << (cached ? _(" - cached") : "")); ThreadedDownloader* downloader; if(url.getProtocol() == "file") { LOG(LOG_INFO, _("NET: STANDALONE: DownloadManager: local file")); downloader=new LocalDownloader(url.getPath(), cached, owner); } else if(url.getProtocol().substr(0, 4) == "rtmp") { LOG(LOG_INFO, _("NET: STANDALONE: DownloadManager: RTMP stream")); downloader=new RTMPDownloader(url.getParsedURL(), url.getStream(), owner); } else { LOG(LOG_INFO, _("NET: STANDALONE: DownloadManager: remote file")); downloader=new CurlDownloader(url.getParsedURL(), cached, owner); } downloader->enableFencingWaiting(); addDownloader(downloader); getSys()->addJob(downloader); return downloader; } /** * \brief Create a Downloader for an URL and send data to the host * * Returns a pointer to a newly created \c Downloader for the given URL. * \param[in] url The URL (as a \c URLInfo) the \c Downloader is requested for * \param[in] data The binary data to send to the host * \param[in] headers Request headers in the full form, f.e. "Content-Type: ..." * \return A pointer to a newly created \c Downloader for the given URL. * \see DownloadManager::destroy() */ Downloader* StandaloneDownloadManager::downloadWithData(const URLInfo& url, const std::vector& data, const std::list& headers, ILoadable* owner) { LOG(LOG_INFO, _("NET: STANDALONE: DownloadManager::downloadWithData '") << url.getParsedURL()); ThreadedDownloader* downloader; if(url.getProtocol() == "file") { LOG(LOG_INFO, _("NET: STANDALONE: DownloadManager: local file - Ignoring data field")); downloader=new LocalDownloader(url.getPath(), false, owner); } else if(url.getProtocol() == "rtmpe") throw RunTimeException("RTMPE does not support additional data"); else { LOG(LOG_INFO, _("NET: STANDALONE: DownloadManager: remote file")); downloader=new CurlDownloader(url.getParsedURL(), data, headers, owner); } downloader->enableFencingWaiting(); addDownloader(downloader); getSys()->addJob(downloader); return downloader; } /** * \brief Downloader constructor. * * Constructor for the Downloader class. Can only be called from derived classes. * \param[in] _url The URL for the Downloader. * \param[in] _cached Whether or not to cache this download. */ Downloader::Downloader(const tiny_string& _url, bool _cached, ILoadable* o): cacheOpened(0),dataAvailable(0),terminated(0),hasTerminated(false),cacheHasOpened(false), //LOCKING waitingForCache(false),waitingForData(false),waitingForTermination(false), //STATUS forceStop(true),failed(false),finished(false), //FLAGS url(_url),originalURL(url), //PROPERTIES buffer(NULL),stableBuffer(NULL), //BUFFERING owner(o), //PROGRESS cachePos(0),cacheSize(0),keepCache(false),cached(_cached), //CACHING redirected(false),requestStatus(0), //HTTP REDIR, STATUS & HEADERS length(0),receivedLength(0) //DOWNLOADED DATA { setg(NULL,NULL,NULL); } /** * \brief Downloader constructor. * * Constructor for the Downloader class. Can only be called from derived classes. * \param[in] _url The URL for the Downloader. * \param[in] data Additional data to send to the host */ Downloader::Downloader(const tiny_string& _url, const std::vector& _data, const std::list& h, ILoadable* o): cacheOpened(0),dataAvailable(0),terminated(0),hasTerminated(false),cacheHasOpened(false), //LOCKING waitingForCache(false),waitingForData(false),waitingForTermination(false), //STATUS forceStop(true),failed(false),finished(false), //FLAGS url(_url),originalURL(url), //PROPERTIES buffer(NULL),stableBuffer(NULL), //BUFFERING owner(o), //PROGRESS cachePos(0),cacheSize(0),keepCache(false),cached(false), //CACHING redirected(false),requestStatus(0),requestHeaders(h),data(_data),//HTTP REDIR, STATUS & HEADERS length(0),receivedLength(0) //DOWNLOADED DATA { setg(NULL,NULL,NULL); } /** * \brief Downloader destructor. * * Destructor for the Downloader class. Can only be called from derived/friend classes (DownloadManager) * Calls \c waitForTermination() and waits for the mutex before proceeding. * \see Downloader::waitForTermination() */ Downloader::~Downloader() { waitForTermination(); Mutex::Lock l(mutex); if(cached) { if(cache.is_open()) cache.close(); if(!keepCache && cacheFilename != "") unlink(cacheFilename.raw_buf()); } if(buffer != NULL) { free(buffer); } if(stableBuffer != NULL && stableBuffer!=buffer) { free(stableBuffer); } } /** * \brief Called by the streambuf API * * Called by the streambuf API when there is no more data to read. * Waits for the mutex at start and releases the mutex when finished. * \throw RunTimeException Cache file could not be read */ Downloader::int_type Downloader::underflow() { Mutex::Lock l(mutex); //Let's see if the other buffer contains new data syncBuffers(); if(egptr()-gptr()>0) { //There is data already return *(uint8_t*)gptr(); } const unsigned int startOffset=getOffset(); const unsigned int startReceivedLength=receivedLength; assert(startOffset<=startReceivedLength); //If we have read all available data if(startReceivedLength==startOffset) { //The download has failed or has finished if(failed || finished) return EOF; //We haven't reached the end of the download, more bytes should follow else { waitForData_locked(); syncBuffers(); //Check if we haven't failed or finished (and there wasn't any new data) if(failed || (finished && startReceivedLength==receivedLength)) return EOF; } } //We should have an initialized buffer here since there is some data assert_and_throw(buffer != NULL); //Temporary pointers to new streambuf read positions char* begin; char* cur; char* end; //Index in the buffer pointing to the data to be returned uint32_t index; if(cached) { waitForCache(); size_t newCacheSize = receivedLength-(cachePos+cacheSize); if(newCacheSize > cacheMaxSize) newCacheSize = cacheMaxSize; //Move the start of our new window to the end of our last window cachePos = cachePos+cacheSize; cacheSize = newCacheSize; //Seek to the start of our new window cache.seekg(cachePos); //Read into our buffer window cache.read((char*)stableBuffer, cacheSize); if(cache.fail()) { throw RunTimeException(_("Downloader::underflow: reading from cache file failed")); } begin=(char*)stableBuffer; cur=(char*)stableBuffer; end=(char*)stableBuffer+cacheSize; index=0; } else { begin=(char*)stableBuffer; cur=(char*)stableBuffer+startOffset; end=(char*)stableBuffer+receivedLength; index=startOffset; } //If we've failed, don't bother any more if(failed) return EOF; //Set our new iterators in the buffer (begin, cursor, end) setg(begin, cur, end); //Cast to unsigned, otherwise 0xff would become eof return (unsigned char)stableBuffer[index]; } /** * Internal function to synchronize oldBuffer and buffer * * \pre Must be called from a function called by the streambuf API */ void Downloader::syncBuffers() { if(stableBuffer!=buffer) { //The buffer have been changed free(stableBuffer); stableBuffer=buffer; //Remember the relative positions of the input pointers intptr_t curPos = (intptr_t) (gptr()-eback()); intptr_t curLen = (intptr_t) (egptr()-eback()); //Do some pointer arithmetic to point the input pointers to the right places in the new buffer setg((char*)stableBuffer,(char*)(stableBuffer+curPos),(char*)(stableBuffer+curLen)); } } /** * \brief Called by the streambuf API * * Called by the streambuf API to seek to an absolute position * Mutex must be locked on entry. * \throw RunTimeException Cache file could not be read */ Downloader::pos_type Downloader::seekpos(pos_type pos, std::ios_base::openmode mode) { assert_and_throw(mode==std::ios_base::in); assert_and_throw(buffer && stableBuffer); syncBuffers(); // read from stream until we have enough data uint32_t tmplen = receivedLength; while (!hasTerminated && pos > receivedLength) { waitForData_locked(); syncBuffers(); if (tmplen == receivedLength) break; // no new data read tmplen = receivedLength; } if(cached) { waitForCache(); //The requested position is inside our current window if(pos >= cachePos && pos <= cachePos+cacheSize) { //Just move our cursor to the correct position in our window setg((char*)stableBuffer, (char*)stableBuffer+pos-cachePos, (char*)stableBuffer+cacheSize); } //The requested position is outside our current window else if(pos <= receivedLength) { cachePos = pos; cacheSize = receivedLength-pos; if(cacheSize > cacheMaxSize) cacheSize = cacheMaxSize; //Seek to the requested position cache.seekg(cachePos); //Read into our window cache.read((char*)stableBuffer, cacheSize); if(cache.fail()) throw RunTimeException(_("Downloader::seekpos: reading from cache file failed")); //Our window starts at position pos setg((char*) stableBuffer, (char*) stableBuffer, ((char*) stableBuffer)+cacheSize); } //The requested position is bigger then our current amount of available data else if(pos > receivedLength) return -1; } else { //The requested position is valid if(pos <= receivedLength) setg((char*)stableBuffer,(char*)stableBuffer+pos,(char*)stableBuffer+receivedLength); //The requested position is bigger then our current amount of available data else return -1; } return pos; } /** * \brief Called by the streambuf API * * Called by the streambuf API to seek to a relative position * Waits for the mutex at start and releases the mutex when finished. */ Downloader::pos_type Downloader::seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode mode) { assert_and_throw(mode==std::ios_base::in); assert_and_throw(buffer != NULL); Mutex::Lock l(mutex); if (off != 0) { switch (dir) { case std::ios_base::beg: seekpos(off,mode); break; case std::ios_base::cur: { pos_type tmp = getOffset(); seekpos(tmp+off,mode); break; } case std::ios_base::end: l.release(); waitForTermination(); l.acquire(); if (finished) seekpos(length+off,mode); break; default: break; } } return getOffset(); } /** * \brief Get the position of the read cursor in the (virtual) downloaded data * * Get the position of the read cursor in the (virtual) downloaded data. * If downloading to memory this method returns the position of the read cursor in the buffer. * If downloading to a cache file, this method returns the position of the read cursor in the buffer * + the position of the buffer window into the cache file. */ Downloader::pos_type Downloader::getOffset() const { pos_type ret = gptr()-eback(); if(cached) ret+=cachePos; return ret; } /** * \brief Marks the downloader as failed * * Sets the \c failed and finished flag to \c true, sets the final length and * signals \c dataAvailable if it is being waited for. * It also signals \c terminated to mark the end of the download. * A download should finish be either calling \c setFailed() or \c setFinished(), not both. * \post \c failed == \c true & \c finished == \c true * \post \c length == \c receivedLength * \post Signals \c dataAvailable if it is being waited for (\c waitingForData == \c true). * \post \c waitingForTermination == \c false * \post Signals \c terminated */ void Downloader::setFailed() { failed=true; finished = true; //Set the final length length = receivedLength; //If we are waiting for data to become available, signal dataAvailable if(waitingForData) { waitingForData = false; dataAvailable.signal(); } waitingForTermination = false; terminated.signal(); } /** * \brief Marks the downloader as finished * * Marks the downloader as finished, sets the final length and * signals \c dataAvailable if it is being waited for. * It also signals \c terminated to mark the end of the download. * A download should finish be either calling \c setFailed() or \c setFinished(), not both. * \post \c finished == \ctrue * \post \c length == \c receivedLength * \post Signals \c dataAvailable if it is being waited for (\c waitingForData == true). * \post \c waitingForTermination == \c false * \post Signals \c terminated */ void Downloader::setFinished() { finished=true; //Set the final length length = receivedLength; //If we are waiting for data to become available, signal dataAvailable if(waitingForData) { waitingForData = false; dataAvailable.signal(); } waitingForTermination = false; terminated.signal(); } /** * \brief (Re)allocates the buffer * * (Re)allocates the buffer to a given size * Waits for mutex at start and releases mutex when finished. * \post \c buffer is (re)allocated * mutex must be locked on entry */ void Downloader::allocateBuffer(size_t size) { //Create buffer if(buffer == NULL) { buffer = (uint8_t*) calloc(size, sizeof(uint8_t)); stableBuffer = buffer; setg((char*)buffer,(char*)buffer,(char*)buffer); } //If the buffer already exists, reallocate else { assert(!cached); intptr_t curLen = receivedLength; //We have to extend the buffer, so create a new one if(stableBuffer!=buffer) { //We're already filling a different buffer from the one used to read //Extend it! buffer = (uint8_t*)realloc(buffer,size); } else { //Create a different buffer buffer = (uint8_t*) calloc(size, sizeof(uint8_t)); //Copy the stableBuffer into this memcpy(buffer,stableBuffer,curLen); } //Synchronization of the buffers will be done at the first chance } } /** * \brief Creates & opens a temporary cache file * * Creates a temporary cache file in /tmp and calls \c openExistingCache() with that file. * Waits for mutex at start and releases mutex when finished. * \throw RunTimeException Temporary file could not be created * \throw RunTimeException Called when the downloader isn't cached or when the cache is already open * \see Downloader::openExistingCache() * mutex must be hold prior calling */ void Downloader::openCache() { //Only act if the downloader is cached and the cache hasn't been opened yet if(cached && !cache.is_open()) { //Create a temporary file(name) std::string cacheFilenameS = Config::getConfig()->getCacheDirectory() + "/" + Config::getConfig()->getCachePrefix() + "XXXXXX"; char* cacheFilenameC = g_newa(char,cacheFilenameS.length()+1); strncpy(cacheFilenameC, cacheFilenameS.c_str(), cacheFilenameS.length()); cacheFilenameC[cacheFilenameS.length()] = '\0'; //char cacheFilenameC[30] = "/tmp/lightsparkdownloadXXXXXX"; //strcpy(cacheFilenameC, "/tmp/lightsparkdownloadXXXXXX"); int fd = g_mkstemp(cacheFilenameC); if(fd == -1) throw RunTimeException(_("Downloader::openCache: cannot create temporary file")); //We are using fstream to read/write to the cache, so we don't need this FD close(fd); //Let the openExistingCache function handle the rest openExistingCache(tiny_string(cacheFilenameC, true)); } else throw RunTimeException(_("Downloader::openCache: downloader isn't cached or called twice")); } /** * \brief Opens an existing cache file * * Opens an existing cache file, allocates the buffer and signals \c cacheOpened. * Waits for mutex at start and releases mutex when finished. * \post \c cacheFilename is set * \post \c cache file is opened * \post \c buffer is initialized * \post \c cacheOpened is signalled * \throw RunTimeException File could not be opened * \throw RunTimeException Called when the downloader isn't cached or when the cache is already open * \see Downloader::allocateBuffer() * mutex must be hold on entering */ void Downloader::openExistingCache(tiny_string filename) { //Only act if the downloader is cached and the cache hasn't been opened yet if(cached && !cache.is_open()) { //Save the filename cacheFilename = filename; //Open the cache file cache.open(cacheFilename.raw_buf(), std::fstream::binary | std::fstream::in | std::fstream::out); if(!cache.is_open()) throw RunTimeException(_("Downloader::openCache: cannot open temporary cache file")); allocateBuffer(cacheMaxSize); LOG(LOG_INFO, _("NET: Downloading to cache file: ") << cacheFilename); cacheOpened.signal(); } else throw RunTimeException(_("Downloader::openCache: downloader isn't cached or called twice")); } /** * \brief Set the expected length of the download * * Sets the expected length of the download. * Can be called multiple times if the length isn't known up front (reallocating the buffer on the fly). * Waits for mutex at start and releases mutex when finished. * \post \c buffer is (re)allocated * mutex must be hold prior calling */ void Downloader::setLength(uint32_t _length) { //Set the length length=_length; //The first call to this function should open the cache if(cached) { if(!cache.is_open()) openCache(); } else { if(buffer == NULL) LOG(LOG_INFO, _("NET: Downloading to memory")); allocateBuffer(length); } notifyOwnerAboutBytesTotal(); } /** * \brief Appends data to the buffer * * Appends a given amount of received data to the buffer/cache. * This method will grow the expected length of the download on-the-fly as needed. * So when \c length == 0 this call will call \c setLength(added) * Waits for mutex at start and releases mutex when finished. * \post \c buffer/cache contains the added data * \post \c length = \c receivedLength + \c added * \see Downloader::setLength() */ void Downloader::append(uint8_t* buf, uint32_t added) { if(added==0) return; Mutex::Lock l(mutex); //If the added data would overflow the buffer, grow it if((receivedLength+added)>length) { uint32_t newLength; assert(length>=receivedLength); //If reallocating the buffer ask for a minimum amount of space if((receivedLength+added)-length > bufferMinGrowth) newLength = receivedLength + added; else newLength = length + bufferMinGrowth; assert(newLength>=receivedLength+added); setLength(newLength); } if(cached) { //Seek to where we last wrote data cache.seekp(receivedLength); cache.write((char*) buf, added); } else memcpy(buffer+receivedLength, buf, added); receivedLength += added; if(waitingForData) { waitingForData = false; dataAvailable.signal(); } notifyOwnerAboutBytesLoaded(); } /** * \brief Parse a string of multiple headers. * * Parses a string of multiple headers. * Header lines are expected to be seperated by \n * Calls \c parseHeader on every individual header. * \see Downloader::parseHeader() */ void Downloader::parseHeaders(const char* _headers, bool _setLength) { if(_headers == NULL) return; std::string headersStr(_headers); size_t cursor = 0; size_t newLinePos = headersStr.find("\n"); while(newLinePos != std::string::npos) { if(headersStr[cursor] == '\n') cursor++; parseHeader(headersStr.substr(cursor, newLinePos-cursor), _setLength); cursor = newLinePos; newLinePos = headersStr.find("\n", cursor+1); } } /** * \brief Parse a string containing a single header. * * Parse a string containing a single header. * The header line is not expected to contain a newline character. * Waits for mutex at start and releases mutex when finished. */ void Downloader::parseHeader(std::string header, bool _setLength) { Mutex::Lock l(mutex); if(header.substr(0, 9) == "HTTP/1.1 " || header.substr(0, 9) == "HTTP/1.0 ") { std::string status = header.substr(9, 3); requestStatus = atoi(status.c_str()); //HTTP error or server error or proxy error, let's fail //TODO: shouldn't we fetch the data anyway if(getRequestStatus()/100 == 4 || getRequestStatus()/100 == 5 || getRequestStatus()/100 == 6) { setFailed(); } else if(getRequestStatus()/100 == 3) {;} //HTTP redirect else if(getRequestStatus()/100 == 2) {;} //HTTP OK } else { std::string headerName; std::string headerValue; size_t colonPos; colonPos = header.find(":"); if(colonPos != std::string::npos) { headerName = header.substr(0, colonPos); if(header[colonPos+1] == ' ') headerValue = header.substr(colonPos+2, header.length()-colonPos-1); else headerValue = header.substr(colonPos+1, header.length()-colonPos); std::transform(headerName.begin(), headerName.end(), headerName.begin(), ::tolower); //std::transform(headerValue.begin(), headerValue.end(), headerValue.begin(), ::tolower); headers.insert(std::make_pair(tiny_string(headerName), tiny_string(headerValue))); //Set the new real URL when we are being redirected if(getRequestStatus()/100 == 3 && headerName == "location") { LOG(LOG_INFO, _("NET: redirect detected")); setRedirected(URLInfo(url).goToURL(tiny_string(headerValue)).getParsedURL()); } if(headerName == "content-length") { //Now read the length and allocate the byteArray //Only read the length when we're not redirecting if(getRequestStatus()/100 != 3) { setLength(atoi(headerValue.c_str())); return; } } } } } /** * \brief Forces the download to stop * * Sets the \c failed and finished flag to \c true, sets the final length and signals \c dataAvailable * \post \c failed == true & finished == true * \post \c length == receivedLength * \post \c dataAvailable is signalled * \post \c waitingForTermination == \c false * \post Signals \c terminated */ void Downloader::stop() { failed = true; finished = true; length = receivedLength; waitingForData = false; dataAvailable.signal(); waitingForTermination = false; terminated.signal(); } /** * \brief Wait for the cache file to be opened * * If \c !cacheHasOpened: wait for the \c cacheOpened signal and set \c cacheHasOpened to \c true * Waits for the mutex at start and releases the mutex when finished. * \post \c cacheOpened signals has been handled * \post \c cacheHasOpened = true * mutex must be locked on entry */ void Downloader::waitForCache() { if(!cacheHasOpened) { waitingForCache = true; mutex.unlock(); cacheOpened.wait(); mutex.lock(); cacheHasOpened = true; } } /** * \brief Wait for data to become available * * Wait for data to become available. * Waits for the mutex at start and releases the mutex when finished. * \post \c dataAvailable signal has been handled */ void Downloader::waitForData_locked() { waitingForData = true; mutex.unlock(); dataAvailable.wait(); mutex.lock(); } /** * \brief Wait for termination of the downloader * * If \c getSys()->isShuttingDown(), calls \c setFailed() and returns. * Otherwise if \c !hasTerminated: wait for the \c terminated signal and set \c hasTerminated to \c true * Waits for the mutex at start and releases the mutex when finished. * \post \c terminated signal has been handled * \post \c hasTerminated = true */ void Downloader::waitForTermination() { Mutex::Lock l(mutex); if(getSys()->isShuttingDown()) { setFailed(); return; } if(!hasTerminated) { waitingForTermination = true; l.release(); terminated.wait(); l.acquire(); hasTerminated = true; } } void Downloader::notifyOwnerAboutBytesTotal() const { if(owner) owner->setBytesTotal(length); } void Downloader::notifyOwnerAboutBytesLoaded() const { if(owner) owner->setBytesLoaded(receivedLength); } void ThreadedDownloader::enableFencingWaiting() { RELEASE_WRITE(fenceState,true); } /** * \brief The jobFence for ThreadedDownloader. * * This is the very last thing \c ThreadPool does with the \c ThreadedDownloader. * \post The \c fenceState is set to false */ void ThreadedDownloader::jobFence() { RELEASE_WRITE(fenceState,false); } void ThreadedDownloader::waitFencing() { while(fenceState); } /** * \brief Constructor for the ThreadedDownloader class. * * Constructor for the ThreadedDownloader class. Can only be called from derived classes. * \param[in] _url The URL for the Downloader. * \param[in] _cached Whether or not to cache this download. */ ThreadedDownloader::ThreadedDownloader(const tiny_string& url, bool cached, ILoadable* o): Downloader(url, cached, o),fenceState(false) { } /** * \brief Constructor for the ThreadedDownloader class. * * Constructor for the ThreadedDownloader class. Can only be called from derived classes. * \param[in] _url The URL for the Downloader. * \param[in] data Additional data to send to the host */ ThreadedDownloader::ThreadedDownloader(const tiny_string& url, const std::vector& data, const std::list& headers, ILoadable* o): Downloader(url, data, headers, o),fenceState(false) { } /** * \brief Destructor for the ThreadedDownloader class. * * Waits for the \c fenced signal. * \post \c fenced signalled was handled * ThreadedDownloader::~ThreadedDownloader() { sem_wait(&fenced); //-- Fenced signalled }*/ /** * \brief Constructor for the CurlDownloader class. * * \param[in] _url The URL for the Downloader. * \param[in] _cached Whether or not to cache this download. */ CurlDownloader::CurlDownloader(const tiny_string& _url, bool _cached, ILoadable* o): ThreadedDownloader(_url, _cached, o) { } /** * \brief Constructor for the CurlDownloader class. * * \param[in] _url The URL for the Downloader. * \param[in] data Additional data to send to the host */ CurlDownloader::CurlDownloader(const tiny_string& _url, const std::vector& _data, const std::list& _headers, ILoadable* o): ThreadedDownloader(_url, _data, _headers, o) { } /** * \brief Called by \c IThreadJob::stop to abort this thread. * Calls \c Downloader::stop. * \see Downloader::stop() */ void CurlDownloader::threadAbort() { Downloader::stop(); } /** * \brief Called by \c ThreadPool to start executing this thread */ void CurlDownloader::execute() { if(url.empty()) { setFailed(); return; } LOG(LOG_INFO, _("NET: CurlDownloader::execute: reading remote file: ") << url.raw_buf()); #ifdef ENABLE_CURL CURL *curl; CURLcode res; curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, url.raw_buf()); //Needed for thread-safety reasons. //This makes CURL not respect DNS resolving timeouts. //TODO: openssl needs locking callbacks. We should implement these. curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); //ALlow self-signed and incorrect certificates. //TODO: decide if we should allow them. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt(curl, CURLOPT_WRITEDATA, this); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_header); curl_easy_setopt(curl, CURLOPT_HEADERDATA, this); curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback); curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, this); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); //Its probably a good idea to limit redirections, 100 should be more than enough curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 100); curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0"); // Empty string means that CURL will decompress if the // server send a compressed file. (This has been // renamed to CURLOPT_ACCEPT_ENCODING in newer CURL, // we use the old name to support the old versions.) curl_easy_setopt(curl, CURLOPT_ENCODING, ""); if (URLInfo(url).sameHost(getSys()->mainClip->getOrigin()) && !getSys()->getCookies().empty()) curl_easy_setopt(curl, CURLOPT_COOKIE, getSys()->getCookies().c_str()); struct curl_slist *headerList=NULL; bool hasContentType=false; if(!requestHeaders.empty()) { std::list::const_iterator it; for(it=requestHeaders.begin(); it!=requestHeaders.end(); ++it) { headerList=curl_slist_append(headerList, it->raw_buf()); hasContentType |= it->lowercase().startsWith("content-type:"); } } if(!data.empty()) { curl_easy_setopt(curl, CURLOPT_POST, 1); //data is const, it would not be invalidated curl_easy_setopt(curl, CURLOPT_POSTFIELDS, &data.front()); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, data.size()); //For POST it's mandatory to set the Content-Type assert(hasContentType); } if(headerList) curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerList); //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); res = curl_easy_perform(curl); curl_slist_free_all(headerList); curl_easy_cleanup(curl); if(res!=0) { setFailed(); return; } } else { setFailed(); return; } #else //ENABLE_CURL not defined LOG(LOG_ERROR,_("NET: CURL not enabled in this build. Downloader will always fail.")); setFailed(); return; #endif //Notify the downloader no more data should be expected setFinished(); } /** * \brief Progress callback for CURL * * Gets called by CURL to report progress. Can be used to signal CURL to stop downloading. */ int CurlDownloader::progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) { CurlDownloader* th=static_cast(clientp); return th->threadAborting || th->failed; } /** * \brief Data callback for CURL * * Gets called by CURL when data is available to handle. * \see Downloader::append() */ size_t CurlDownloader::write_data(void *buffer, size_t size, size_t nmemb, void *userp) { CurlDownloader* th=static_cast(userp); size_t added=size*nmemb; if(th->getRequestStatus()/100 == 2) th->append((uint8_t*)buffer,added); return added; } /** * \brief Header callback for CURL * * Gets called by CURL when a header needs to be handled. * \see Downloader::parseHeader() */ size_t CurlDownloader::write_header(void *buffer, size_t size, size_t nmemb, void *userp) { CurlDownloader* th=static_cast(userp); std::string header((char*) buffer); //Strip newlines header = header.substr(0, header.find("\r\n")); header = header.substr(0, header.find("\n")); //We haven't set the length of the download uet, so set it from the headers th->parseHeader(header, true); return size*nmemb; } /** * \brief Constructor for the LocalDownloader class * * \param[in] _url The URL for the Downloader. * \param[in] _cached Whether or not to cache this download. */ LocalDownloader::LocalDownloader(const tiny_string& _url, bool _cached, ILoadable* o):ThreadedDownloader(_url, _cached, o) { } /** * \brief Called by \c IThreadJob::stop to abort this thread. * Calls \c Downloader::stop. * \see Downloader::stop() */ void LocalDownloader::threadAbort() { Downloader::stop(); } /** * \brief Called by \c ThreadPool to start executing this thread * Waits for the mutex at start and releases the mutex when finished when the download is cached. * \see Downloader::append() * \see Downloader::openExistingCache() */ void LocalDownloader::execute() { if(url.empty()) { setFailed(); return; } else { LOG(LOG_INFO, _("NET: LocalDownloader::execute: reading local file: ") << url.raw_buf()); //If the caching is selected, we override the normal behaviour and use the local file as the cache file //This prevents unneeded copying of the file's data if(isCached()) { Mutex::Lock l(mutex); //Make sure we don't delete the local file afterwards keepCache = true; openExistingCache(url); cache.seekg(0, std::ios::end); //Report that we've downloaded everything already length = cache.tellg(); receivedLength = length; notifyOwnerAboutBytesLoaded(); notifyOwnerAboutBytesTotal(); } //Otherwise we follow the normal procedure else { std::ifstream file; file.open(url.raw_buf(), std::ios::in|std::ios::binary); if(file.is_open()) { file.seekg(0, std::ios::end); { Mutex::Lock l(mutex); setLength(file.tellg()); } file.seekg(0, std::ios::beg); char buffer[bufSize]; bool readFailed = 0; while(!file.eof()) { if(file.fail() || hasFailed()) { readFailed = 1; break; } file.read(buffer, bufSize); append((uint8_t *) buffer, file.gcount()); } if(readFailed) { LOG(LOG_ERROR, _("NET: LocalDownloader::execute: reading from local file failed: ") << url.raw_buf()); setFailed(); return; } file.close(); } else { LOG(LOG_ERROR, _("NET: LocalDownloader::execute: could not open local file: ") << url.raw_buf()); setFailed(); return; } } } //Notify the downloader no more data should be expected setFinished(); } DownloaderThreadBase::DownloaderThreadBase(_NR request, IDownloaderThreadListener* _listener): listener(_listener), downloader(NULL) { assert(listener); if(!request.isNull()) { url=request->getRequestURL(); requestHeaders=request->getHeaders(); request->getPostData(postData); } } bool DownloaderThreadBase::createDownloader(bool cached, _NR dispatcher, ILoadable* owner, bool checkPolicyFile) { if(checkPolicyFile) { SecurityManager::EVALUATIONRESULT evaluationResult = \ getSys()->securityManager->evaluatePoliciesURL(url, true); if(threadAborting) return false; if(evaluationResult == SecurityManager::NA_CROSSDOMAIN_POLICY) { getVm()->addEvent(dispatcher,_MR(Class::getInstanceS("SecurityError: " "connection to domain not allowed by securityManager"))); return false; } } if(threadAborting) return false; //All the checks passed, create the downloader if(postData.empty()) { //This is a GET request downloader=getSys()->downloadManager->download(url, cached, owner); } else { downloader=getSys()->downloadManager->downloadWithData(url, postData, requestHeaders, owner); } return true; } void DownloaderThreadBase::jobFence() { //Get a copy of the downloader, do hold the lock less time. //It's safe to set this->downloader to NULL, this is the last function that will //be called over this thread job Downloader* d=NULL; { SpinlockLocker l(downloaderLock); d=downloader; downloader=NULL; } if(d) getSys()->downloadManager->destroy(d); listener->threadFinished(this); } void DownloaderThreadBase::threadAbort() { //We have to stop the downloader SpinlockLocker l(downloaderLock); if(downloader != NULL) downloader->stop(); threadAborting=true; } lightspark-0.7.2/src/backends/netutils.h000066400000000000000000000241151212105246600202530ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2010-2012 Timon Van Overveldt (timonvo@gmail.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_NETUTILS_H #define BACKENDS_NETUTILS_H 1 #include "compat.h" #include #include #include #include #include "swftypes.h" #include "thread_pool.h" #include "backends/urlutils.h" #include "smartrefs.h" namespace lightspark { class Downloader; class ILoadable { protected: ~ILoadable(){} public: virtual void setBytesTotal(uint32_t b) = 0; virtual void setBytesLoaded(uint32_t b) = 0; }; class DLL_PUBLIC DownloadManager { private: Mutex mutex; std::list downloaders; protected: DownloadManager(); void addDownloader(Downloader* downloader); bool removeDownloader(Downloader* downloader); void cleanUp(); public: virtual ~DownloadManager(); virtual Downloader* download(const URLInfo& url, bool cached, ILoadable* owner)=0; virtual Downloader* downloadWithData(const URLInfo& url, const std::vector& data, const std::list& headers, ILoadable* owner)=0; virtual void destroy(Downloader* downloader)=0; void stopAll(); enum MANAGERTYPE { NPAPI, STANDALONE }; MANAGERTYPE type; }; class DLL_PUBLIC StandaloneDownloadManager:public DownloadManager { public: StandaloneDownloadManager(); ~StandaloneDownloadManager(); Downloader* download(const URLInfo& url, bool cached, ILoadable* owner); Downloader* downloadWithData(const URLInfo& url, const std::vector& data, const std::list& headers, ILoadable* owner); void destroy(Downloader* downloader); }; class DLL_PUBLIC Downloader: public std::streambuf { private: //Handles streambuf out-of-data events virtual int_type underflow(); //Seeks to absolute position virtual pos_type seekoff(off_type, std::ios_base::seekdir, std::ios_base::openmode); //Seeks to relative position virtual pos_type seekpos(pos_type, std::ios_base::openmode); //Helper to get the current offset pos_type getOffset() const; protected: //Abstract base class, can't be constructed Downloader(const tiny_string& _url, bool _cached, ILoadable* o); Downloader(const tiny_string& _url, const std::vector& data, const std::list& headers, ILoadable* o); //-- LOCKING //Provides internal mutual exclusing Mutex mutex; //Signals the cache opening Semaphore cacheOpened; //Signals new bytes available for reading Semaphore dataAvailable; //Signals termination of the download Semaphore terminated; //True if the download is terminated bool hasTerminated; //True if cache has opened bool cacheHasOpened; //-- STATUS //True if the downloader is waiting for the cache to be opened bool waitingForCache; //True if the downloader is waiting for data bool waitingForData; void waitForData_locked(); //True if the downloader is waiting for termination bool waitingForTermination; //-- FLAGS //This flag forces a stop in internal code bool forceStop; //These flags specify what type of termination happened bool failed; bool finished; //Mark the download as failed void setFailed(); //Mark the download as finished void setFinished(); //-- PROPERTIES tiny_string url; tiny_string originalURL; //-- BUFFERING //This will hold the whole download (non-cached) or a window into the download (cached) uint8_t* buffer; //We can't change the used buffer (for example when resizing) asynchronously. We can only do that on underflows uint8_t* stableBuffer; //Minimum growth of the buffer static const size_t bufferMinGrowth = 4096; //(Re)allocate the buffer void allocateBuffer(size_t size); //Synchronize stableBuffer and buffer void syncBuffers(); //-- PROGRESS MONITORING ILoadable* owner; void notifyOwnerAboutBytesTotal() const; void notifyOwnerAboutBytesLoaded() const; //-- CACHING //Cache filename tiny_string cacheFilename; //Cache fstream std::fstream cache; //Position of the cache buffer into the file uint32_t cachePos; //Size of data in the buffer uint32_t cacheSize; //Maximum size of the cache buffer static const size_t cacheMaxSize = 8192; //True if the cache file doesn't need to be deleted on destruction bool keepCache:1; //True if the file is cached to disk (default = false) bool cached:1; //Creates & opens a temporary cache file void openCache(); //Opens an existing cache file void openExistingCache(tiny_string filename); //-- HTTP REDIRECTION, STATUS & HEADERS bool redirected:1; void setRedirected(const tiny_string& newURL) { redirected = true; url = newURL; } uint16_t requestStatus; std::map headers; void parseHeaders(const char* headers, bool _setLength); void parseHeader(std::string header, bool _setLength); //Data to send to the host const std::list requestHeaders; const std::vector data; //-- DOWNLOADED DATA //File length (can change in certain cases, resulting in reallocation of the buffer (non-cached)) uint32_t length; //Amount of data already received uint32_t receivedLength; //Append data to the internal buffer void append(uint8_t* buffer, uint32_t length); //Set the length of the downloaded file, can be called multiple times to accomodate a growing file void setLength(uint32_t _length); public: //This class can only get destroyed by DownloadManager derivate classes virtual ~Downloader(); //Stop the download void stop(); //Wait for cache to be opened void waitForCache(); //Wait for data to become available void waitForData() { Mutex::Lock l(mutex); waitForData_locked(); } //Wait for the download to terminate void waitForTermination(); //True if the download has failed bool hasFailed() { return failed; } //True if the download has finished //Can be used in conjunction with failed to find out if it finished successfully bool hasFinished() { return finished; } //True if the download is cached bool isCached() { return cached; } const tiny_string& getURL() { return url; } //Gets the total length of the downloaded file (may change) uint32_t getLength() { return length; } //Gets the length of downloaded data uint32_t getReceivedLength() { return receivedLength; } size_t getHeaderCount() { return headers.size(); } tiny_string getHeader(const char* header) { return getHeader(tiny_string(header)); } tiny_string getHeader(tiny_string header) { return headers[header]; } std::map::iterator getHeadersBegin() { return headers.begin(); } std::map::iterator getHeadersEnd() { return headers.end(); } bool isRedirected() { return redirected; } const tiny_string& getOriginalURL() { return originalURL; } uint16_t getRequestStatus() { return requestStatus; } }; class ThreadedDownloader : public Downloader, public IThreadJob { private: ACQUIRE_RELEASE_FLAG(fenceState); public: void enableFencingWaiting(); void jobFence(); void waitFencing(); protected: //Abstract base class, can not be constructed ThreadedDownloader(const tiny_string& url, bool cached, ILoadable* o); ThreadedDownloader(const tiny_string& url, const std::vector& data, const std::list& headers, ILoadable* o); // //This class can only get destroyed by DownloadManager // virtual ~ThreadedDownloader(); }; //CurlDownloader can be used as a thread job, standalone or as a streambuf class CurlDownloader: public ThreadedDownloader { private: static size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp); static size_t write_header(void *buffer, size_t size, size_t nmemb, void *userp); static int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow); void execute(); void threadAbort(); public: CurlDownloader(const tiny_string& _url, bool _cached, ILoadable* o); CurlDownloader(const tiny_string& _url, const std::vector& data, const std::list& headers, ILoadable* o); }; //LocalDownloader can be used as a thread job, standalone or as a streambuf class LocalDownloader: public ThreadedDownloader { private: static size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp); static size_t write_header(void *buffer, size_t size, size_t nmemb, void *userp); static int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow); void execute(); void threadAbort(); //Size of the reading buffer static const size_t bufSize = 8192; public: LocalDownloader(const tiny_string& _url, bool _cached, ILoadable* o); }; class IDownloaderThreadListener { protected: virtual ~IDownloaderThreadListener() {} public: virtual void threadFinished(IThreadJob*)=0; }; class URLRequest; class EventDispatcher; // Common functionality for the resource loading classes (Loader, // URLStream, etc) class DownloaderThreadBase : public IThreadJob { private: IDownloaderThreadListener* listener; protected: URLInfo url; std::vector postData; std::list requestHeaders; Spinlock downloaderLock; Downloader* downloader; bool createDownloader(bool cached, _NR dispatcher=NullRef, ILoadable* owner=NULL, bool checkPolicyFile=true); void jobFence(); public: DownloaderThreadBase(_NR request, IDownloaderThreadListener* listener); void execute()=0; void threadAbort(); }; }; #endif /* BACKENDS_NETUTILS_H */ lightspark-0.7.2/src/backends/pluginmanager.cpp000066400000000000000000000231131212105246600215650ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #define BOOST_FILESYSTEM_NO_DEPRECATED #include "backends/pluginmanager.h" #include #include #include #include #include "logger.h" #include "exceptions.h" #include using namespace lightspark; using namespace std; using namespace boost::filesystem; PluginManager::PluginManager() { assert( g_module_supported() ); findPlugins(); } /*************************** Find liblightsparkBACKENDplugin libraries ****************************/ void PluginManager::findPlugins() { //Search for all files under the plugins directory //Verify if they are audio plugins //If true, add to list of audio plugins #ifdef _WIN32 const path plugins_folder = getExectuablePath(); #else const path plugins_folder = string(PRIVATELIBDIR) + "/plugins/"; #endif const string pattern ( "liblightspark+[A-Za-z]+plugin.*" ); //Stuff used by/for pcre const char* patternError; int patternErrorOffset; pcre* file_pattern = pcre_compile ( pattern.c_str(), 0, &patternError, &patternErrorOffset, NULL ); if(patternError) throw RunTimeException("PluginManager::findPlugins(): can't compile file_pattern"); //We don't expect any captured substrings, so 3 ints should be enough #if defined DEBUG LOG(LOG_INFO, "Looking for plugins under " << plugins_folder << " for pattern " << pattern); #endif if ( !is_directory ( plugins_folder ) ) { LOG ( LOG_ERROR, _ ( ( ( string ) ( "The plugins folder doesn't exists under " + plugins_folder.string() ) ).c_str() ) ); } else { for ( directory_iterator itr ( plugins_folder ), end_itr; itr != end_itr; ++itr ) { if ( is_regular_file ( *itr ) ) //Is it a real file? This will remove symlink { #if BOOST_VERSION >= 104600 string leaf_name = itr->path().filename().string(); #else string leaf_name = itr->path().filename(); #endif int patternOvector[3]; int rc=pcre_exec(file_pattern, NULL, leaf_name.c_str(), leaf_name.length(), 0, 0, patternOvector, 3); if ( rc > 0 ) // Does it answer to the desired pattern? { #if BOOST_VERSION >= 104600 path fullpath = plugins_folder.string(); #else path fullpath = plugins_folder.directory_string(); #endif fullpath /= leaf_name; //Try to load the file and see if it's an audio plugin if ( GModule* h_plugin = g_module_open( fullpath.string().c_str(), G_MODULE_BIND_LAZY) ) { PLUGIN_FACTORY p_factory_function; PLUGIN_CLEANUP p_cleanup_function; if ( g_module_symbol(h_plugin, "create", (void**)&p_factory_function) && g_module_symbol(h_plugin, "release", (void**)&p_cleanup_function) ) { //Does it contain the LS IPlugin? IPlugin *p_plugin = p_factory_function (); //Instanciate the plugin LOG ( LOG_INFO, _ ( "A plugin was found. Adding it to the list." ) ); addPluginToList ( p_plugin, fullpath.string() ); //Add the plugin info to the audio plugins list p_cleanup_function ( p_plugin ); g_module_close ( h_plugin ); } else //If doesn't implement our IPlugin interface entry points, close it { g_module_close( h_plugin ); } } } } } } pcre_free(file_pattern); } //return a list of backends of the appropriated PLUGIN_TYPES vector PluginManager::get_backendsList ( PLUGIN_TYPES typeSearched ) { vector retrievedList; uint32_t count = 0; for ( uint32_t index = 0; index < pluginsList.size(); index++ ) { if ( pluginsList[index]->pluginType == typeSearched ) { if ( count == retrievedList.size() ) { retrievedList.push_back ( new string ); } retrievedList[count] = &pluginsList[index]->backendName; count++; } } return retrievedList; } //get the desired plugin associated to the backend IPlugin *PluginManager::get_plugin ( string desiredBackend ) { LOG ( LOG_INFO, _ ( ( ( string ) ( "get_plugin: " + desiredBackend ) ).c_str() ) ); int32_t index = findPluginInList ( "", desiredBackend, "", NULL, NULL ); if ( index >= 0 ) { loadPlugin ( index ); return pluginsList[index]->oLoadedPlugin; } else { return NULL; } } /******************* When a plugin is not needed anymore somewhere, the client that had asked it tells the manager it doesn't need it anymore. The PluginManager releases it (delete and unload). *******************/ void PluginManager::release_plugin ( IPlugin* o_plugin ) { for ( uint32_t index = 0; index < pluginsList.size(); index++ ) { if ( pluginsList[index]->oLoadedPlugin == o_plugin ) { unloadPlugin ( index ); } } } /********************* Adds the information about a plugin in the plugins list *********************/ void PluginManager::addPluginToList ( IPlugin *o_plugin, string pathToPlugin ) { //Verify if the plugin is already in the list int32_t index = findPluginInList ( "", "", pathToPlugin, NULL, NULL ); if ( index >= 0 ) //If true, plugin is already in the list, we have nothing to do { return; } else { index = ( int32_t ) ( pluginsList.size() ); //we want to add the plugin to the end of the list if ( pluginsList.size() == ( uint32_t ) ( index ) ) { pluginsList.push_back ( new PluginModule() ); } pluginsList[index]->pluginName = o_plugin->get_pluginName(); pluginsList[index]->backendName = o_plugin->get_backendName(); pluginsList[index]->pluginPath = pathToPlugin; pluginsList[index]->enabled = false; LOG ( LOG_INFO, _ ( ( ( string ) ( "The plugin " + pluginsList[index]->pluginName + " was added with backend: " + pluginsList[index]->backendName ) ).c_str() ) ); } } /********************** Removes the information about a plugin from the plugins list. It's used only by the manager when there are modifications in the plugins folder. **********************/ void PluginManager::removePluginFromList ( string pluginPath ) { int32_t index = findPluginInList ( "", "", pluginPath, NULL, NULL ); if ( index >= 0 ) { unloadPlugin ( index ); pluginsList.erase ( pluginsList.begin() + index ); } } /************************** Looks in the plugins list for the desired entry. If found, returns the location in the list (index). Else, returns -1 (which can't be an entry in the list) **************************/ int32_t PluginManager::findPluginInList ( string desiredname, string desiredbackend, string desiredpath, GModule* hdesiredloadPlugin, IPlugin* o_desiredPlugin ) { for ( uint32_t index = 0; index < pluginsList.size(); index++ ) { if ( ( desiredname != "" ) && ( pluginsList[index]->pluginName == desiredname ) ) { return index; } if ( ( desiredbackend != "" ) && ( pluginsList[index]->backendName == desiredbackend ) ) { return index; } if ( ( desiredpath != "" ) && ( pluginsList[index]->pluginPath == desiredpath ) ) { return index; } if ( ( hdesiredloadPlugin != NULL ) && ( pluginsList[index]->hLoadedPlugin == hdesiredloadPlugin ) ) { return index; } if ( ( o_desiredPlugin != NULL ) && ( pluginsList[index]->oLoadedPlugin == o_desiredPlugin ) ) { return index; } } return -1; } //Takes care to load and instanciate anything related to the plugin void PluginManager::loadPlugin ( uint32_t desiredindex ) { if( (pluginsList[desiredindex]->hLoadedPlugin = g_module_open( pluginsList[desiredindex]->pluginPath.c_str(), G_MODULE_BIND_LAZY))) { PLUGIN_FACTORY p_factory_function; if ( g_module_symbol(pluginsList[desiredindex]->hLoadedPlugin, "create", (void**)&p_factory_function) ) { //Does it contain the LS IPlugin? pluginsList[desiredindex]->oLoadedPlugin = ( *p_factory_function ) (); //Instanciate the plugin pluginsList[desiredindex]->enabled = true; } } } //Takes care of unloading and releasing anything related to the plugin void PluginManager::unloadPlugin ( uint32_t desiredIndex ) { if ( pluginsList[desiredIndex]->oLoadedPlugin || pluginsList[desiredIndex]->hLoadedPlugin ) //If there is already a backend loaded, unload it { if ( pluginsList[desiredIndex]->oLoadedPlugin != NULL ) { PLUGIN_CLEANUP p_cleanup_function; if ( g_module_symbol(pluginsList[desiredIndex]->hLoadedPlugin, "release", (void**)&p_cleanup_function) ) { p_cleanup_function ( pluginsList[desiredIndex]->oLoadedPlugin ); } else { delete pluginsList[desiredIndex]->oLoadedPlugin; } pluginsList[desiredIndex]->oLoadedPlugin = NULL; g_module_close ( pluginsList[desiredIndex]->hLoadedPlugin ); } pluginsList[desiredIndex]->enabled = false; //Unselecting any entry in the plugins list } } PluginManager::~PluginManager() { for(auto i = pluginsList.begin(); i != pluginsList.end(); ++i) delete *i; } PluginModule::PluginModule() : pluginName ( "undefined" ), pluginType ( UNDEFINED ), backendName ( "undefined" ), pluginPath ( "" ), enabled ( false ), hLoadedPlugin ( NULL ), oLoadedPlugin ( NULL ) { } PluginModule::~PluginModule() { } lightspark-0.7.2/src/backends/pluginmanager.h000066400000000000000000000052761212105246600212440ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_PLUGINMANAGER_H #define BACKENDS_PLUGINMANAGER_H 1 #include "compat.h" #include #include #include "backends/interfaces/IPlugin.h" //convenience typedef for the pointers to the 2 functions we expect to find in the plugin libraries typedef IPlugin * ( *PLUGIN_FACTORY ) (); typedef void ( *PLUGIN_CLEANUP ) ( IPlugin * ); typedef struct _GModule GModule; namespace lightspark { class PluginModule; class PluginManager { private: std::vector pluginsList; void findPlugins(); void addPluginToList ( IPlugin *o_plugin, std::string pathToPlugin ); void removePluginFromList ( std::string plugin_path ); int32_t findPluginInList ( std::string desiredname = "", std::string desiredbackend = "", std::string desiredpath = "", GModule* hdesiredLoadPlugin = NULL, IPlugin *o_desiredPlugin = NULL ); void loadPlugin ( uint32_t desiredindex ); void unloadPlugin ( uint32_t desiredIndex ); public: PluginManager(); std::vector get_backendsList ( PLUGIN_TYPES typeSearched ); IPlugin *get_plugin ( std::string desiredBackend ); void release_plugin ( IPlugin *o_plugin ); ~PluginManager(); }; class PluginModule { friend class PluginManager; protected: std::string pluginName; //plugin name PLUGIN_TYPES pluginType; //plugin type to be able to filter them std::string backendName; //backend (can be something like pulseaudio, opengl, ffmpeg) std::string pluginPath; //full path to the plugin file bool enabled; //should it be enabled (if the audio backend is present)? GModule* hLoadedPlugin; //when loaded, handle to the plugin so we can unload it later IPlugin *oLoadedPlugin; //when instanciated, object to the class public: PluginModule(); ~PluginModule(); }; } #endif /* BACKENDS_PLUGINMANAGER_H */ lightspark-0.7.2/src/backends/rendering.cpp000066400000000000000000000744331212105246600207240ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "scripting/abc.h" #include "parsing/textfile.h" #include "backends/rendering.h" #include "compat.h" #include #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN # include #endif //None is #defined by X11/X.h, but because it conflicts with libxml++ //headers Lightspark undefines it elsewhere except in this file. #ifndef None #define None 0L #endif //The interpretation of texture data change with the endianness #if __BYTE_ORDER == __BIG_ENDIAN #define GL_UNSIGNED_INT_8_8_8_8_HOST GL_UNSIGNED_INT_8_8_8_8_REV #else #define GL_UNSIGNED_INT_8_8_8_8_HOST GL_UNSIGNED_BYTE #endif using namespace lightspark; using namespace std; /* calculate FPS every second */ const Glib::TimeVal RenderThread::FPS_time(/*seconds*/1,/*microseconds*/0); static GStaticPrivate renderThread = G_STATIC_PRIVATE_INIT; /* TLS */ RenderThread* lightspark::getRenderThread() { RenderThread* ret = (RenderThread*)g_static_private_get(&renderThread); /* If this is NULL, then you are not calling from the render thread, * which is disallowed! (OpenGL is not threadsafe) */ assert(ret); return ret; } void RenderThread::wait() { if(status==STARTED) { //Signal potentially blocking semaphore event.signal(); t->join(); } } RenderThread::RenderThread(SystemState* s): m_sys(s),status(CREATED),currentPixelBuffer(0),currentPixelBufferOffset(0), pixelBufferWidth(0),pixelBufferHeight(0),prevUploadJob(NULL), renderNeeded(false),uploadNeeded(false),resizeNeeded(false),newTextureNeeded(false),event(0),newWidth(0),newHeight(0),scaleX(1),scaleY(1), offsetX(0),offsetY(0),tempBufferAcquired(false),frameCount(0),secsCount(0),initialized(0), hasNPOTTextures(false),cairoTextureContext(NULL) { LOG(LOG_INFO,_("RenderThread this=") << this); #ifdef _WIN32 fontPath = "TimesNewRoman.ttf"; #else fontPath = "Serif"; #endif time_s.assign_current_time(); } /* this is called in the context of the gtk main thread */ void RenderThread::start(EngineData* data) { status=STARTED; engineData=data; /* this function must be called in the gtk main thread */ engineData->setSizeChangeHandler(sigc::mem_fun(this,&RenderThread::requestResize)); #ifdef HAVE_NEW_GLIBMM_THREAD_API t = Thread::create(sigc::mem_fun(this,&RenderThread::worker)); #else t = Thread::create(sigc::mem_fun(this,&RenderThread::worker),true); #endif } void RenderThread::stop() { initialized.signal(); } RenderThread::~RenderThread() { wait(); LOG(LOG_INFO,_("~RenderThread this=") << this); } void RenderThread::handleNewTexture() { //Find if any largeTexture is not initialized Locker l(mutexLargeTexture); for(uint32_t i=0;isizeNeeded(w,h); const TextureChunk& tex=u->getTexture(); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixelBuffers[currentPixelBuffer]); #ifndef ENABLE_GLES2 //Copy content of the pbo to the texture, currentPixelBufferOffset is the offset in the pbo loadChunkBGRA(tex, w, h, (uint8_t*)currentPixelBufferOffset); #else loadChunkBGRA(tex, w, h, pixelBuf); #endif glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); u->uploadFence(); prevUploadJob=NULL; } void RenderThread::handleUpload() { ITextureUploadable* u=getUploadJob(); assert(u); uint32_t w,h; u->sizeNeeded(w,h); if(w>pixelBufferWidth || h>pixelBufferHeight) resizePixelBuffers(w,h); //Increment and wrap current buffer index #ifndef ENABLE_GLES2 unsigned int nextBuffer = (currentPixelBuffer + 1)%2; glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixelBuffers[nextBuffer]); uint8_t* buf=(uint8_t*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER,GL_WRITE_ONLY); if(!buf) { handleGLErrors(); return; } uint8_t* alignedBuf=(uint8_t*)(uintptr_t((buf+15))&(~0xfL)); u->upload(alignedBuf, w, h); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); currentPixelBufferOffset=alignedBuf-buf; currentPixelBuffer=nextBuffer; #else //TODO See if a more elegant way of handling the non-PBO case can be found. //for now, each frame is uploaded one at a time synchronously to the server if(!pixelBuf) if(posix_memalign((void **)&pixelBuf, 16, w*h*4)) { LOG(LOG_ERROR, "posix_memalign could not allocate memory"); return; } u->upload(pixelBuf, w, h); #endif //Get the texture to be sure it's allocated when the upload comes u->getTexture(); prevUploadJob=u; } /* * Create an OpenGL context, load shaders and setup FBO */ void RenderThread::init() { /* This will call initialized.signal() when lighter goes out of scope */ SemaphoreLighter lighter(initialized); windowWidth=engineData->width; windowHeight=engineData->height; #if defined(_WIN32) PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, //Flags PFD_TYPE_RGBA, //The kind of framebuffer. RGBA or palette. 32, //Colordepth of the framebuffer. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, //Number of bits for the depthbuffer 0, //Number of bits for the stencilbuffer 0, //Number of Aux buffers in the framebuffer. PFD_MAIN_PLANE, 0, 0, 0, 0 }; if(!(mDC = GetDC((HWND)engineData->window))) throw RunTimeException("GetDC failed"); int PixelFormat; if (!(PixelFormat=ChoosePixelFormat(mDC,&pfd))) throw RunTimeException("ChoosePixelFormat failed"); if(!SetPixelFormat(mDC,PixelFormat,&pfd)) throw RunTimeException("SetPixelFormat failed"); if (!(mRC=wglCreateContext(mDC))) throw RunTimeException("wglCreateContext failed"); if(!wglMakeCurrent(mDC,mRC)) throw RunTimeException("wglMakeCurrent failed"); #elif !defined(ENABLE_GLES2) mDisplay = XOpenDisplay(NULL); int a,b; Bool glx_present=glXQueryVersion(mDisplay, &a, &b); if(!glx_present) throw RunTimeException("glX not present"); int attrib[10]={GLX_DOUBLEBUFFER, True, None}; GLXFBConfig* fb=glXChooseFBConfig(mDisplay, 0, attrib, &a); if(!fb) { attrib[6]=None; LOG(LOG_ERROR,_("Falling back to no double buffering")); fb=glXChooseFBConfig(mDisplay, 0, attrib, &a); } if(!fb) throw RunTimeException(_("Could not find any GLX configuration")); int i; for(i=0;ivisual) break; } if(i==a) { //No suitable id found throw RunTimeException(_("No suitable graphics configuration available")); } mFBConfig=fb[i]; LOG(LOG_INFO, "Chosen config " << hex << fb[i] << dec); XFree(fb); mContext = glXCreateNewContext(mDisplay, mFBConfig,GLX_RGBA_TYPE ,NULL,1); glXMakeCurrent(mDisplay, engineData->window, mContext); if(!glXIsDirect(mDisplay, mContext)) LOG(LOG_INFO, "Indirect!!"); #else //egl mDisplay = XOpenDisplay(NULL); int a; eglBindAPI(EGL_OPENGL_ES_API); mEGLDisplay = eglGetDisplay(mDisplay); if (mEGLDisplay == EGL_NO_DISPLAY) throw RunTimeException(_("EGL not present")); EGLint major, minor; if (eglInitialize(mEGLDisplay, &major, &minor) == EGL_FALSE) throw RunTimeException(_("EGL initialization failed")); LOG(LOG_INFO, _("EGL version: ") << eglQueryString(mEGLDisplay, EGL_VERSION)); EGLint config_attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; if (!eglChooseConfig(mEGLDisplay, config_attribs, 0, 0, &a)) throw RunTimeException(_("Could not get number of EGL configurations")); else LOG(LOG_INFO, "Number of EGL configurations: " << a); EGLConfig *conf = new EGLConfig[a]; if (!eglChooseConfig(mEGLDisplay, config_attribs, conf, a, &a)) throw RunTimeException(_("Could not find any EGL configuration")); int i; for(i=0;ivisual) break; } if(i==a) { //No suitable id found throw RunTimeException(_("No suitable graphics configuration available")); } mEGLConfig=conf[i]; LOG(LOG_INFO, "Chosen config " << hex << conf[i] << dec); mEGLContext = eglCreateContext(mEGLDisplay, mEGLConfig, EGL_NO_CONTEXT, context_attribs); if (mEGLContext == EGL_NO_CONTEXT) throw RunTimeException(_("Could not create EGL context")); mEGLSurface = eglCreateWindowSurface(mEGLDisplay, mEGLConfig, engineData->window, NULL); if (mEGLSurface == EGL_NO_SURFACE) throw RunTimeException(_("Could not create EGL surface")); eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext); #endif commonGLInit(windowWidth, windowHeight); commonGLResize(); } void RenderThread::worker() { setTLSSys(m_sys); /* set TLS variable for getRenderThread() */ g_static_private_set(&renderThread, this, NULL); ThreadProfile* profile=m_sys->allocateProfiler(RGB(200,0,0)); profile->setTag("Render"); try { init(); ThreadProfile* profile=m_sys->allocateProfiler(RGB(200,0,0)); profile->setTag("Render"); glEnable(GL_TEXTURE_2D); Chronometer chronometer; while(1) { event.wait(); if(m_sys->isShuttingDown()) break; chronometer.checkpoint(); if(resizeNeeded) { //Order of the operations here matters for requestResize windowWidth=newWidth; windowHeight=newHeight; resizeNeeded=false; newWidth=0; newHeight=0; //End of order critical part LOG(LOG_INFO,_("Window resized to ") << windowWidth << 'x' << windowHeight); commonGLResize(); m_sys->resizeCompleted(); profile->accountTime(chronometer.checkpoint()); continue; } if(newTextureNeeded) handleNewTexture(); if(prevUploadJob) finalizeUpload(); if(uploadNeeded) { handleUpload(); profile->accountTime(chronometer.checkpoint()); continue; } if(m_sys->isOnError()) { renderErrorPage(this, m_sys->standalone); } #if defined(_WIN32) SwapBuffers(mDC); #elif !defined(ENABLE_GLES2) glXSwapBuffers(mDisplay, engineData->window); #else eglSwapBuffers(mEGLDisplay, mEGLSurface); #endif if(!m_sys->isOnError()) { coreRendering(); //Call glFlush to offload work on the GPU glFlush(); } profile->accountTime(chronometer.checkpoint()); renderNeeded=false; } deinit(); } catch(LightsparkException& e) { LOG(LOG_ERROR,_("Exception in RenderThread, stopping rendering: ") << e.what()); //TODO: add a comandline switch to disable rendering. Then add that commandline switch //to the test runner script and uncomment the next line //m_sys->setError(e.cause); } /* cleanup */ //Keep addUploadJob from enqueueing status=TERMINATED; //Fence existing jobs Locker l(mutexUploadJobs); if(prevUploadJob) prevUploadJob->uploadFence(); for(auto i=uploadJobs.begin(); i != uploadJobs.end(); ++i) (*i)->uploadFence(); } void RenderThread::deinit() { glDisable(GL_TEXTURE_2D); commonGLDeinit(); #if defined(_WIN32) wglMakeCurrent(NULL,NULL); wglDeleteContext(mRC); /* Do not ReleaseDC(e->window,hDC); as our window does not have CS_OWNDC */ #elif !defined(ENABLE_GLES2) glXMakeCurrent(mDisplay, None, NULL); glXDestroyContext(mDisplay, mContext); XCloseDisplay(mDisplay); #else eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(mEGLDisplay, mEGLContext); XCloseDisplay(mDisplay); #endif engineData->removeSizeChangeHandler(); return; } bool RenderThread::loadShaderPrograms() { //Create render program assert(glCreateShader); GLuint f = glCreateShader(GL_FRAGMENT_SHADER); const char *fs = NULL; fs = dataFileRead("lightspark.frag"); if(fs==NULL) { LOG(LOG_ERROR,_("Shader lightspark.frag not found")); throw RunTimeException("Fragment shader code not found"); } assert(glShaderSource); glShaderSource(f, 1, &fs,NULL); free((void*)fs); GLuint g = glCreateShader(GL_VERTEX_SHADER); bool ret=true; char str[1024]; int a; GLint stat; assert(glCompileShader); glCompileShader(f); assert(glGetShaderInfoLog); glGetShaderInfoLog(f,1024,&a,str); LOG(LOG_INFO,_("Fragment shader compilation ") << str); glGetShaderiv(f, GL_COMPILE_STATUS, &stat); if (!stat) { throw RunTimeException("Could not compile fragment shader"); } fs = dataFileRead("lightspark.vert"); if(fs==NULL) { LOG(LOG_ERROR,_("Shader lightspark.vert not found")); throw RunTimeException("Vertex shader code not found"); } glShaderSource(g, 1, &fs,NULL); free((void*)fs); glGetShaderInfoLog(g,1024,&a,str); LOG(LOG_INFO,_("Vertex shader compilation ") << str); glCompileShader(g); glGetShaderiv(g, GL_COMPILE_STATUS, &stat); if (!stat) { throw RunTimeException("Could not compile vertex shader"); } assert(glCreateProgram); gpu_program = glCreateProgram(); glBindAttribLocation(gpu_program, VERTEX_ATTRIB, "ls_Vertex"); glBindAttribLocation(gpu_program, COLOR_ATTRIB, "ls_Color"); glBindAttribLocation(gpu_program, TEXCOORD_ATTRIB, "ls_TexCoord"); assert(glAttachShader); glAttachShader(gpu_program,f); glAttachShader(gpu_program,g); assert(glLinkProgram); glLinkProgram(gpu_program); assert(glGetProgramiv); glGetProgramiv(gpu_program,GL_LINK_STATUS,&a); if(a==GL_FALSE) { ret=false; return ret; } assert(ret); return true; } void RenderThread::commonGLDeinit() { glBindFramebuffer(GL_FRAMEBUFFER,0); for(uint32_t i=0;i0); largeTextureSize=min(maxTexSize,1024); //Create the PBOs glGenBuffers(2,pixelBuffers); //Set uniforms glUseProgram(gpu_program); int tex=glGetUniformLocation(gpu_program,"g_tex1"); if(tex!=-1) glUniform1i(tex,0); tex=glGetUniformLocation(gpu_program,"g_tex2"); if(tex!=-1) glUniform1i(tex,1); //The uniform that enables YUV->RGB transform on the texels (needed for video) yuvUniform =glGetUniformLocation(gpu_program,"yuv"); //The uniform that tells the alpha value multiplied to the alpha of every pixel alphaUniform =glGetUniformLocation(gpu_program,"alpha"); //The uniform that tells to draw directly using the selected color directUniform =glGetUniformLocation(gpu_program,"direct"); //The uniform that contains the coordinate matrix projectionMatrixUniform =glGetUniformLocation(gpu_program,"ls_ProjectionMatrix"); modelviewMatrixUniform =glGetUniformLocation(gpu_program,"ls_ModelViewMatrix"); fragmentTexScaleUniform=glGetUniformLocation(gpu_program,"texScale"); //Texturing must be enabled otherwise no tex coord will be sent to the shaders glEnable(GL_TEXTURE_2D); glGenTextures(1, &cairoTextureID); if(handleGLErrors()) { LOG(LOG_ERROR,_("GL errors during initialization")); } } void RenderThread::commonGLResize() { m_sys->stageCoordinateMapping(windowWidth, windowHeight, offsetX, offsetY, scaleX, scaleY); glViewport(0,0,windowWidth,windowHeight); lsglLoadIdentity(); lsglOrtho(0,windowWidth,0,windowHeight,-100,0); //scaleY is negated to adapt the flash and gl coordinates system //An additional translation is added for the same reason lsglTranslatef(offsetX,windowHeight-offsetY,0); lsglScalef(scaleX,-scaleY,1); setMatrixUniform(LSGL_PROJECTION); } void RenderThread::requestResize(uint32_t w, uint32_t h, bool force) { //We can skip the resize if the current size is correct //and there is no pending resize or if there is already a //pending resize with the correct size //This test is correct only if the order of operation where //the resize is handled does not change! if(!force && ((windowWidth==w && windowHeight==h && resizeNeeded==false) || (newWidth==w && newHeight==h))) { return; } newWidth=w; newHeight=h; resizeNeeded=true; event.signal(); } void RenderThread::resizePixelBuffers(uint32_t w, uint32_t h) { //Add enough room to realign to 16 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixelBuffers[0]); glBufferData(GL_PIXEL_UNPACK_BUFFER, w*h*4+16, 0, GL_STREAM_DRAW); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixelBuffers[1]); glBufferData(GL_PIXEL_UNPACK_BUFFER, w*h*4+16, 0, GL_STREAM_DRAW); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); pixelBufferWidth=w; pixelBufferHeight=h; #ifdef ENABLE_GLES2 if (pixelBuf) { free(pixelBuf); pixelBuf = 0; } #endif } cairo_t* RenderThread::getCairoContext(int w, int h) { if (!cairoTextureContext) { cairoTextureData = new uint8_t[w*h*4]; cairoTextureSurface = cairo_image_surface_create_for_data(cairoTextureData, CAIRO_FORMAT_ARGB32, w, h, w*4); cairoTextureContext = cairo_create(cairoTextureSurface); cairo_select_font_face (cairoTextureContext, fontPath.c_str(), CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cairoTextureContext, 11); } return cairoTextureContext; } //Render strings using Cairo's 'toy' text API void RenderThread::renderText(cairo_t *cr, const char *text, int x, int y) { cairo_move_to(cr, x, y); cairo_save(cr); cairo_scale(cr, 1.0, -1.0); cairo_show_text(cr, text); cairo_restore(cr); } //Send the texture drawn by Cairo to the GPU void RenderThread::mapCairoTexture(int w, int h) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, cairoTextureID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, cairoTextureData); GLfloat vertex_coords[] = {0,0, GLfloat(w),0, 0,GLfloat(h), GLfloat(w),GLfloat(h)}; GLfloat texture_coords[] = {0,0, 1,0, 0,1, 1,1}; glVertexAttribPointer(VERTEX_ATTRIB, 2, GL_FLOAT, GL_FALSE, 0, vertex_coords); glVertexAttribPointer(TEXCOORD_ATTRIB, 2, GL_FLOAT, GL_FALSE, 0, texture_coords); glEnableVertexAttribArray(VERTEX_ATTRIB); glEnableVertexAttribArray(TEXCOORD_ATTRIB); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableVertexAttribArray(VERTEX_ATTRIB); glDisableVertexAttribArray(TEXCOORD_ATTRIB); } void RenderThread::plotProfilingData() { lsglLoadIdentity(); lsglScalef(1.0f/scaleX,-1.0f/scaleY,1); lsglTranslatef(-offsetX,(windowHeight-offsetY)*(-1.0f),0); setMatrixUniform(LSGL_MODELVIEW); cairo_t *cr = getCairoContext(windowWidth, windowHeight); glUniform1f(directUniform, 1); char frameBuf[20]; snprintf(frameBuf,20,"Frame %u",m_sys->mainClip->state.FP); GLfloat vertex_coords[40]; GLfloat color_coords[80]; //Draw bars for (int i=0;i<9;i++) { vertex_coords[i*4] = 0; vertex_coords[i*4+1] = (i+1)*windowHeight/10; vertex_coords[i*4+2] = windowWidth; vertex_coords[i*4+3] = (i+1)*windowHeight/10; } for (int i=0;i<80;i++) color_coords[i] = 0.7; glVertexAttribPointer(VERTEX_ATTRIB, 2, GL_FLOAT, GL_FALSE, 0, vertex_coords); glVertexAttribPointer(COLOR_ATTRIB, 4, GL_FLOAT, GL_FALSE, 0, color_coords); glEnableVertexAttribArray(VERTEX_ATTRIB); glEnableVertexAttribArray(COLOR_ATTRIB); glDrawArrays(GL_LINES, 0, 20); glDisableVertexAttribArray(VERTEX_ATTRIB); glDisableVertexAttribArray(COLOR_ATTRIB); list::iterator it=m_sys->profilingData.begin(); for(;it!=m_sys->profilingData.end();++it) (*it)->plot(1000000/m_sys->mainClip->getFrameRate(),cr); glUniform1f(directUniform, 0); mapCairoTexture(windowWidth, windowHeight); //clear the surface cairo_save(cr); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_paint(cr); cairo_restore(cr); } void RenderThread::coreRendering() { glBindFramebuffer(GL_FRAMEBUFFER, 0); glDrawBuffer(GL_BACK); //Clear the back buffer RGB bg=m_sys->mainClip->getBackground(); glClearColor(bg.Red/255.0F,bg.Green/255.0F,bg.Blue/255.0F,1); glClear(GL_COLOR_BUFFER_BIT); lsglLoadIdentity(); setMatrixUniform(LSGL_MODELVIEW); m_sys->mainClip->getStage()->Render(*this); if(m_sys->showProfilingData) plotProfilingData(); handleGLErrors(); } //Renders the error message which caused the VM to stop. void RenderThread::renderErrorPage(RenderThread *th, bool standalone) { lsglLoadIdentity(); lsglScalef(1.0f/th->scaleX,-1.0f/th->scaleY,1); lsglTranslatef(-th->offsetX,(th->windowHeight-th->offsetY)*(-1.0f),0); setMatrixUniform(LSGL_MODELVIEW); cairo_t *cr = getCairoContext(windowWidth, windowHeight); cairo_set_source_rgb(cr, 0, 0, 0); cairo_paint(cr); cairo_set_source_rgb(cr, 0.8, 0.8, 0.8); renderText(cr, "We're sorry, Lightspark encountered a yet unsupported Flash file", 0,th->windowHeight/2+20); stringstream errorMsg; errorMsg << "SWF file: " << th->m_sys->mainClip->getOrigin().getParsedURL(); renderText(cr, errorMsg.str().c_str(),0,th->windowHeight/2); errorMsg.str(""); errorMsg << "Cause: " << th->m_sys->errorCause; renderText(cr, errorMsg.str().c_str(),0,th->windowHeight/2-20); if (standalone) { renderText(cr, "Please look at the console output to copy this error", 0,th->windowHeight/2-40); renderText(cr, "Press 'Ctrl+Q' to exit",0,th->windowHeight/2-60); } else { renderText(cr, "Press Ctrl+C to copy this error to clipboard", 0,th->windowHeight/2-40); } glUniform1f(alphaUniform, 1); mapCairoTexture(windowWidth, windowHeight); glFlush(); } void RenderThread::addUploadJob(ITextureUploadable* u) { Locker l(mutexUploadJobs); if(m_sys->isShuttingDown() || status!=STARTED) { u->uploadFence(); return; } uploadJobs.push_back(u); uploadNeeded=true; event.signal(); } ITextureUploadable* RenderThread::getUploadJob() { Locker l(mutexUploadJobs); assert(!uploadJobs.empty()); ITextureUploadable* ret=uploadJobs.front(); uploadJobs.pop_front(); if(uploadJobs.empty()) uploadNeeded=false; return ret; } void RenderThread::draw(bool force) { if(renderNeeded && !force) //A rendering is already queued return; renderNeeded=true; event.signal(); time_d.assign_current_time(); Glib::TimeVal diff=time_d-time_s-FPS_time; if(!diff.negative()) /* is one seconds elapsed? */ { time_s=time_d; LOG(LOG_INFO,_("FPS: ") << dec << frameCount); frameCount=0; secsCount++; } else frameCount++; } void RenderThread::tick() { draw(false); } void RenderThread::tickFence() { } void RenderThread::releaseTexture(const TextureChunk& chunk) { uint32_t blocksW=(chunk.width+CHUNKSIZE-1)/CHUNKSIZE; uint32_t blocksH=(chunk.height+CHUNKSIZE-1)/CHUNKSIZE; uint32_t numberOfBlocks=blocksW*blocksH; Locker l(mutexLargeTexture); LargeTexture& tex=largeTextures[chunk.texId]; for(uint32_t i=0;i=bitmapSize) { badRect=true; break; } if(tex.bitmap[bitOffset/8]&(1<<(bitOffset%8))) { badRect=true; break; } } if(badRect) break; } if(!badRect) break; } if(start==bitmapSize) return false; //Now set all those blocks are used for(uint32_t i=0;i. **************************************************************************/ #ifndef BACKENDS_RENDERING_H #define BACKENDS_RENDERING_H 1 #include "backends/lsopengl.h" #include "backends/rendering_context.h" #include "timer.h" #include #ifdef _WIN32 # include #endif namespace lightspark { class RenderThread: public ITickJob, public GLRenderContext { friend class DisplayObject; private: SystemState* m_sys; Thread* t; enum STATUS { CREATED=0, STARTED, TERMINATED }; volatile STATUS status; EngineData* engineData; void worker(); void init(); void deinit(); void commonGLInit(int width, int height); void commonGLResize(); void commonGLDeinit(); GLuint pixelBuffers[2]; uint32_t currentPixelBuffer; intptr_t currentPixelBufferOffset; uint32_t pixelBufferWidth; uint32_t pixelBufferHeight; void resizePixelBuffers(uint32_t w, uint32_t h); ITextureUploadable* prevUploadJob; GLuint allocateNewGLTexture() const; LargeTexture& allocateNewTexture(); bool allocateChunkOnTextureCompact(LargeTexture& tex, TextureChunk& ret, uint32_t blocksW, uint32_t blocksH); bool allocateChunkOnTextureSparse(LargeTexture& tex, TextureChunk& ret, uint32_t blocksW, uint32_t blocksH); //Possible events to be handled //TODO: pad to avoid false sharing on the cache lines volatile bool renderNeeded; volatile bool uploadNeeded; volatile bool resizeNeeded; volatile bool newTextureNeeded; void handleNewTexture(); void finalizeUpload(); void handleUpload(); Semaphore event; std::string fontPath; volatile uint32_t newWidth; volatile uint32_t newHeight; float scaleX; float scaleY; int offsetX; int offsetY; #ifdef _WIN32 HGLRC mRC; HDC mDC; #else Display* mDisplay; Window mWindow; #ifndef ENABLE_GLES2 GLXFBConfig mFBConfig; GLXContext mContext; #else EGLDisplay mEGLDisplay; EGLContext mEGLContext; EGLConfig mEGLConfig; EGLSurface mEGLSurface; #endif #endif Glib::TimeVal time_s, time_d; static const Glib::TimeVal FPS_time; bool loadShaderPrograms(); bool tempBufferAcquired; void tick(); void tickFence(); int frameCount; int secsCount; Mutex mutexUploadJobs; std::deque uploadJobs; /* Utility to get a job to do */ ITextureUploadable* getUploadJob(); /* Common code to handle the core of the rendering */ void coreRendering(); void plotProfilingData(); Semaphore initialized; static void SizeAllocateCallback(GtkWidget* widget, GdkRectangle* allocation, gpointer data); public: RenderThread(SystemState* s); ~RenderThread(); /** The EngineData object must survive for the whole life of this RenderThread */ void start(EngineData* data); /* The stop function should be call on exit even if the thread is not started */ void stop(); void wait(); void draw(bool force); /** Allocates a chunk from the shared texture */ TextureChunk allocateTexture(uint32_t w, uint32_t h, bool compact); /** Release texture */ void releaseTexture(const TextureChunk& chunk); /** Load the given data in the given texture chunk */ void loadChunkBGRA(const TextureChunk& chunk, uint32_t w, uint32_t h, uint8_t* data); /** Enqueue something to be uploaded to texture */ void addUploadJob(ITextureUploadable* u); void requestResize(uint32_t w, uint32_t h, bool force); void waitForInitialization() { initialized.wait(); } void forceInitialization() { initialized.signal(); } //OpenGL programs int gpu_program; volatile uint32_t windowWidth; volatile uint32_t windowHeight; bool hasNPOTTextures; GLint fragmentTexScaleUniform; GLint directUniform; void renderErrorPage(RenderThread *rt, bool standalone); cairo_t *cairoTextureContext; cairo_surface_t *cairoTextureSurface; uint8_t *cairoTextureData; GLuint cairoTextureID; cairo_t* getCairoContext(int w, int h); void mapCairoTexture(int w, int h); void renderText(cairo_t *cr, const char *text, int x, int y); }; RenderThread* getRenderThread(); }; #endif /* BACKENDS_RENDERING_H */ lightspark-0.7.2/src/backends/rendering_context.cpp000066400000000000000000000257601212105246600224670ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2011-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ //This file implements a few helpers that should be drop-in replacements for //the Open GL coordinate matrix handling API. GLES 2.0 does not provide this //API, so applications need to handle the coordinate transformations and keep //the state themselves. // //The functions have the same signature as the original gl ones but with a ls //prefix added to make their purpose more clear. The main difference from a //usage point of view compared to the GL API is that the operations take effect //- the projection of modelview matrix uniforms sent to the shader - only when //explicitly calling setMatrixUniform. #include #include #include #include "backends/rendering_context.h" #include "logger.h" #include "scripting/flash/display/flashdisplay.h" using namespace std; using namespace lightspark; #define LSGL_MATRIX_SIZE (16*sizeof(GLfloat)) const GLfloat RenderContext::lsIdentityMatrix[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; const CachedSurface CairoRenderContext::invalidSurface; RenderContext::RenderContext(CONTEXT_TYPE t):contextType(t) { lsglLoadIdentity(); } void RenderContext::lsglLoadMatrixf(const GLfloat *m) { memcpy(lsMVPMatrix, m, LSGL_MATRIX_SIZE); } void RenderContext::lsglLoadIdentity() { lsglLoadMatrixf(lsIdentityMatrix); } void RenderContext::lsglMultMatrixf(const GLfloat *m) { GLfloat tmp[16]; for(int i=0;i<4;i++) { for(int j=0;j<4;j++) { GLfloat sum=0; for (int k=0;k<4;k++) { sum += lsMVPMatrix[i+k*4]*m[j*4+k]; } tmp[i+j*4] = sum; } } memcpy(lsMVPMatrix, tmp, LSGL_MATRIX_SIZE); } void RenderContext::lsglScalef(GLfloat scaleX, GLfloat scaleY, GLfloat scaleZ) { static GLfloat scale[16]; memcpy(scale, lsIdentityMatrix, LSGL_MATRIX_SIZE); scale[0] = scaleX; scale[5] = scaleY; scale[10] = scaleZ; lsglMultMatrixf(scale); } void RenderContext::lsglTranslatef(GLfloat translateX, GLfloat translateY, GLfloat translateZ) { static GLfloat trans[16]; memcpy(trans, lsIdentityMatrix, LSGL_MATRIX_SIZE); trans[12] = translateX; trans[13] = translateY; trans[14] = translateZ; lsglMultMatrixf(trans); } void GLRenderContext::lsglOrtho(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f) { GLfloat ortho[16]; memset(ortho, 0, sizeof(ortho)); ortho[0] = 2/(r-l); ortho[5] = 2/(t-b); ortho[10] = 2/(n-f); ortho[12] = -(r+l)/(r-l); ortho[13] = -(t+b)/(t-b); ortho[14] = -(f+n)/(f-n); ortho[15] = 1; lsglMultMatrixf(ortho); } const CachedSurface& GLRenderContext::getCachedSurface(const DisplayObject* d) const { return d->cachedSurface; } void GLRenderContext::renderTextured(const TextureChunk& chunk, int32_t x, int32_t y, uint32_t w, uint32_t h, float alpha, COLOR_MODE colorMode) { //Set color mode glUniform1f(yuvUniform, (colorMode==YUV_MODE)?1:0); //Set alpha glUniform1f(alphaUniform, alpha); //Set matrix setMatrixUniform(LSGL_MODELVIEW); glBindTexture(GL_TEXTURE_2D, largeTextures[chunk.texId].id); const uint32_t blocksPerSide=largeTextureSize/CHUNKSIZE; uint32_t startX, startY, endX, endY; assert(chunk.getNumberOfChunks()==((chunk.width+CHUNKSIZE-1)/CHUNKSIZE)*((chunk.height+CHUNKSIZE-1)/CHUNKSIZE)); uint32_t curChunk=0; //The 4 corners of each texture are specified as the vertices of 2 triangles, //so there are 6 vertices per quad, two of them duplicated (the diagonal) //Allocate the data on the stack to reduce heap fragmentation GLfloat *vertex_coords = g_newa(GLfloat,chunk.getNumberOfChunks()*12); GLfloat *texture_coords = g_newa(GLfloat,chunk.getNumberOfChunks()*12); for(uint32_t i=0, k=0;isecond.tex.chunks; it->second.tex.chunks=NULL; } cairo_destroy(cr); } cairo_surface_t* CairoRenderContext::getCairoSurfaceForData(uint8_t* buf, uint32_t width, uint32_t height) { uint32_t cairoWidthStride=cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); assert(cairoWidthStride==width*4); return cairo_image_surface_create_for_data(buf, CAIRO_FORMAT_ARGB32, width, height, cairoWidthStride); } void CairoRenderContext::simpleBlit(int32_t destX, int32_t destY, uint8_t* sourceBuf, uint32_t sourceTotalWidth, uint32_t sourceTotalHeight, int32_t sourceX, int32_t sourceY, uint32_t sourceWidth, uint32_t sourceHeight) { cairo_surface_t* sourceSurface = getCairoSurfaceForData(sourceBuf, sourceTotalWidth, sourceTotalHeight); cairo_pattern_t* sourcePattern = cairo_pattern_create_for_surface(sourceSurface); cairo_surface_destroy(sourceSurface); cairo_pattern_set_filter(sourcePattern, CAIRO_FILTER_NEAREST); cairo_pattern_set_extend(sourcePattern, CAIRO_EXTEND_NONE); cairo_matrix_t matrix; cairo_matrix_init_translate(&matrix, sourceX-destX, sourceY-destY); cairo_pattern_set_matrix(sourcePattern, &matrix); cairo_set_source(cr, sourcePattern); cairo_pattern_destroy(sourcePattern); cairo_rectangle(cr, destX, destY, sourceWidth, sourceHeight); cairo_fill(cr); } void CairoRenderContext::transformedBlit(const MATRIX& m, uint8_t* sourceBuf, uint32_t sourceTotalWidth, uint32_t sourceTotalHeight, FILTER_MODE filterMode) { cairo_surface_t* sourceSurface = getCairoSurfaceForData(sourceBuf, sourceTotalWidth, sourceTotalHeight); cairo_pattern_t* sourcePattern = cairo_pattern_create_for_surface(sourceSurface); cairo_surface_destroy(sourceSurface); cairo_pattern_set_filter(sourcePattern, (filterMode==FILTER_SMOOTH)?CAIRO_FILTER_BILINEAR:CAIRO_FILTER_NEAREST); cairo_pattern_set_extend(sourcePattern, CAIRO_EXTEND_NONE); cairo_set_matrix(cr, &m); cairo_set_source(cr, sourcePattern); cairo_pattern_destroy(sourcePattern); cairo_rectangle(cr, 0, 0, sourceTotalWidth, sourceTotalHeight); cairo_fill(cr); } void CairoRenderContext::renderTextured(const TextureChunk& chunk, int32_t x, int32_t y, uint32_t w, uint32_t h, float alpha, COLOR_MODE colorMode) { //TODO: support alpha, and colorMode uint8_t* buf=(uint8_t*)chunk.chunks; cairo_surface_t* chunkSurface = getCairoSurfaceForData(buf, chunk.width, chunk.height); cairo_pattern_t* chunkPattern = cairo_pattern_create_for_surface(chunkSurface); cairo_surface_destroy(chunkSurface); cairo_pattern_set_filter(chunkPattern, CAIRO_FILTER_BILINEAR); cairo_pattern_set_extend(chunkPattern, CAIRO_EXTEND_NONE); cairo_matrix_t matrix; //TODO: Support scaling cairo_matrix_init_translate(&matrix, -x, -y); cairo_pattern_set_matrix(chunkPattern, &matrix); cairo_set_source(cr, chunkPattern); cairo_pattern_destroy(chunkPattern); cairo_rectangle(cr, x, y, w, h); cairo_fill(cr); } const CachedSurface& CairoRenderContext::getCachedSurface(const DisplayObject* d) const { auto ret=customSurfaces.find(d); if(ret==customSurfaces.end()) { //No surface is stored, return an invalid one return invalidSurface; } return ret->second; } CachedSurface& CairoRenderContext::allocateCustomSurface(const DisplayObject* d, uint8_t* texBuf) { auto ret=customSurfaces.insert(make_pair(d, CachedSurface())); assert(ret.second); CachedSurface& surface=ret.first->second; surface.tex.chunks=(uint32_t*)texBuf; return surface; } lightspark-0.7.2/src/backends/rendering_context.h000066400000000000000000000117401212105246600221250ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2011-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_RENDERING_CONTEXT_H #define BACKENDS_RENDERING_CONTEXT_H 1 #include #include "backends/lsopengl.h" #include "backends/graphics.h" namespace lightspark { enum VertexAttrib { VERTEX_ATTRIB=0, COLOR_ATTRIB, TEXCOORD_ATTRIB}; /* * The RenderContext contains all (public) functions that are needed by DisplayObjects to draw themselves. */ class RenderContext { protected: /* Modelview matrix manipulation */ static const GLfloat lsIdentityMatrix[16]; GLfloat lsMVPMatrix[16]; std::stack lsglMatrixStack; ~RenderContext(){} void lsglMultMatrixf(const GLfloat *m); public: enum CONTEXT_TYPE { CAIRO=0, GL }; RenderContext(CONTEXT_TYPE t); CONTEXT_TYPE contextType; /* Modelview matrix manipulation */ void lsglLoadIdentity(); void lsglLoadMatrixf(const GLfloat *m); void lsglScalef(GLfloat scaleX, GLfloat scaleY, GLfloat scaleZ); void lsglTranslatef(GLfloat translateX, GLfloat translateY, GLfloat translateZ); enum COLOR_MODE { RGB_MODE=0, YUV_MODE }; enum MASK_MODE { NO_MASK = 0, ENABLE_MASK }; /* Textures */ /** Render a quad of given size using the given chunk */ virtual void renderTextured(const TextureChunk& chunk, int32_t x, int32_t y, uint32_t w, uint32_t h, float alpha, COLOR_MODE colorMode)=0; /** * Get the right CachedSurface from an object */ virtual const CachedSurface& getCachedSurface(const DisplayObject* obj) const=0; }; class GLRenderContext: public RenderContext { protected: GLint projectionMatrixUniform; GLint modelviewMatrixUniform; GLint yuvUniform; GLint alphaUniform; /* Textures */ Mutex mutexLargeTexture; uint32_t largeTextureSize; class LargeTexture { public: GLuint id; uint8_t* bitmap; LargeTexture(uint8_t* b):id(-1),bitmap(b){} ~LargeTexture(){/*delete[] bitmap;*/} }; std::vector largeTextures; ~GLRenderContext(){} enum LSGL_MATRIX {LSGL_PROJECTION=0, LSGL_MODELVIEW}; /* * Uploads the current matrix as the specified type. */ void setMatrixUniform(LSGL_MATRIX m) const; public: GLRenderContext() : RenderContext(GL), largeTextureSize(0) { } void lsglOrtho(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); void renderTextured(const TextureChunk& chunk, int32_t x, int32_t y, uint32_t w, uint32_t h, float alpha, COLOR_MODE colorMode); /** * Get the right CachedSurface from an object * In the OpenGL case we just get the CachedSurface inside the object itself */ const CachedSurface& getCachedSurface(const DisplayObject* obj) const; /* Utility */ static bool handleGLErrors(); }; class CairoRenderContext: public RenderContext { private: std::map customSurfaces; cairo_t* cr; static cairo_surface_t* getCairoSurfaceForData(uint8_t* buf, uint32_t width, uint32_t height); /* * An invalid surface to be returned for objects with no content */ static const CachedSurface invalidSurface; public: CairoRenderContext(uint8_t* buf, uint32_t width, uint32_t height); virtual ~CairoRenderContext(); void renderTextured(const TextureChunk& chunk, int32_t x, int32_t y, uint32_t w, uint32_t h, float alpha, COLOR_MODE colorMode); /** * Get the right CachedSurface from an object * In the Cairo case we get the right CachedSurface out of the map */ const CachedSurface& getCachedSurface(const DisplayObject* obj) const; /** * The CairoRenderContext acquires the ownership of the buffer * it will be freed on destruction */ CachedSurface& allocateCustomSurface(const DisplayObject* d, uint8_t* texBuf); /** * Do a fast non filtered, non scaled blit of ARGB data */ void simpleBlit(int32_t destX, int32_t destY, uint8_t* sourceBuf, uint32_t sourceTotalWidth, uint32_t sourceTotalHeight, int32_t sourceX, int32_t sourceY, uint32_t sourceWidth, uint32_t sourceHeight); /** * Do an optionally filtered blit with transformation */ enum FILTER_MODE { FILTER_NONE = 0, FILTER_SMOOTH }; void transformedBlit(const MATRIX& m, uint8_t* sourceBuf, uint32_t sourceTotalWidth, uint32_t sourceTotalHeight, FILTER_MODE filterMode); }; } #endif /* BACKENDS_RENDERING_CONTEXT_H */ lightspark-0.7.2/src/backends/rtmputils.cpp000066400000000000000000000064141212105246600210040ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2011-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "backends/rtmputils.h" #include "logger.h" #include "swf.h" #ifdef ENABLE_RTMP #include #endif using namespace lightspark; using namespace std; RTMPDownloader::RTMPDownloader(const tiny_string& _url, const tiny_string& _stream, ILoadable* o): ThreadedDownloader(_url, true, o), stream(_stream) { } void RTMPDownloader::threadAbort() { Downloader::stop(); } void RTMPDownloader::execute() { #ifdef ENABLE_RTMP bool downloadFailed=true; //Allocate and initialize the RTMP context RTMP* rtmpCtx=RTMP_Alloc(); RTMP_Init(rtmpCtx); //Build the URL for the library tiny_string rtmpUrl=url; rtmpUrl+=" playpath="; rtmpUrl+=stream; rtmpUrl+=" swfVfy="; rtmpUrl+=getSys()->mainClip->getOrigin().getURL(); rtmpUrl+=" tcUrl="; rtmpUrl+=url; //Setup url needs a char*, not a const char*... int urlLen=rtmpUrl.numBytes(); char* urlBuf=new char[urlLen+1]; strncpy(urlBuf,rtmpUrl.raw_buf(),urlLen+1); int ret=RTMP_SetupURL(rtmpCtx, urlBuf); LOG(LOG_TRACE, "RTMP_SetupURL " << rtmpUrl << " " << ret); if(!ret) { setFailed(); goto cleanup; } ret=RTMP_Connect(rtmpCtx, NULL); LOG(LOG_TRACE, "Connect_Connect " << ret); if(!ret) { setFailed(); goto cleanup; } ret=RTMP_ConnectStream(rtmpCtx, 0); LOG(LOG_TRACE, "RTMP_ConnectStream " << ret); if(!ret) { setFailed(); goto cleanup; } //TODO: implement unsafe buffer concept char buf[4096]; RTMP_SetBufferMS(rtmpCtx, 3600000); RTMP_UpdateBufferMS(rtmpCtx); // looping conditions copied from rtmpdump sources do { //TODO: avoid the copy in the temporary buffer ret=RTMP_Read(rtmpCtx,buf,4096); if(ret>0) append((uint8_t*)buf,ret); } while(ret >= 0 && !threadAborting && !hasFailed() && RTMP_IsConnected(rtmpCtx) && !RTMP_IsTimedout(rtmpCtx)); // Apparently negative ret indicates error only if // m_read.status isn't a success code, see rtmpdump sources downloadFailed=ret < 0 && rtmpCtx->m_read.status != RTMP_READ_COMPLETE; if(downloadFailed || RTMP_IsTimedout(rtmpCtx)) setFailed(); cleanup: RTMP_Close(rtmpCtx); RTMP_Free(rtmpCtx); delete[] urlBuf; #else //ENABLE_RTMP not defined LOG(LOG_ERROR,_("NET: RTMP not enabled in this build. Downloader will always fail.")); setFailed(); return; #endif //Notify the downloader no more data should be expected. Do //this only if setFailed() hasn't been called above. if(!hasFinished()) setFinished(); } lightspark-0.7.2/src/backends/rtmputils.h000066400000000000000000000024701212105246600204470ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2011-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_RTMPUTILS_H #define BACKENDS_RTMPUTILS_H 1 #include "backends/netutils.h" namespace lightspark { class ILoadable; class RTMPDownloader: public ThreadedDownloader { private: void execute(); void threadAbort(); tiny_string stream; public: RTMPDownloader(const tiny_string& _url, const tiny_string& _stream, ILoadable* o); }; }; #endif /* BACKENDS_RTMPUTILS_H */ lightspark-0.7.2/src/backends/security.cpp000066400000000000000000001442751212105246600206200ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2010-2011 Timon Van Overveldt (timonvo@gmail.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "parsing/crossdomainpolicy.h" #include "swf.h" #include "compat.h" #include "scripting/class.h" #include "scripting/toplevel/Error.h" #include "scripting/flash/net/XMLSocket.h" #include #include #include #include #include "backends/security.h" using namespace lightspark; using namespace std; const unsigned int SocketPolicyFile::MASTER_PORT = 843; const char *SocketPolicyFile::MASTER_PORT_URL = ":843"; /** * \brief SecurityManager constructor */ SecurityManager::SecurityManager(): sandboxType(REMOTE),exactSettings(true),exactSettingsLocked(false) { sandboxNames[0] = "remote"; sandboxNames[1] = "localWithFile"; sandboxNames[2] = "localWithNetwork"; sandboxNames[3] = "localTrusted"; sandboxTitles[0] = "remote"; sandboxTitles[1] = "local-with-filesystem"; sandboxTitles[2] = "local-with-networking"; sandboxTitles[3] = "local-trusted"; //== Lock initialized } /** * \brief SecurityManager destructor * * SecurityManager destructor. Acquires mutex before proceeding. */ SecurityManager::~SecurityManager() { RecMutex::Lock l(mutex); URLPFileMapIt i = pendingURLPFiles.begin(); for(; i != pendingURLPFiles.end(); ++i) delete (*i).second; i = loadedURLPFiles.begin(); for(;i != loadedURLPFiles.end(); ++i) delete (*i).second; } /** * \brief Add policy file at the given URL * * Adds a policy file at the given URL to list of managed policy files. * Classifies the URL first and then decides whether to call \c addURLPolicyFile() * (the currently only supported type) * \param url The URL where the policy file resides * \return A pointer to the newly created PolicyFile object or NULL if the URL is of an unsupported type */ PolicyFile* SecurityManager::addPolicyFile(const URLInfo& url) { if(url.getProtocol() == "http" || url.getProtocol() == "https" || url.getProtocol() == "ftp") return addURLPolicyFile(url); else if(url.getProtocol() == "xmlsocket") return addSocketPolicyFile(url); return NULL; } /** * \brief Add an URL policy file at the given URL * * Adds an URL policy file at the given URL to the list of managed URL policy files. * Policy files aren't loaded when adding, this is delayed until the policy file is actually needed. * Waits for mutex at start and releases mutex when finished * \param url The URL where the URL policy file resides * \return A pointer to the newly created URLPolicyFile object */ URLPolicyFile* SecurityManager::addURLPolicyFile(const URLInfo& url) { RecMutex::Lock l(mutex); URLPolicyFile* file = new URLPolicyFile(url); if(file->isValid()) { LOG(LOG_INFO, _("SECURITY: Added URL policy file is valid, adding to URL policy file list (") << url << ")"); pendingURLPFiles.insert(URLPFilePair(url.getHostname(), file)); } return file; } /** * \brief Add a socket policy file at the given URL * * Adds an socket policy file at the given URL to the list of managed socket policy files. * Policy files aren't loaded when adding, this is delayed until the policy file is actually needed. * Waits for mutex at start and releases mutex when finished * \param url The URL where the socket policy file resides * \return A pointer to the newly created SocketPolicyFile object */ SocketPolicyFile* SecurityManager::addSocketPolicyFile(const URLInfo& url) { RecMutex::Lock l(mutex); SocketPolicyFile* file = new SocketPolicyFile(url); if(file->isValid()) { LOG(LOG_INFO, _("SECURITY: Added socket policy file is valid, adding to socket policy file list (") << url << ")"); pendingSocketPFiles.insert(SocketPFilePair(url.getHostname(), file)); } return file; } template T* SecurityManager::getPolicyFileByURL(std::multimap& pendingFiles, std::multimap& loadedFiles, const URLInfo& url) { RecMutex::Lock l(mutex); std::pair< typename std::multimap::iterator, typename std::multimap::iterator > range; typename std::multimap::iterator i; //Check the loaded URL policy files first range = loadedFiles.equal_range(url.getHostname()); for(i = range.first; i != range.second; ++i) { if((*i).second->getOriginalURL() == url) { LOG(LOG_INFO, _("SECURITY: URL policy file found in loaded list (") << url << ")"); return (*i).second; } } //Check the pending URL policy files next range = pendingFiles.equal_range(url.getHostname()); for(i = range.first; i != range.second; ++i) { if((*i).second->getOriginalURL() == url) { LOG(LOG_INFO, _("SECURITY: URL policy file found in pending list (") << url << ")"); return (*i).second; } } return NULL; } /** * \brief Search for an URL policy file object in lists * * Searches for an URL policy file object in the lists of managed URL policy files by URL. * Returns NULL when such an object could not be found. * Waits for mutex at start and releases mutex when finished * \param url The URL where the URL policy file object would reside. * \return The found URL policy file object or NULL */ URLPolicyFile* SecurityManager::getURLPolicyFileByURL(const URLInfo& url) { return getPolicyFileByURL(pendingURLPFiles, loadedURLPFiles, url); } /** * \brief Search for an socket policy file object in lists * * Searches for a socket policy file object in the lists of managed socket policy files by URL. * Returns NULL when such an object could not be found. * Waits for mutex at start and releases mutex when finished * \param url The URL where the socket policy file object would reside. * \return The found socket policy file object or NULL */ SocketPolicyFile* SecurityManager::getSocketPolicyFileByURL(const URLInfo& url) { return getPolicyFileByURL(pendingSocketPFiles, loadedSocketPFiles, url); } template void SecurityManager::loadPolicyFile(std::multimap& pendingFiles, std::multimap& loadedFiles, PolicyFile *file) { RecMutex::Lock l(mutex); if(pendingFiles.count(file->getURL().getHostname()) > 0) { LOG(LOG_INFO, _("SECURITY: Loading policy file (") << file->getURL() << ")"); // Policy files are downloaded in blocking manner, // release the lock during loading l.release(); file->load(); l.acquire(); std::pair< typename std::multimap::iterator, typename std::multimap::iterator > range; range = pendingFiles.equal_range(file->getURL().getHostname()); typename std::multimap::iterator i; for(i = range.first; i != range.second; ++i) { if((*i).second == file) { loadedFiles.insert(make_pair(file->getURL().getHostname(), (*i).second)); pendingFiles.erase(i); break; } } } } /** * \brief Load a given URL policy file object * * Loads a given URL policy file object (if it isn't loaded yet). * This moves the object from the pending URL policy files list to the loaded URL policy files list. * Waits for mutex at start and releases mutex when finished * \param file A pointer to the URL policy file object to load. */ void SecurityManager::loadURLPolicyFile(URLPolicyFile* file) { loadPolicyFile(pendingURLPFiles, loadedURLPFiles, file); } /** * \brief Load a given socket policy file object * * Loads a given socket policy file object (if it isn't loaded yet). * This moves the object from the pending socekt policy files list to the loaded socket policy files list. * Waits for mutex at start and releases mutex when finished * \param file A pointer to the socket policy file object to load. */ void SecurityManager::loadSocketPolicyFile(SocketPolicyFile* file) { loadPolicyFile(pendingSocketPFiles, loadedSocketPFiles, file); } template std::list *SecurityManager::searchPolicyFiles(const URLInfo& url, T *master, bool loadPendingPolicies, std::multimap& pendingFiles, std::multimap& loadedFiles) { std::list *result = new std::list; RecMutex::Lock l(mutex); //Check if the master policy file is loaded. //If another user-added relevant policy file is already loaded, //it's master will have already been loaded too (to check if it is allowed). //So IF any relevant policy file is loaded already, then the master will be too. if(master->isLoaded() && master->isValid()) { LOG(LOG_INFO, _("SECURITY: Master policy file is loaded and valid (") << url << ")"); PolicyFile::METAPOLICY siteControl = master->getMetaPolicy(); //Master defines no policy files are allowed at all if(siteControl == PolicyFile::NONE) { LOG(LOG_INFO, _("SECURITY: DISALLOWED: Master policy file disallows policy files")); delete result; return NULL; } result->push_back(master); //Non-master policy files are allowed if(siteControl != PolicyFile::MASTER_ONLY) { LOG(LOG_INFO, _("SECURITY: Searching for loaded non-master policy files (") << loadedFiles.count(url.getHostname()) << ")"); std::pair< typename std::multimap::iterator, typename std::multimap::iterator > range; typename std::multimap::const_iterator i; range = loadedFiles.equal_range(url.getHostname()); i = range.first; for(;i != range.second; ++i) { if((*i).second == master) continue; result->push_back((*i).second); } //And check the pending policy files next (if we are allowed to) if(loadPendingPolicies) { LOG(LOG_INFO, _("SECURITY: Searching for and loading pending non-master policy files (") << pendingFiles.count(url.getHostname()) << ")"); while(true) { i=pendingFiles.find(url.getHostname()); if(i==pendingFiles.end()) break; result->push_back((*i).second); l.release(); getSys()->securityManager->loadPolicyFile(pendingFiles, loadedFiles, (*i).second); //NOTE: loadURLPolicyFile() will change pendingURLPFiles, //erasing & moving to loadURLPFiles. Therefore, the //iterator i is now invalid. l.acquire(); } } } } return result; } /** * \brief Search for URL policy files relevant to a given URL * * Searches the loaded URL policy file list for URL policy files that are relevant to a given URL. * If \c loadPendingPolicies is true, it search the pending URL policy files list next, * loading every relative policy file. * Waits for mutex at start and releases mutex when finished * \param url The URL that will be evaluated using the relevant policy files. * \param loadPendingPolicies Whether or not to load (and thus check) pending URL policy files. * \return An pointer to a newly created URLPFileList containing the relevant policy files. * This list needs to be deleted after use. */ URLPFileList* SecurityManager::searchURLPolicyFiles(const URLInfo& url, bool loadPendingPolicies) { //Get or create the master policy file object URLInfo masterURL = url.goToURL("/crossdomain.xml"); URLPolicyFile* master = getURLPolicyFileByURL(masterURL); if(master == NULL) master = addURLPolicyFile(masterURL); if(loadPendingPolicies) getSys()->securityManager->loadURLPolicyFile(master); //Get applicable policy files return searchPolicyFiles(url, master, loadPendingPolicies, pendingURLPFiles, loadedURLPFiles); } /** * \brief Search for socket policy files relevant to a given URL * * Searches the loaded socket policy file list for policy files that are relevant to a given URL. * If \c loadPendingPolicies is true, it search the pending socket policy files list next, * loading every relative policy file. * Waits for mutex at start and releases mutex when finished * \param url The URL that will be evaluated using the relevant policy files. * \param loadPendingPolicies Whether or not to load (and thus check) pending socket policy files. * \return An pointer to a newly created SocketPFileList containing the relevant policy files. * This list needs to be deleted after use. */ SocketPFileList* SecurityManager::searchSocketPolicyFiles(const URLInfo& url, bool loadPendingPolicies) { //Get or create the master policy file object URLInfo masterURL = url.goToURL(SocketPolicyFile::MASTER_PORT_URL); SocketPolicyFile* master = getSocketPolicyFileByURL(masterURL); if(master == NULL) master = addSocketPolicyFile(masterURL); if(loadPendingPolicies) getSys()->securityManager->loadSocketPolicyFile(master); //Get applicable policy files SocketPFileList *result; result = searchPolicyFiles(url, master, loadPendingPolicies, pendingSocketPFiles, loadedSocketPFiles); //The target port is checked last if allowed if(master->isLoaded() && master->isValid() && (result != NULL)) { if (master->getMetaPolicy() == PolicyFile::ALL) { SocketPolicyFile* destination = getSocketPolicyFileByURL(url); if (destination == NULL) { //Create and add policy file if it //didn't exist. If it exists //searchPolicyFiles() already added it //to result. destination = addSocketPolicyFile(url); if(loadPendingPolicies) getSys()->securityManager->loadSocketPolicyFile(destination); result->push_back(destination); } } } return result; } /** * \brief Checks if a given sandbox is in the given allowed sandboxes * * \param sandbox The sandbox to check * \param allowedSandboxes A bitwise expression of allowed sandboxes. * \return \c true if the sandbox is allowed, \c false if not */ bool SecurityManager::evaluateSandbox(SANDBOXTYPE sandbox, int allowedSandboxes) { return (allowedSandboxes & sandbox) != 0; } /** * \brief Evaluates an URL static properties to see if it is allowed by the various security features. * * This first checks if the current sandbox is allowed access to the URL. * Next the port is checked to see if isn't restricted. * Then, if requested, the URL is checked to see if it doesn't point to a resource * above the current directory in the directory hierarchy (only applicable to local URLs). * \param url The URL to evaluate * \param allowedSandboxesRemote The sandboxes that are allowed to access remote URLs in this case. * Can be a bitwise expression of sandboxes. * \param allowedSandboxesLocal The sandboxes that are allowed to access local URLs in this case. * Can be a bitwise expression of sandboxes. * \return \c ALLOWED if the URL is allowed or one of \c NA_*, where * is the reason for not allowing. * \see SecurityManager::evaluateSandboxURL() * \see SecurityManager::evaluatePortURL() * \see SecurityManager::evaluateLocalDirectoryURL() */ SecurityManager::EVALUATIONRESULT SecurityManager::evaluateURLStatic(const URLInfo& url, int allowedSandboxesRemote, int allowedSandboxesLocal, bool restrictLocalDirectory) { //Check the sandbox first EVALUATIONRESULT sandboxResult = evaluateSandboxURL(url, allowedSandboxesRemote, allowedSandboxesLocal); if(sandboxResult != ALLOWED) return sandboxResult; //Check if the URL points to a restricted port EVALUATIONRESULT portResult = evaluatePortURL(url); if(portResult != ALLOWED) return portResult; //If requested, make sure local URLs are restricted to the local directory if(restrictLocalDirectory) { EVALUATIONRESULT restrictLocalDirResult = evaluateLocalDirectoryURL(url); if(restrictLocalDirResult != ALLOWED) return restrictLocalDirResult; } //All checks passed, so we allow the URL connection return ALLOWED; } /** * \brief Throw SecurityError if URL doesn't satisfy security constrains. */ void SecurityManager::checkURLStaticAndThrow(const URLInfo& url, int allowedSandboxesRemote, int allowedSandboxesLocal, bool restrictLocalDirectory) { SecurityManager::EVALUATIONRESULT evaluationResult = getSys()->securityManager->evaluateURLStatic(url, allowedSandboxesRemote, allowedSandboxesLocal, restrictLocalDirectory); //Network sandboxes can't access local files (this should be a SecurityErrorEvent) if(evaluationResult == SecurityManager::NA_REMOTE_SANDBOX) throw Class::getInstanceS("SecurityError: " "connect to network"); //Local-with-filesystem sandbox can't access network else if(evaluationResult == SecurityManager::NA_LOCAL_SANDBOX) throw Class::getInstanceS("SecurityError: " "connect to local file"); else if(evaluationResult == SecurityManager::NA_PORT) throw Class::getInstanceS("SecurityError: " "connect to restricted port"); else if(evaluationResult == SecurityManager::NA_RESTRICT_LOCAL_DIRECTORY) throw Class::getInstanceS("SecurityError: " "not allowed to navigate up for local files"); } /** * \brief Checks if the current sandbox is allowed access to the given URL. * * \param url The URL to evaluate the sandbox against * \param allowedSandboxesRemote The sandboxes that are allowed to access remote URLs in this case. * Can be a bitwise expression of sandboxes. * \param allowedSandboxesLocal The sandboxes that are allowed to access local URLs in this case. * Can be a bitwise expression of sandboxes. * \return \c ALLOWED if allowed or otherwise \c NA_REMOTE_SANDBOX/NA_LOCAL_SANDBOX depending on the reason. */ SecurityManager::EVALUATIONRESULT SecurityManager::evaluateSandboxURL(const URLInfo& url, int allowedSandboxesRemote, int allowedSandboxesLocal) { //The URL is remote and the current sandbox doesn't match the allowed sandboxes for remote URLs if(url.getProtocol() != "file" && (~allowedSandboxesRemote) & sandboxType) return NA_REMOTE_SANDBOX; //The URL is local and the current sandbox doesn't match the allowed sandboxes for local URLs if(url.getProtocol() == "file" && (~allowedSandboxesLocal) & sandboxType) return NA_LOCAL_SANDBOX; return ALLOWED; } /** * \brief Checks if the URL doesn't point to a resource higher up the directory hierarchy than * the current directory * * \param url The URL to evaluate * \return \c ALLOWED if allowed or otherwise \c NA_RESTRICT_LOCAL_DIRECTORY */ SecurityManager::EVALUATIONRESULT SecurityManager::evaluateLocalDirectoryURL(const URLInfo& url) { //The URL is local and points to a directory above the origin if(url.getProtocol() == "file" && !url.isSubOf(getSys()->mainClip->getOrigin())) return NA_RESTRICT_LOCAL_DIRECTORY; return ALLOWED; } /** * \brief Checks if the port in the given URL isn't restricted, depending on the protocol of the URL * * \param url The URL to evaluate * \return \c ALLOWED if allowed or otherwise \c NA_PORT */ SecurityManager::EVALUATIONRESULT SecurityManager::evaluatePortURL(const URLInfo& url) { if(url.getProtocol() == "http" || url.getProtocol() == "https") if(url.getPort() == 20 || url.getPort() == 21) return NA_PORT; if(url.getProtocol() == "http" || url.getProtocol() == "https" || url.getProtocol() == "ftp") { switch(url.getPort()) { case 1: case 7: case 9: case 11: case 13: case 15: case 17: case 19: case 22: case 23: case 25: case 37: case 42: case 43: case 53: case 77: case 79: case 87: case 95: case 101: case 102: case 103: case 104: case 109: case 110: case 111: case 113: case 115: case 117: case 119: case 123: case 135: case 139: case 143: case 179: case 389: case 465: case 512: case 513: case 514: case 515: case 526: case 530: case 531: case 532: case 540: case 556: case 563: case 587: case 601: case 636: case 993: case 995: case 2049: case 4045: case 6000: return NA_PORT; } } return ALLOWED; } /** * \brief Checks URL policy files to see if the player is allowed access to the given UR * * Waits for mutex at start and releases mutex when finished * \param url The URL to evaluate * \param loadPendingPolicies Whether to load (and thus check) pending policies before evaluating * \return \c ALLOWED if allowed or otherwise \c NA_CROSSDOMAIN_POLICY */ SecurityManager::EVALUATIONRESULT SecurityManager::evaluatePoliciesURL(const URLInfo& url, bool loadPendingPolicies) { //This check doesn't apply to local files if(url.getProtocol() == "file" && getSys()->mainClip->getOrigin().getProtocol() == "file") return ALLOWED; //Streaming from RTMP is always allowed (see //http://forums.adobe.com/thread/422391) if(url.isRTMP()) return ALLOWED; LOG(LOG_INFO, _("SECURITY: Evaluating URL for cross domain policies:")); LOG(LOG_INFO, _("SECURITY: --> URL: ") << url); LOG(LOG_INFO, _("SECURITY: --> Origin: ") << getSys()->mainClip->getOrigin()); //The URL has exactly the same domain name as the origin, always allowed if(url.getProtocol() == getSys()->mainClip->getOrigin().getProtocol() && url.getHostname() == getSys()->mainClip->getOrigin().getHostname()) { LOG(LOG_INFO, _("SECURITY: Same hostname as origin, allowing")); return ALLOWED; } //Search for the policy files to check URLPFileList* files = searchURLPolicyFiles(url, loadPendingPolicies); RecMutex::Lock l(mutex); //Check the policy files if(files != NULL) { URLPFileListConstIt it = files->begin(); for(; it != files->end(); ++it) { if((*it)->allowsAccessFrom(getSys()->mainClip->getOrigin(), url)) { LOG(LOG_INFO, _("SECURITY: ALLOWED: A policy file explicitly allowed access")); delete files; return ALLOWED; } } } LOG(LOG_INFO, _("SECURITY: DISALLOWED: No policy file explicitly allowed access")); delete files; return NA_CROSSDOMAIN_POLICY; } SecurityManager::EVALUATIONRESULT SecurityManager::evaluateSocketConnection(const URLInfo& url, bool loadPendingPolicies) { if(url.getProtocol() != "xmlsocket") return NA_CROSSDOMAIN_POLICY; LOG(LOG_INFO, _("SECURITY: Evaluating socket policy:")); LOG(LOG_INFO, _("SECURITY: --> URL: ") << url); LOG(LOG_INFO, _("SECURITY: --> Origin: ") << getSys()->mainClip->getOrigin()); //Search for the policy files to check SocketPFileList* files = searchSocketPolicyFiles(url, loadPendingPolicies); RecMutex::Lock l(mutex); //Check the policy files if(files != NULL) { SocketPFileListConstIt it = files->begin(); for(; it != files->end(); ++it) { if((*it)->allowsAccessFrom(getSys()->mainClip->getOrigin(), url)) { LOG(LOG_INFO, _("SECURITY: ALLOWED: A policy file explicitly allowed access")); delete files; return ALLOWED; } } } LOG(LOG_INFO, _("SECURITY: DISALLOWED: No policy file explicitly allowed access")); delete files; return NA_CROSSDOMAIN_POLICY; } /** * \brief Checks URL policy files to see if the player is allowed to send a given request header * as part of a request for the given URL * * Waits for mutex at start and releases mutex when finished * \param url The URL of the request to which the request header belongs * \param header The request header to evaluate * \param loadPendingPolicies Whether or not to load (and thus check) pending policy files * \return \c ALLOWED if allowed or otherwise \c NA_HEADER */ SecurityManager::EVALUATIONRESULT SecurityManager::evaluateHeader(const URLInfo& url, const tiny_string& header, bool loadPendingPolicies) { //This check doesn't apply to local files if(url.getProtocol() == "file" && getSys()->mainClip->getOrigin().getProtocol() == "file") return ALLOWED; LOG(LOG_INFO, _("SECURITY: Evaluating header for cross domain policies ('") << header << "'):"); LOG(LOG_INFO, _("SECURITY: --> URL: ") << url); LOG(LOG_INFO, _("SECURITY: --> Origin: ") << getSys()->mainClip->getOrigin()); string headerStrLower(header.raw_buf()); transform(headerStrLower.begin(), headerStrLower.end(), headerStrLower.begin(), ::tolower); string headerStr = headerStrLower; if(headerStr.find("_") != string::npos) headerStr.replace(headerStr.find("_"), 1, "-"); //Disallowed headers, in any case if(headerStr == "accept-charset" && headerStr == "accept-encoding" && headerStr == "accept-ranges" && headerStr == "age" && headerStr == "allow" && headerStr == "allowed" && headerStr == "authorization" && headerStr == "charge-to" && headerStr == "connect" && headerStr == "connection" && headerStr == "content-length" && headerStr == "content-location" && headerStr == "content-range" && headerStr == "cookie" && headerStr == "date" && headerStr == "delete" && headerStr == "etag" && headerStr == "expect" && headerStr == "get" && headerStr == "head" && headerStr == "host" && headerStr == "if-modified-since" && headerStr == "keep-alive" && headerStr == "last-modified" && headerStr == "location" && headerStr == "max-forwards" && headerStr == "options" && headerStr == "origin" && headerStr == "post" && headerStr == "proxy-authenticate" && headerStr == "proxy-authorization" && headerStr == "proxy-connection" && headerStr == "public" && headerStr == "put" && headerStr == "range" && headerStr == "referer" && headerStr == "request-range" && headerStr == "retry-after" && headerStr == "server" && headerStr == "te" && headerStr == "trace" && headerStr == "trailer" && headerStr == "transfer-encoding" && headerStr == "upgrade" && headerStr == "uri" && headerStr == "user-agent" && headerStr == "vary" && headerStr == "via" && headerStr == "warning" && headerStr == "www-authenticate" && headerStr == "x-flash-version") { LOG(LOG_INFO, _("SECURITY: DISALLOWED: Header is restricted")); return NA_HEADER; } //The URL has exactly the same domain name as the origin, always allowed if(url.getProtocol() == getSys()->mainClip->getOrigin().getProtocol() && url.getHostname() == getSys()->mainClip->getOrigin().getHostname()) { LOG(LOG_INFO, _("SECURITY: ALLOWED: Same hostname as origin")); return ALLOWED; } //Search for the policy files to check URLPFileList* files = searchURLPolicyFiles(url, loadPendingPolicies); RecMutex::Lock l(mutex); //Check the policy files if(files != NULL) { URLPFileListConstIt it = files->begin(); for(; it != files->end(); ++it) { if((*it)->allowsHTTPRequestHeaderFrom(getSys()->mainClip->getOrigin(), url, headerStrLower)) { LOG(LOG_INFO, _("SECURITY: ALLOWED: A policy file explicitly allowed the header")); delete files; return ALLOWED; } } } LOG(LOG_INFO, _("SECURITY: DISALLOWED: No policy file explicitly allowed the header")); delete files; return NA_CROSSDOMAIN_POLICY; } /** * \brief Constructor for PolicyFile * * PolicyFile is an abstract base class so this method can only be called from a derived class. * \param _url The URL where this policy file resides * \param _type The type of policy file (URL or SOCKET) */ PolicyFile::PolicyFile(URLInfo _url, TYPE _type): originalURL(_url),url(_url),type(_type),valid(false),ignore(false), loaded(false),siteControl(NULL) { } /** * \brief Destructor for PolicyFile. * * Can only be called from SecurityManager. * Waits for mutex before proceeding. * \see SecurityManager */ PolicyFile::~PolicyFile() { Mutex::Lock l(mutex); for(list::iterator i = allowAccessFrom.begin(); i != allowAccessFrom.end(); ++i) delete (*i); if (siteControl) delete siteControl; } /** * \brief Loads and parses a policy file * * Can only be called from within SecurityManager * Waits for mutex at start and releases mutex when finished * \see SecurityManager::loadURLPolicyFile() */ void PolicyFile::load() { //TODO: support download timeout handling //Invalid URLPolicyFile or already loaded, ignore this call if(!isValid() || isLoaded()) return; ignore = isIgnoredByMaster(); //Download the policy file vector policy; if (!isIgnored()) valid = retrievePolicyFile(policy); Mutex::Lock l(mutex); if (isLoaded()) { // Another thread already processed this PolicyFile // while we were downloading return; } //We only try loading once, if something goes wrong, valid will be set to 'invalid' loaded = true; //We've checked the master file to see of we need to ignore this file. (not the case) //Now let's parse this file. if(isValid() && !isIgnored()) { CrossDomainPolicy::POLICYFILETYPE parserType; CrossDomainPolicy::POLICYFILESUBTYPE parserSubtype; getParserType(parserType, parserSubtype); CrossDomainPolicy parser(&policy[0], policy.size(), parserType, parserSubtype, isMaster()); CrossDomainPolicy::ELEMENT elementType = parser.getNextElement(); while(elementType != CrossDomainPolicy::END && elementType != CrossDomainPolicy::INVALID) { handlePolicyElement(elementType, parser); //No more parsing is needed if this site-control entry specifies that //no policy files are allowed if (elementType == CrossDomainPolicy::SITE_CONTROL && isMaster() && getMetaPolicy() == PolicyFile::NONE) { break; } elementType = parser.getNextElement(); } //The last element was INVALID if(elementType == CrossDomainPolicy::INVALID) valid = false; if(isMaster()) { //Ignore this file if the site control policy is "none" if(getMetaPolicy() == PolicyFile::NONE) ignore = true; valid = checkSiteControlValidity(); } } else { valid = false; } } bool PolicyFile::checkSiteControlValidity() { return true; } void PolicyFile::handlePolicyElement(CrossDomainPolicy::ELEMENT& elementType, const CrossDomainPolicy& parser) { if(elementType == CrossDomainPolicy::SITE_CONTROL) { if (siteControl) { // From spec: If site-control is defined // multiple times, "none" takes preference. if (getMetaPolicy() == NONE) return; delete siteControl; siteControl = NULL; } siteControl = new PolicySiteControl(parser.getPermittedPolicies()); } else if(elementType == CrossDomainPolicy::ALLOW_ACCESS_FROM) { allowAccessFrom.push_back(new PolicyAllowAccessFrom(this, parser.getDomain(), parser.getToPorts(), parser.getSecure(), parser.getSecureSpecified())); } } PolicyFile::METAPOLICY PolicyFile::getMetaPolicy() { if (!isMaster()) { // Only the master can have site-control return PolicyFile::NONE; } else if (siteControl) { return siteControl->getPermittedPolicies(); } else if (isValid() && isLoaded()) { // Policy file is loaded but does not contain // site-control tag return PolicySiteControl::defaultSitePolicy(getType()); } else { // Policy file is invalid, deny everything return PolicyFile::NONE; } } /** * \brief Constructor for URLPolicyFile * * Can only be called from SecurityManager * \param _url The URL where this URL policy file resides * \see SecurityManager::addURLPolicyFile() */ URLPolicyFile::URLPolicyFile(const URLInfo& _url): PolicyFile(_url, URL) { if(url.isValid()) valid = true; if(url.getProtocol() == "http") subtype = HTTP; else if(url.getProtocol() == "https") subtype = HTTPS; else if(url.getProtocol() == "ftp") subtype = FTP; } /** * \brief Destructor for URLPolicyFile * * Can only be called from SecurityManager. * Waits for mutex at start and releases mutex when finished * \see SecurityManager */ URLPolicyFile::~URLPolicyFile() { Mutex::Lock l(mutex); for(list::iterator i = allowHTTPRequestHeadersFrom.begin(); i != allowHTTPRequestHeadersFrom.end(); ++i) delete (*i); } /** * \brief Gets the master URL policy file controlling this URL policy file * * Searches for the master policy file in the list of managed policy files. * If it isn't found, the master policy file gets added. * Waits for mutex at start and releases mutex when finished * \return The master policy file controlling this policy file. */ URLPolicyFile* URLPolicyFile::getMasterPolicyFile() { Mutex::Lock l(mutex); if(isMaster()) return this; URLPolicyFile* file = getSys()->securityManager->getURLPolicyFileByURL(url.goToURL("/crossdomain.xml")); if(file == NULL) file = getSys()->securityManager->addURLPolicyFile(url.goToURL("/crossdomain.xml")); return file; } /** * \brief Checks whether this URL policy file is a master policy file * * \return \c true if this policy file is a master policy file, otherwise \c false */ bool URLPolicyFile::isMaster() const { return url.getPath() == "/crossdomain.xml"; } bool URLPolicyFile::isIgnoredByMaster() { if(!isMaster()) { //Load master policy file if not loaded yet URLPolicyFile* master = getMasterPolicyFile(); getSys()->securityManager->loadURLPolicyFile(master); //Master policy file found and valid and has a site-control entry if(master->isValid()) { PolicyFile::METAPOLICY permittedPolicies = master->getMetaPolicy(); //For all types: master-only, none if(permittedPolicies == PolicyFile::MASTER_ONLY || permittedPolicies == PolicyFile::NONE) return true; //Only for FTP: by-ftp-filename else if(subtype == FTP && permittedPolicies == PolicyFile::BY_FTP_FILENAME && url.getPathFile() != "crossdomain.xml") return true; } } return false; } bool URLPolicyFile::retrievePolicyFile(vector& outData) { bool ok = true; //No caching needed for this download, we don't expect very big files Downloader* downloader=getSys()->downloadManager->download(url, false, NULL); //Wait until the file is fetched downloader->waitForTermination(); if(downloader->hasFailed()) ok = false; //If files are redirected, we use the new URL as the file's URL if(ok && downloader->isRedirected()) { URLInfo newURL(downloader->getURL()); if(url.getHostname() != newURL.getHostname()) { LOG(LOG_INFO, _("SECURITY: Policy file was redirected to other domain, marking invalid")); ok = false; } url = newURL; LOG(LOG_INFO, _("SECURITY: Policy file was redirected")); } //Policy files must have on of the following content-types to be valid: //text/*, application/xml or application/xhtml+xml tiny_string contentType = downloader->getHeader("content-type"); if(ok && (subtype == HTTP || subtype == HTTPS) && contentType.substr(0, 5) != "text/" && contentType != "application/xml" && contentType != "application/xhtml+xml") { LOG(LOG_INFO, _("SECURITY: Policy file has an invalid content-type, marking invalid")); ok = false; } //One more check from the master file: see if the content-type is OK //if site-control specifies by-content-type if(ok && !isMaster()) { //If the site-control policy of the master policy file is by-content-type, only policy files with //content-type = text/x-cross-domain-policy are allowed. URLPolicyFile* master = getMasterPolicyFile(); if(master->isValid() && (subtype == HTTP || subtype == HTTPS) && master->getMetaPolicy() == PolicyFile::BY_CONTENT_TYPE && contentType != "text/x-cross-domain-policy") { LOG(LOG_INFO, _("SECURITY: Policy file content-type isn't strict, marking invalid")); ignore = true; } } if (ok) { istream s(downloader); size_t bufLength = downloader->getLength(); size_t offset = outData.size(); outData.resize(offset+bufLength); s.read((char*)&outData[offset], bufLength); } getSys()->downloadManager->destroy(downloader); return ok; } void URLPolicyFile::getParserType(CrossDomainPolicy::POLICYFILETYPE& parserType, CrossDomainPolicy::POLICYFILESUBTYPE& parserSubtype) { parserType = CrossDomainPolicy::URL; parserSubtype = CrossDomainPolicy::NONE; if(subtype == HTTP) parserSubtype = CrossDomainPolicy::HTTP; else if(subtype == HTTPS) parserSubtype = CrossDomainPolicy::HTTPS; else if(subtype == FTP) parserSubtype = CrossDomainPolicy::FTP; } bool URLPolicyFile::checkSiteControlValidity() { //by-ftp-filename only applies to FTP if((subtype == HTTP || subtype == HTTPS) && getMetaPolicy() == PolicyFile::BY_FTP_FILENAME) return false; //by-content-type only applies to HTTP(S) else if(subtype == FTP && getMetaPolicy() == PolicyFile::BY_CONTENT_TYPE) return false; return true; } /** * \brief Checks whether this policy file allows the given URL access * * \param requestingUrl The URL (of the SWF file) that is requesting the data * \param to The URL that is being requested by a resource at \c requestingUrl * \return \c true if allowed, otherwise \c false */ bool URLPolicyFile::allowsAccessFrom(const URLInfo& requestingUrl, const URLInfo& to) { //File must be loaded if(!isLoaded()) return false; //This policy file doesn't apply to the given URL if(!isMaster() && !to.isSubOf(url)) return false; //Check if the file is invalid or ignored if(!isValid() || isIgnored()) return false; list::const_iterator i = allowAccessFrom.begin(); for(; i != allowAccessFrom.end(); ++i) { //This allow-access-from entry applies to our domain AND it allows our domain if((*i)->allowsAccessFrom(requestingUrl)) return true; } return false; } /** * \brief Checks whether this policy file allowed the given URL to send a given request header * * \param url The URL to check if it is allowed by the policy file to send the given header * \param to The URL of the request to which the request header belongs * \param header The request header which needs to be checked if it is allowed * \return \c true if allowed, otherwise \c false */ bool URLPolicyFile::allowsHTTPRequestHeaderFrom(const URLInfo& url, const URLInfo& to, const string& header) { //File must be loaded if(!isLoaded()) return false; //Only used for HTTP(S) if(subtype != HTTP && subtype != HTTPS) return false; //This policy file doesn't apply to the given URL if(!isMaster() && !to.isSubOf(url)) return false; //Check if the file is invalid or ignored if(!isValid() || isIgnored()) return false; list::const_iterator i = allowHTTPRequestHeadersFrom.begin(); for(; i != allowHTTPRequestHeadersFrom.end(); ++i) { if((*i)->allowsHTTPRequestHeaderFrom(url, header)) return true; } return false; } void URLPolicyFile::handlePolicyElement(CrossDomainPolicy::ELEMENT& elementType, const CrossDomainPolicy& parser) { PolicyFile::handlePolicyElement(elementType, parser); if (elementType == CrossDomainPolicy::ALLOW_HTTP_REQUEST_HEADERS_FROM) { allowHTTPRequestHeadersFrom.push_back( new PolicyAllowHTTPRequestHeadersFrom(this, parser.getDomain(), parser.getHeaders(), parser.getSecure(), parser.getSecureSpecified())); } } /** * \brief Constructor for SocketPolicyFile * * Can only be called from SecurityManager * \param _url The URL where this socket policy file resides */ SocketPolicyFile::SocketPolicyFile(const URLInfo& _url): PolicyFile(_url, SOCKET) { if(url.isValid()) valid = true; } /** * \brief Checks whether this policy file allows the given URL access * * \param requestingUrl The URL (of the SWF file) that is requesting the data * \param to The URL that is being requested by a resource at \c requestingUrl * \return \c true if allowed, otherwise \c false */ bool SocketPolicyFile::allowsAccessFrom(const URLInfo& requestingUrl, const URLInfo& to) { //File must be loaded if(!isLoaded()) return false; //Check if the file is invalid or ignored if(!isValid() || isIgnored()) return false; list::const_iterator i = allowAccessFrom.begin(); for(; i != allowAccessFrom.end(); ++i) { //This allow-access-from entry applies to our domain AND it allows our domain if((*i)->allowsAccessFrom(requestingUrl, to.getPort())) return true; } return false; } /** * \brief Checks whether this socket policy file is a master policy file * * \return \c true if this policy file is a master policy file, otherwise \c false */ bool SocketPolicyFile::isMaster() const { return url.getPort() == MASTER_PORT; } SocketPolicyFile* SocketPolicyFile::getMasterPolicyFile() { Mutex::Lock l(mutex); if(isMaster()) return this; URLInfo masterurl = url.goToURL(MASTER_PORT_URL); SocketPolicyFile* file = getSys()->securityManager->getSocketPolicyFileByURL(masterurl); if(file == NULL) file = getSys()->securityManager->addSocketPolicyFile(masterurl); return file; } bool SocketPolicyFile::isIgnoredByMaster() { //Check if this file is allowed/ignored by the master policy file if(!isMaster()) { //Load master policy file if not loaded yet SocketPolicyFile* master = getMasterPolicyFile(); getSys()->securityManager->loadSocketPolicyFile(master); //Master policy file found and valid and has a site-control entry if(master->isValid()) { PolicyFile::METAPOLICY permittedPolicies = master->getMetaPolicy(); if(permittedPolicies == PolicyFile::MASTER_ONLY || permittedPolicies == PolicyFile::NONE) return true; } } return false; } /** * \brief Download the content of the policy file * * \param url Location of the policy file to load * \param outData Policy file content will be inserted in here * \return \c true if policy file was downloaded without errors, otherwise \c false (content of outData will be undefined) */ bool SocketPolicyFile::retrievePolicyFile(vector& outData) { tiny_string hostname = url.getHostname(); uint16_t port = url.getPort(); SocketIO sock; if (!sock.connect(hostname, port)) { if (isMaster()) { //It's legal not to have a master socket policy. //We still check the other policy files. LOG(LOG_INFO, _("SECURITY: Master socket policy file not available, using default policy")); const char *default_policy = ""; unsigned int len = strlen(default_policy); outData.insert(outData.end(), default_policy, default_policy+len); return true; } else return false; } const char *socket_policy_cmd = "\0"; unsigned int socket_policy_cmd_len = strlen(socket_policy_cmd)+1; ssize_t nbytes = sock.sendAll(socket_policy_cmd, socket_policy_cmd_len); if (nbytes != socket_policy_cmd_len) { return false; } nbytes = 0; do { char buf[4096]; nbytes = sock.receive(buf, sizeof buf); outData.insert(outData.end(), buf, buf + nbytes); } while (nbytes > 0); if (nbytes < 0) { // error reading from socket return false; } // The policy file is considered invalid if the last character // is not '\0' if (outData.size() == 0 || outData[outData.size()-1] != '\0') { return false; } // Ignore the null terminator outData.resize(outData.size()-1); return true; } void SocketPolicyFile::getParserType(CrossDomainPolicy::POLICYFILETYPE& parserType, CrossDomainPolicy::POLICYFILESUBTYPE& parserSubtype) { parserType = CrossDomainPolicy::SOCKET; parserSubtype = CrossDomainPolicy::NONE; } /** * \brief Constructor for the PolicySiteControl class * * Can only be called from within PolicyFile. * \param _file The policy file this entry belongs to * \param _permittedPolicies The value of the permitted-cross-domain-policies attribute. * \see URLPolicyFile::load() */ PolicySiteControl::PolicySiteControl(const string _permittedPolicies) { if(_permittedPolicies == "all") permittedPolicies = PolicyFile::ALL; else if(_permittedPolicies == "by-content-type") permittedPolicies = PolicyFile::BY_CONTENT_TYPE; else if(_permittedPolicies == "by-ftp-filename") permittedPolicies = PolicyFile::BY_FTP_FILENAME; else if(_permittedPolicies == "master-only") permittedPolicies = PolicyFile::MASTER_ONLY; else if(_permittedPolicies == "none") permittedPolicies = PolicyFile::NONE; else { LOG(LOG_ERROR, _("SECURITY: Unknown site-policy value: ") << _permittedPolicies); permittedPolicies = PolicyFile::NONE; } } PolicyFile::METAPOLICY PolicySiteControl::defaultSitePolicy(PolicyFile::TYPE policyFileType) { if (policyFileType == PolicyFile::SOCKET) return PolicyFile::ALL; else return PolicyFile::MASTER_ONLY; } /** * \brief Constructor for the PolicyAllowAccessFrom class * * Can only be called from within PolicyFile. * \param _file The policy file this entry belongs to * \param _domain The value of the domain attribute * \param _toPorts The value of the to-ports attribute * \param _secure The value of the secure attribute * \param secureSpecified Whether or not the secure attribute was present * \see URLPolicyFile::load() */ PolicyAllowAccessFrom::PolicyAllowAccessFrom(PolicyFile* _file, const string _domain, const string _toPorts, bool _secure, bool secureSpecified): file(_file),domain(_domain),secure(_secure) { if(!secureSpecified) { if(file->getType() == PolicyFile::URL && dynamic_cast(file)->getSubtype() == URLPolicyFile::HTTPS) secure = true; if(file->getType() == PolicyFile::SOCKET) secure = false; } //Set the default value if(_toPorts.length() == 0 || _toPorts == "*") toPorts.push_back(new PortRange(0, 0, false, true)); else { string ports = _toPorts; size_t cursor = 0; size_t commaPos; size_t dashPos; string startPortStr; string endPortStr; uint16_t startPort; uint16_t endPort; do { commaPos = ports.find(",", cursor); dashPos = ports.find("-", commaPos); if(dashPos != string::npos) { startPortStr = ports.substr(cursor, dashPos-cursor); if(startPortStr == "*") { toPorts.push_back(new PortRange(0, 0, false, true)); break; } startPort = atoi(startPortStr.c_str()); if(ports.length() < dashPos+1) { endPortStr = ports.substr(dashPos+1, commaPos-(dashPos+1)); endPort = atoi(endPortStr.c_str()); toPorts.push_back(new PortRange(startPort, endPort, true)); } else toPorts.push_back(new PortRange(startPort)); } else { startPortStr = ports.substr(cursor, commaPos-cursor); if(startPortStr == "*") { toPorts.push_back(new PortRange(0, 0, false, true)); break; } startPort = atoi(startPortStr.c_str()); toPorts.push_back(new PortRange(startPort)); } cursor = commaPos+1; } while(commaPos != string::npos); } } /** * \brief Destructor for the PolicyAllowsAccessFrom class * * Can only be called from within PolicyFile. * \see PolicyFile */ PolicyAllowAccessFrom::~PolicyAllowAccessFrom() { for(list::iterator i = toPorts.begin(); i != toPorts.end(); ++i) delete (*i); toPorts.clear(); } /** * \brief Checks if the entry allows access from the given URL * * \param url The URL to check this entry against * \return \c true if this entry allows the given URL access, otherwise \c false */ bool PolicyAllowAccessFrom::allowsAccessFrom(const URLInfo& url, uint16_t toPort) const { //TODO: resolve domain names using DNS before checking for a match? //See section 1.5.9 in specification //Check if domains match if(!URLInfo::matchesDomain(domain, url.getHostname())) return false; //Check if the requesting URL is secure, if needed if(file->getType() == PolicyFile::URL && dynamic_cast(file)->getSubtype() == URLPolicyFile::HTTPS && secure && url.getProtocol() != "https") return false; if(file->getType() == PolicyFile::SOCKET && secure && url.getProtocol() != "https") return false; //Check for to-ports (only applies to SOCKET connections) if(file->getType() == PolicyFile::SOCKET) { // toPort should always be specified for sockets if (toPort == 0) return false; bool match = false; std::list::const_iterator it; for (it=toPorts.begin(); it!=toPorts.end(); ++it) { if ((*it)->matches(toPort)) { match = true; break; } } if (!match) return false; } return true; } /** * \brief Constructor for the PolicyAllowHTTPRequestHeadersFrom class * * Can only be called from within PolicyFile. * \param _file The policy file this entry belongs to * \param _domain The value of the domain attribute * \param _headers The value of the header attribute * \param _secure The value of the secure attribute * \param secureSpecified Whether or not the secure attribute was present * \see URLPolicyFile::load() */ PolicyAllowHTTPRequestHeadersFrom::PolicyAllowHTTPRequestHeadersFrom(URLPolicyFile* _file, const string _domain, const string _headers, bool _secure, bool secureSpecified): file(_file),domain(_domain),secure(_secure) { if(!secureSpecified && file->getSubtype() == URLPolicyFile::HTTPS) secure = true; //Socket policy files don't use http-request-headers-from if((_file->getType()==PolicyFile::SOCKET) || _headers.length() == 0 || _headers == "*") headers.push_back(new string("*")); else { string headersStr = _headers; size_t cursor = 0; size_t commaPos; do { commaPos = headersStr.find(",", cursor); headers.push_back(new string(headersStr.substr(cursor, commaPos-cursor))); cursor = commaPos+1; } while(commaPos != string::npos); } } /** * \brief Destructor for the PolicyAllowHTTPRequestHeadersFrom class * * Can only be called from within PolicyFile. * \see PolicyFile */ PolicyAllowHTTPRequestHeadersFrom::~PolicyAllowHTTPRequestHeadersFrom() { for(list::iterator i = headers.begin(); i != headers.end(); ++i) delete (*i); headers.clear(); } /** * \brief Checks if the entry allows a given request header from a given URL * * \param url The URL to check this entry against * \param header The header to check this entry against * \return \c true if this entry allows the given URL to send the given request header, otherwise \c false */ bool PolicyAllowHTTPRequestHeadersFrom::allowsHTTPRequestHeaderFrom(const URLInfo& url, const string& header) const { if(file->getSubtype() != URLPolicyFile::HTTP && file->getSubtype() != URLPolicyFile::HTTPS) return false; //Check if domains match if(!URLInfo::matchesDomain(domain, url.getHostname())) return false; //Check if the requesting URL is secure, if needed if(file->getSubtype() == URLPolicyFile::HTTPS && secure && url.getProtocol() != "https") return false; //Check if the header is explicitly allowed bool headerFound = false; string expression; for(list::const_iterator i = headers.begin(); i != headers.end(); ++i) { expression = (**i); transform(expression.begin(), expression.end(), expression.begin(), ::tolower); if(expression == header || expression == "*") { headerFound = true; break; } //Match suffix wildcards else if(expression[expression.length()-1] == '*' && header.substr(0, expression.length()-1) == expression.substr(0, expression.length()-1)) { headerFound = true; break; } } if(!headerFound) return false; return true; } lightspark-0.7.2/src/backends/security.h000066400000000000000000000363641212105246600202640ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2010-2011 Timon Van Overveldt (timonvo@gmail.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_SECURITY_H #define BACKENDS_SECURITY_H 1 #include "compat.h" #include #include #include #include #include "swftypes.h" #include "threading.h" #include "urlutils.h" #include "parsing/crossdomainpolicy.h" namespace lightspark { class PolicyFile; class URLPolicyFile; class SocketPolicyFile; typedef std::list URLPFileList; typedef std::list::iterator URLPFileListIt; typedef std::list::const_iterator URLPFileListConstIt; typedef std::pair URLPFilePair; typedef std::multimap URLPFileMap; typedef std::multimap::iterator URLPFileMapIt; typedef std::multimap::const_iterator URLPFileMapConstIt; typedef std::pair URLPFileMapItPair; typedef std::pair URLPFileMapConstItPair; typedef std::list SocketPFileList; typedef std::list::const_iterator SocketPFileListConstIt; typedef std::pair SocketPFilePair; typedef std::multimap SocketPFileMap; class SecurityManager { public: enum SANDBOXTYPE { REMOTE=1, LOCAL_WITH_FILE=2, LOCAL_WITH_NETWORK=4, LOCAL_TRUSTED=8 }; private: RecMutex mutex; const char* sandboxNames[4]; const char* sandboxTitles[4]; //Multimap (by domain) of pending policy files URLPFileMap pendingURLPFiles; //Multimap (by domain) of loaded policy files URLPFileMap loadedURLPFiles; //Multimap (by domain) of pending socket policy files SocketPFileMap pendingSocketPFiles; //Multimap (by domain) of loaded socket policy files SocketPFileMap loadedSocketPFiles; //Security sandbox type SANDBOXTYPE sandboxType; //Use exact domains for player settings bool exactSettings; //True if exactSettings was already set once bool exactSettingsLocked; template void loadPolicyFile(std::multimap& pendingFiles, std::multimap& loadedFiles, PolicyFile *file); template T* getPolicyFileByURL(std::multimap& pendingFiles, std::multimap& loadedFiles, const URLInfo& url); template std::list *searchPolicyFiles(const URLInfo& url, T *master, bool loadPendingPolicies, std::multimap& pendingFiles, std::multimap& loadedFiles); //Search for and loads (if allowed) policy files which should be checked //(used by evaluatePoliciesURL & evaluateHeader) //Master policy file is first-in-line and should be checked first URLPFileList* searchURLPolicyFiles(const URLInfo& url, bool loadPendingPolicies); SocketPFileList* searchSocketPolicyFiles(const URLInfo& url, bool loadPendingPolicies); public: SecurityManager(); ~SecurityManager(); //Add a policy file located at url, will decide what type of policy file it is. PolicyFile* addPolicyFile(const tiny_string& url) { return addPolicyFile(URLInfo(url)); } PolicyFile* addPolicyFile(const URLInfo& url); //Add an URL policy file located at url URLPolicyFile* addURLPolicyFile(const URLInfo& url); //Add a Socket policy file located at url SocketPolicyFile* addSocketPolicyFile(const URLInfo& url); //Get the URL policy file object (if any) for the URL policy file at url URLPolicyFile* getURLPolicyFileByURL(const URLInfo& url); SocketPolicyFile* getSocketPolicyFileByURL(const URLInfo& url); void loadURLPolicyFile(URLPolicyFile* file); void loadSocketPolicyFile(SocketPolicyFile* file); //Set the sandbox type void setSandboxType(SANDBOXTYPE type) { sandboxType = type; } SANDBOXTYPE getSandboxType() const { return sandboxType; } const char* getSandboxName() const { return getSandboxName(sandboxType); } const char* getSandboxName(SANDBOXTYPE type) const { if(type == REMOTE) return sandboxNames[0]; else if(type == LOCAL_WITH_FILE) return sandboxNames[1]; else if(type == LOCAL_WITH_NETWORK) return sandboxNames[2]; else if(type == LOCAL_TRUSTED) return sandboxNames[3]; return NULL; } const char* getSandboxTitle() const { return getSandboxTitle(sandboxType); } const char* getSandboxTitle(SANDBOXTYPE type) const { if(type == REMOTE) return sandboxTitles[0]; else if(type == LOCAL_WITH_FILE) return sandboxTitles[1]; else if(type == LOCAL_WITH_NETWORK) return sandboxTitles[2]; else if(type == LOCAL_TRUSTED) return sandboxTitles[3]; return NULL; } //Set exactSettings void setExactSettings(bool settings, bool locked=true) { if(!exactSettingsLocked) { exactSettings = settings; exactSettingsLocked = locked; } } bool getExactSettings() const { return exactSettings; } bool getExactSettingsLocked() const { return exactSettingsLocked; } //Evaluates whether the current sandbox is in the allowed sandboxes bool evaluateSandbox(int allowedSandboxes) { return evaluateSandbox(sandboxType, allowedSandboxes); } bool evaluateSandbox(SANDBOXTYPE sandbox, int allowedSandboxes); //The possible results for the URL evaluation methods below enum EVALUATIONRESULT { ALLOWED, NA_RESTRICT_LOCAL_DIRECTORY, NA_REMOTE_SANDBOX, NA_LOCAL_SANDBOX, NA_CROSSDOMAIN_POLICY, NA_PORT, NA_HEADER }; //Evaluates an URL by checking allowed sandboxes (URL policy files are not checked) EVALUATIONRESULT evaluateURLStatic(const tiny_string& url, int allowedSandboxesRemote, int allowedSandboxesLocal, bool restrictLocalDirectory) { return evaluateURLStatic(URLInfo(url), allowedSandboxesRemote, allowedSandboxesLocal); } EVALUATIONRESULT evaluateURLStatic(const URLInfo& url, int allowedSandboxesRemote, int allowedSandboxesLocal, bool restrictLocalDirectory=true); static void checkURLStaticAndThrow(const URLInfo& url, int allowedSandboxesRemote, int allowedSandboxesLocal, bool restrictLocalDirectory=true); //Evaluates an URL by checking if the type of URL (local/remote) matches the allowed sandboxes EVALUATIONRESULT evaluateSandboxURL(const URLInfo& url, int allowedSandboxesRemote, int allowedSandboxesLocal); //Checks for restricted ports EVALUATIONRESULT evaluatePortURL(const URLInfo& url); //Evaluates a (local) URL by checking if it points to a subdirectory of the origin EVALUATIONRESULT evaluateLocalDirectoryURL(const URLInfo& url); //Checks URL policy files EVALUATIONRESULT evaluatePoliciesURL(const URLInfo& url, bool loadPendingPolicies); //Check socket policy files EVALUATIONRESULT evaluateSocketConnection(const URLInfo& url, bool loadPendingPolicies); //Check for restricted headers and policy files explicitly allowing certain headers EVALUATIONRESULT evaluateHeader(const tiny_string& url, const tiny_string& header, bool loadPendingPolicies) { return evaluateHeader(URLInfo(url), header, loadPendingPolicies); } EVALUATIONRESULT evaluateHeader(const URLInfo& url, const tiny_string& header, bool loadPendingPolicies); }; class PolicySiteControl; class PolicyAllowAccessFrom; class PolicyAllowHTTPRequestHeadersFrom; class PolicyFile { friend class SecurityManager; public: enum TYPE { URL, SOCKET }; enum METAPOLICY { ALL, //All types of policy files are allowed (default for SOCKET) BY_CONTENT_TYPE, //Only policy files served with 'Content-Type: text/x-cross-domain-policy' are allowed (only for HTTP) BY_FTP_FILENAME, //Only policy files with 'crossdomain.xml' as filename are allowed (only for FTP) MASTER_ONLY, //Only this master policy file is allowed (default for HTTP/HTTPS/FTP) NONE, //No policy files are allowed, including this master policy file NONE_THIS_RESPONSE //Don't use this policy file, provided as a HTTP header only (TODO: support this type) }; private: URLInfo originalURL; protected: PolicyFile(URLInfo _url, TYPE _type); virtual ~PolicyFile(); Mutex mutex; URLInfo url; TYPE type; //Is this PolicyFile object valid? //Reason for invalidness can be: incorrect URL, download failed (in case of URLPolicyFiles) bool valid; //Ignore this object? //Reason for ignoring can be: master policy file doesn't allow other/any policy files bool ignore; //Is this file loaded and parsed yet? bool loaded; //Load and parse the policy file void load(); //Return true, if master policy file tells to ignore this file virtual bool isIgnoredByMaster()=0; //Download polic file content from url into policy. //Return true, if file was downloaded successfully and is valid. virtual bool retrievePolicyFile(std::vector& policy)=0; //Return parser parameters required to handle this policy file virtual void getParserType(CrossDomainPolicy::POLICYFILETYPE&, CrossDomainPolicy::POLICYFILESUBTYPE&)=0; //Return false if siteControl is invalid virtual bool checkSiteControlValidity(); //Process one element from the policy file virtual void handlePolicyElement(CrossDomainPolicy::ELEMENT& elementType, const CrossDomainPolicy& parser); PolicySiteControl* siteControl; std::list allowAccessFrom; public: const URLInfo& getURL() const { return url; } const URLInfo& getOriginalURL() const { return originalURL; } TYPE getType() const { return type; } bool isValid() const { return valid; } bool isIgnored() const { return ignore; } virtual bool isMaster() const = 0; bool isLoaded() const { return loaded; } //Get the master policy file controlling this one //virtual PolicyFile* getMasterPolicyFile()=0; METAPOLICY getMetaPolicy(); //Is access to the policy file URL allowed by this policy file? virtual bool allowsAccessFrom(const URLInfo& url, const URLInfo& to) = 0; }; class URLPolicyFile : public PolicyFile { friend class SecurityManager; public: enum SUBTYPE { HTTP, HTTPS, FTP }; private: SUBTYPE subtype; std::list allowHTTPRequestHeadersFrom; protected: URLPolicyFile(const URLInfo& _url); ~URLPolicyFile(); //Load and parse the policy file bool isIgnoredByMaster(); bool retrievePolicyFile(std::vector& policy); void getParserType(CrossDomainPolicy::POLICYFILETYPE&, CrossDomainPolicy::POLICYFILESUBTYPE&); bool checkSiteControlValidity(); void handlePolicyElement(CrossDomainPolicy::ELEMENT& elementType, const CrossDomainPolicy& parser); public: SUBTYPE getSubtype() const { return subtype; } //If strict is true, the policy will be loaded first to see if it isn't redirected bool isMaster() const; //Get the master policy file controlling this one URLPolicyFile* getMasterPolicyFile(); //Is access to the policy file URL allowed by this policy file? bool allowsAccessFrom(const URLInfo& url, const URLInfo& to); //Is this request header allowed by this policy file for the given URL? bool allowsHTTPRequestHeaderFrom(const URLInfo& u, const URLInfo& to, const std::string& header); }; class SocketPolicyFile : public PolicyFile { friend class SecurityManager; protected: SocketPolicyFile(const URLInfo& _url); bool isIgnoredByMaster(); bool retrievePolicyFile(std::vector& outData); void getParserType(CrossDomainPolicy::POLICYFILETYPE&, CrossDomainPolicy::POLICYFILESUBTYPE&); public: static const unsigned int MASTER_PORT; static const char *MASTER_PORT_URL; //If strict is true, the policy will be loaded first to see if it isn't redirected bool isMaster() const; //Get the master policy file controlling this one SocketPolicyFile* getMasterPolicyFile(); //Is access to the policy file URL allowed by this policy file? bool allowsAccessFrom(const URLInfo& url, const URLInfo& to); }; //Site-wide declarations for master policy file //Only valid inside master policy files class PolicySiteControl { private: PolicyFile::METAPOLICY permittedPolicies; //Required public: PolicySiteControl(const std::string _permittedPolicies); PolicyFile::METAPOLICY getPermittedPolicies() const { return permittedPolicies; } static PolicyFile::METAPOLICY defaultSitePolicy(PolicyFile::TYPE policyFileType); }; class PortRange { private: uint16_t startPort; uint16_t endPort; bool isRange; bool matchAll; public: PortRange(uint16_t _startPort, uint16_t _endPort=0, bool _isRange=false, bool _matchAll=false): startPort(_startPort),endPort(_endPort),isRange(_isRange),matchAll(_matchAll){}; bool matches(uint16_t port) { if(matchAll) return true; if(isRange) { return startPort >= port && endPort <= port; } else return startPort == port; } }; //Permit access by documents from specified domains class PolicyAllowAccessFrom { friend class PolicyFile; friend class URLPolicyFile; friend class SocketPolicyFile; private: PolicyFile* file; std::string domain; //Required std::list toPorts; //Only used for SOCKET policy files, required bool secure; //Only used for SOCKET & HTTPS, optional, default: SOCKET=false, HTTPS=true protected: PolicyAllowAccessFrom(PolicyFile* _file, const std::string _domain, const std::string _toPorts, bool _secure, bool secureSpecified); ~PolicyAllowAccessFrom(); public: const std::string& getDomain() const { return domain; } size_t getToPortsLength() const { return toPorts.size(); } std::list::const_iterator getToPortsBegin() const { return toPorts.begin(); } std::list::const_iterator getToPortsEnd() const { return toPorts.end(); } bool getSecure() const { return secure; } //Does this entry allow a given URL? bool allowsAccessFrom(const URLInfo& url, uint16_t toPort=0) const; }; //Permit HTTP request header sending (only for HTTP) class PolicyAllowHTTPRequestHeadersFrom { friend class PolicyFile; friend class URLPolicyFile; private: URLPolicyFile* file; std::string domain; //Required std::list headers; //Required bool secure; //Only used for HTTPS, optional, default=true protected: PolicyAllowHTTPRequestHeadersFrom(URLPolicyFile* _file, const std::string _domain, const std::string _headers, bool _secure, bool secureSpecified); ~PolicyAllowHTTPRequestHeadersFrom(); public: const std::string getDomain() const { return domain; } size_t getHeadersLength() const { return headers.size(); } std::list::const_iterator getHeadersBegin() const { return headers.begin(); } std::list::const_iterator getHeadersEnd() const { return headers.end(); } bool getSecure() const { return secure; } //Does this entry allow a given request header for a given URL? bool allowsHTTPRequestHeaderFrom(const URLInfo& url, const std::string& header) const; }; } #endif /* BACKENDS_SECURITY_H */ lightspark-0.7.2/src/backends/urlutils.cpp000066400000000000000000000332711212105246600206250ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2010-2011 Timon Van Overveldt (timonvo@gmail.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "swf.h" #include "backends/urlutils.h" #include "compat.h" #include "scripting/toplevel/Integer.h" #include #include #include #include #include #include using namespace lightspark; std::ostream& lightspark::operator<<(std::ostream& s, const URLInfo& u) { s << u.getParsedURL(); return s; } URLInfo::URLInfo(const tiny_string& u) { url = u; std::string str = std::string(url.raw_buf()); valid = false; //Check for :// marking that there is a protocol in this url size_t colonPos = str.find("://"); if(colonPos == std::string::npos) invalidReason = MISSING_PROTOCOL; std::string protocolStr = str.substr(0, colonPos); std::transform(protocolStr.begin(), protocolStr.end(), protocolStr.begin(), ::tolower); protocol = protocolStr; size_t hostnamePos = colonPos+3; size_t portPos = std::string::npos; size_t pathPos = std::string::npos; size_t queryPos = std::string::npos; size_t fragmentPos = std::string::npos; size_t cursor = hostnamePos; if(protocol == "file") { pathPos = cursor; if(pathPos == str.length()) invalidReason = MISSING_PATH; } else { //URLEncode spaces by default. This is just a safety check. //Full encoding should be performed BEFORE passing the url to URLInfo url = encode(u, ENCODE_SPACES); pathPos = str.find("/", cursor); cursor = pathPos; portPos = str.rfind(":", cursor); if(portPos < hostnamePos) portPos = std::string::npos; queryPos = str.find("?", cursor); if(queryPos != std::string::npos) cursor = queryPos; fragmentPos = str.find("#", cursor); if(portPos == hostnamePos || pathPos == hostnamePos || queryPos == hostnamePos) invalidReason = MISSING_HOSTNAME; //Rebuild the work string using the escaped url str = std::string(url.raw_buf()); } //Parse the host string std::string hostnameStr = str.substr(hostnamePos, std::min(std::min(pathPos, portPos), queryPos)-hostnamePos); std::transform(hostnameStr.begin(), hostnameStr.end(), hostnameStr.begin(), ::tolower); hostname = hostnameStr; port = 0; //Check if the port after ':' is not empty if(portPos != std::string::npos && portPos != std::min(std::min(str.length()-1, pathPos-1), queryPos-1)) { portPos++; std::istringstream i(str.substr(portPos, std::min(pathPos, str.length())-portPos)); if(!(i >> port)) invalidReason = INVALID_PORT; } //Parse the path string if(pathPos != std::string::npos) { std::string pathStr = str.substr(pathPos, std::min(str.length(), queryPos)-pathPos); path = tiny_string(pathStr); path = normalizePath(path); pathStr = std::string(path.raw_buf()); size_t lastSlash = pathStr.rfind("/"); if(lastSlash != std::string::npos) { pathDirectory = pathStr.substr(0, lastSlash+1); pathFile = pathStr.substr(lastSlash+1); } //We only get here when parsing a file://abc URL else { pathDirectory = ""; pathFile = path; } } else { path = "/"; pathDirectory = path; pathFile = ""; } //Copy the query string if(queryPos != std::string::npos && queryPos < str.length()-1) query = str.substr(queryPos+1); else query = ""; //Copy the query string if(fragmentPos != std::string::npos && fragmentPos < str.length()-1) fragment = str.substr(fragmentPos+1); else fragment = ""; //Create a new normalized and encoded string representation parsedURL = getProtocol(); parsedURL += "://"; parsedURL += getHostname(); if(getPort() > 0) { parsedURL += ":"; parsedURL += Integer::toString(getPort()); } parsedURL += getPath(); if(query != "") { parsedURL += "?"; parsedURL += getQuery(); } if(fragment != "") { parsedURL += "#"; parsedURL += getFragment(); } valid = true; } tiny_string URLInfo::normalizePath(const tiny_string& u) { std::string pathStr(u.raw_buf()); //Remove double slashes size_t doubleSlash = pathStr.find("//"); while(doubleSlash != std::string::npos) { pathStr.replace(doubleSlash, 2, "/"); doubleSlash = pathStr.find("//"); } //Parse all /../ size_t doubleDot = pathStr.find("/../"); size_t previousSlash; while(doubleDot != std::string::npos) { //We are at root, .. doesn't mean anything, just erase if(doubleDot == 0) { pathStr.replace(doubleDot, 3, ""); } //Replace .. with one dir up else { previousSlash = pathStr.rfind("/", doubleDot-2); pathStr.replace(previousSlash, doubleDot-previousSlash+3, ""); } doubleDot = pathStr.find("/../"); } //Replace last /.. with one dir up if(pathStr.length() >= 3 && pathStr.substr(pathStr.length()-3, 3) == "/..") { previousSlash = pathStr.rfind("/", pathStr.length()-4); pathStr.replace(previousSlash, pathStr.length()-previousSlash+2, "/"); } //Eliminate meaningless /./ size_t singleDot = pathStr.find("/./"); while(singleDot != std::string::npos) { pathStr.replace(singleDot, 2, ""); singleDot = pathStr.find("/./"); } //Remove redundant last dot if(pathStr.length() >= 2 && pathStr.substr(pathStr.length()-2, 2) == "/.") pathStr.replace(pathStr.length()-1, 1, ""); if(pathStr.length() == 1 && pathStr[pathStr.length()-1] == '.') pathStr.replace(pathStr.length()-1, 1, ""); return tiny_string(pathStr); } const URLInfo URLInfo::goToURL(const tiny_string& u) const { std::string str = u.raw_buf(); // absolute URL without protocol, add current protocol if(str.find("//") == 0) { tiny_string s; s = getProtocol()+":"+str; return URLInfo(s); } //No protocol or hostname but has port, add protocol and hostname if(str.size() >= 2 && str[0] == ':' && str[1] >= '0' && str[1] <= '9') { tiny_string qualified; qualified = getProtocol(); qualified += "://"; qualified += getHostname(); qualified += str; return URLInfo(qualified); } //No protocol, treat this as an unqualified URL if(str.find("://") == std::string::npos) { tiny_string qualified; qualified = getProtocol(); qualified += "://"; qualified += getHostname(); if(getPort() > 0) { qualified += ":"; qualified += Integer::toString(getPort()); } if(str[0] != '/') qualified += getPathDirectory(); qualified += str; return URLInfo(qualified); } else //Protocol specified, treat this as a qualified URL return URLInfo(u); } bool URLInfo::isSubOf(const URLInfo& url) const { //Check if the beginning of the new pathDirectory equals the old pathDirectory if(getProtocol() != url.getProtocol()) return false; else if(getHostname() != url.getHostname()) return false; else if(!isSubPathOf(url)) return false; else return true; } bool URLInfo::isSubPathOf(const tiny_string& parent, const tiny_string& child) { return child.substr(0, parent.numChars()) == parent; } bool URLInfo::isSubDomainOf(const tiny_string& parent, const tiny_string& child) { std::string parentStr = std::string(parent.raw_buf()); std::transform(parentStr.begin(), parentStr.end(), parentStr.begin(), ::tolower); std::string childStr = std::string(child.raw_buf()); std::transform(childStr.begin(), childStr.end(), childStr.begin(), ::tolower); return childStr.substr(0, parentStr.length()) == parentStr; } bool URLInfo::matchesDomain(const tiny_string& expression, const tiny_string& subject) { std::string expressionStr = std::string(expression.raw_buf()); std::transform(expressionStr.begin(), expressionStr.end(), expressionStr.begin(), ::tolower); std::string subjectStr = std::string(subject.raw_buf()); std::transform(subjectStr.begin(), subjectStr.end(), subjectStr.begin(), ::tolower); //'*' matches everything if(expressionStr == "*" || expressionStr == subjectStr) return true; //'*.somedomain.tld' matches 'somedomain.tld' and every subdomain of 'somedomain.tld' else if(expressionStr.substr(0,2) == "*.") { //Check if subjectStr == 'somedomain.tld' if(subjectStr == expressionStr.substr(2, expressionStr.length()-2)) return true; //Check if subjectStr == 'somesubdomain.somedomain.tld' else if(subjectStr.length() >= expressionStr.length() && subjectStr.substr(subjectStr.length()-expressionStr.length()+1, expressionStr.length()-1) == expressionStr.substr(1, expressionStr.length()-1)) return true; } //No positive matches found, so return false return false; } bool URLInfo::sameHost(const URLInfo& other) const { return protocol == other.protocol && hostname == other.hostname && port == other.port; } tiny_string URLInfo::encode(const tiny_string& u, ENCODING type) { tiny_string str; char buf[7]; for(auto i=u.begin();i!=u.end();++i) { if(type == ENCODE_SPACES) { if(*i == ' ') str += "%20"; else str += *i; } else { //A-Z, a-z or 0-9, all encoding types except encode spaces don't encode these characters if((*i >= 0x41 && *i <= 0x5a) || (*i >= 0x61 && *i <= 0x7a) || (*i >= 0x30 && *i <= 0x39)) str += *i; //Additionally ENCODE_FORM doesn't decode: - _ . ~ else if(type == ENCODE_FORM && (*i == '-' || *i == '_' || *i == '.' || *i == '~')) str += *i; //ENCODE_FORM encodes spaces as + instead of %20 else if(type == ENCODE_FORM && *i == ' ') str += '+'; //Additionally ENCODE_URICOMPONENT and ENCODE_URI don't encode: //- _ . ! ~ * ' ( ) else if((type == ENCODE_URI || type == ENCODE_URICOMPONENT) && (*i == '-' || *i == '_' || *i == '.' || *i == '!' || *i == '~' || *i == '*' || *i == '\'' || *i == '(' || *i == ')')) str += *i; //Additionally ENCODE_URI doesn't encode: //; / ? : @ & = + $ , # else if((type == ENCODE_URI) && (*i == ';' || *i == '/' || *i == '?' || *i == ':' || *i == '@' || *i == '&' || *i == '=' || *i == '+' || *i == '$' || *i == ',' || *i == '#')) str += *i; // ENCODE_ESCAPE doesn't encode: //@ - _ . * + / else if(type == ENCODE_ESCAPE && (*i == '@' || *i == '-' || *i == '_' || *i == '.' || *i == '*' || *i == '+' || *i == '/')) str += *i; else { if(*i<256) sprintf(buf,"%%%02X",*i); else sprintf(buf,"%%u%04X",*i); str += buf; } } } return str; } std::string URLInfo::decode(const std::string& u, ENCODING type) { std::string str; //The string can only shrink str.reserve(u.length()); std::string stringBuf; stringBuf.reserve(3); for(size_t i=0;i u.length()-3 || u[i] != '%') str += u[i]; else { stringBuf = u[i]; stringBuf += u[i+1]; stringBuf += u[i+2]; std::transform(stringBuf.begin(), stringBuf.end(), stringBuf.begin(), ::toupper); //ENCODE_SPACES only decodes %20 to space if(type == ENCODE_SPACES && stringBuf == "%20") str += " "; //ENCODE_SPACES doesn't decode other characters else if(type == ENCODE_SPACES) { str += stringBuf; i+=2; } //ENCODE_URI and ENCODE_URICOMPONENT don't decode: //- _ . ! ~ * ' ( ) else if((type == ENCODE_URI || type == ENCODE_URICOMPONENT) && (stringBuf == "%2D" || stringBuf == "%5F" || stringBuf == "%2E" || stringBuf == "%21" || stringBuf == "%7E" || stringBuf == "%2A" || stringBuf == "%27" || stringBuf == "%28" || stringBuf == "%29")) { str += stringBuf; i+=2; } //Additionally ENCODE_URI doesn't decode: //; / ? : @ & = + $ , # else if(type == ENCODE_URI && (stringBuf == "%23" || stringBuf == "%24" || stringBuf == "%26" || stringBuf == "%2B" || stringBuf == "%2C" || stringBuf == "%2F" || stringBuf == "%3A" || stringBuf == "%3B" || stringBuf == "%3D" || stringBuf == "%3F" || stringBuf == "%40")) { str += stringBuf; i+=2; } //All encoded characters that weren't excluded above are now decoded else { if(u[i+1] == 'u' && i+6 <= u.length() && isxdigit(u[i+2]) && isxdigit(u[i+3]) && isxdigit(u[i+4]) && isxdigit(u[i+5])) { tiny_string s=tiny_string::fromChar((uint32_t)strtoul(u.substr(i+2, 4).c_str(), NULL, 16)); str.append(s.raw_buf()); i += 5; } else if(isxdigit(u[i+1]) && isxdigit(u[i+2])) { tiny_string s=tiny_string::fromChar((uint32_t)strtoul(u.substr(i+1, 2).c_str(), NULL, 16)); str.append(s.raw_buf()); i += 2; } else { str += u[i]; } } } } return str; } bool URLInfo::isRTMP() const { return protocol == "rtmp" || protocol == "rtmpe" || protocol == "rtmps" || protocol == "rtmpt" || protocol == "rtmpte" || protocol == "rtmpts"; } std::list< std::pair > URLInfo::getQueryKeyValue() const { std::list< std::pair > keyvalues; std::list queries = query.split('&'); std::list::iterator it; for(it=queries.begin(); it!=queries.end(); ++it) { uint32_t eqpos = it->find("="); if(eqpos!=tiny_string::npos && (eqpos+1numChars())) { tiny_string key=decode(it->substr(0, eqpos), ENCODE_ESCAPE); tiny_string value=decode(it->substr(eqpos+1, it->numChars()-eqpos-1), ENCODE_ESCAPE); keyvalues.push_back(std::make_pair(key, value)); } } return keyvalues; } lightspark-0.7.2/src/backends/urlutils.h000066400000000000000000000123751212105246600202740ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2010-2011 Timon Van Overveldt (timonvo@gmail.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_URLUTILS_H #define BACKENDS_URLUTILS_H 1 #include "compat.h" #include #include #include #include #include "swftypes.h" namespace lightspark { class DLL_PUBLIC URLInfo { friend std::ostream& operator<<(std::ostream& s, const URLInfo& u); private: tiny_string url; //The URL space encoded tiny_string parsedURL; //The URL normalized and space encoded tiny_string protocol; //Part after tiny_string hostname; //Part after :// after protocol tiny_string path; //Part after first / after hostname tiny_string pathDirectory; tiny_string pathFile; tiny_string query; //Part after first ? tiny_string fragment; //Part after first # tiny_string stream; //The requested stream, used for RTMP protocols public: enum INVALID_REASON { IS_EMPTY, MISSING_PROTOCOL, MISSING_PATH, MISSING_HOSTNAME, INVALID_PORT }; private: INVALID_REASON invalidReason; uint16_t port; //Part after first : after hostname bool valid; public: URLInfo():invalidReason(IS_EMPTY),valid(false) {}; URLInfo(const tiny_string& u); ~URLInfo() {}; bool isValid() const { return valid; } INVALID_REASON getInvalidReason() const { return invalidReason; }; //Remove extraneous slashes, .. and . from URLs tiny_string normalizePath(const tiny_string& u); //Go to the specified URL, using the current URL as the root url for unqualified URLs const URLInfo goToURL(const tiny_string& u) const; //Check if this URL is a sub-URL of the given URL (same protocol & hostname, subpath) bool isSubOf(const URLInfo& parent) const; //Check if this URL has a path that is a sub-path of the given URL bool isSubPathOf(const URLInfo& parent) const { return isSubPathOf(parent.getPathDirectory(), getPathDirectory()); } //Check if a given path is a sub-path of another given path static bool isSubPathOf(const tiny_string& parent, const tiny_string& child); //Check if this URL has a domain that is a subdomain of the given URL bool isSubDomainOf(const URLInfo& parent) const { return isSubDomainOf(parent.getHostname(), getHostname()); } //Check if a given domain is a sub-domain of another given domain static bool isSubDomainOf(const tiny_string& parent, const tiny_string& child); //Check if a given domain a matches a given domain expression (can be used with wildcard domains) static bool matchesDomain(const tiny_string& expression, const tiny_string& subject); //Check if the given url has same protocol, hostname and port bool sameHost(const URLInfo& other) const; bool operator==(const std::string& subject) const { return getParsedURL() == tiny_string(subject); } bool operator==(const tiny_string& subject) const { return getParsedURL() == subject; } bool operator==(const URLInfo& subject) const { return getParsedURL() == subject.getParsedURL(); } const tiny_string& getURL() const { return url; }; const tiny_string& getParsedURL() const { return valid ? parsedURL : url; }; const tiny_string& getProtocol() const { return protocol; }; const tiny_string& getHostname() const { return hostname; }; uint16_t getPort() const { return port; }; const tiny_string& getPath() const { return path; }; const tiny_string& getPathDirectory() const { return pathDirectory; }; const tiny_string& getPathFile() const { return pathFile; }; const tiny_string& getQuery() const { return query; }; const tiny_string& getFragment() const { return fragment; }; std::list< std::pair > getQueryKeyValue() const; bool isRTMP() const; //Accessors to the RTMP requested stream const tiny_string& getStream() const { return stream; } void setStream(const tiny_string& s) { stream=s; } //ENCODE_SPACES is used for safety, it can run over another ENCODING without corrupting data enum ENCODING { ENCODE_SPACES, ENCODE_FORM, ENCODE_URI, ENCODE_URICOMPONENT, ENCODE_ESCAPE }; static tiny_string encode(const tiny_string& u, ENCODING type=ENCODE_URICOMPONENT); static std::string encode(const std::string& u, ENCODING type=ENCODE_URICOMPONENT) { return std::string(encode(tiny_string(u), type)); } static tiny_string decode(const tiny_string& u, ENCODING type=ENCODE_URICOMPONENT) { return tiny_string(decode(std::string(u.raw_buf()), type)); }; static std::string decode(const std::string& u, ENCODING type=ENCODE_URICOMPONENT); }; }; #endif /* BACKENDS_URLUTILS_H */ lightspark-0.7.2/src/backends/xml_support.cpp000066400000000000000000000141471212105246600213370ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2012-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include #include "backends/xml_support.h" #include "logger.h" using namespace lightspark; using namespace std; #ifdef XMLPP_2_35_1 RecoveryDocument::RecoveryDocument(_xmlDoc* d):xmlpp::Document(d) { } void RecoveryDomParser::parse_memory_raw(const unsigned char* contents, size_type bytes_count) { release_underlying(); //Free any existing document. //The following is based on the implementation of xmlParseFile(), in xmlSAXParseFileWithData(): context_ = xmlCreateMemoryParserCtxt((const char*)contents, bytes_count); if(!context_) throw xmlpp::internal_error("Couldn't create parsing context"); xmlSAXHandlerV1* handler=(xmlSAXHandlerV1*)calloc(1,sizeof(xmlSAXHandlerV1)); initxmlDefaultSAXHandler(handler, 0); context_->recovery=1; free(context_->sax); context_->sax=(xmlSAXHandler*)handler; context_->keepBlanks = 0; handler->ignorableWhitespace = xmlSAX2IgnorableWhitespace; //The following is based on the implementation of xmlParseFile(), in xmlSAXParseFileWithData(): //and the implementation of xmlParseMemory(), in xmlSaxParseMemoryWithData(). initialize_context(); if(!context_) throw xmlpp::internal_error("Context not initialized"); xmlParseDocument(context_); check_for_exception(); if(!context_->wellFormed) LOG(LOG_ERROR, "XML data not well formed!"); doc_ = new RecoveryDocument(context_->myDoc); // This is to indicate to release_underlying that we took the // ownership on the doc. context_->myDoc = 0; //Free the parse context, but keep the document alive so people can navigate the DOM tree: //TODO: Why not keep the context alive too? Parser::release_underlying(); check_for_exception(); } #endif xmlpp::Node* XMLBase::buildFromString(const string& str, bool ignoreEmptyTextNodes, const string& default_ns) { string buf = parserQuirks(str); try { parser.parse_memory_raw((const unsigned char*)buf.c_str(), buf.size()); } catch(const exception& e) { } xmlpp::Document* doc=parser.get_document(); if(doc && doc->get_root_node()) { xmlpp::Element *root = doc->get_root_node(); // It would be better to remove empty nodes during // parsing, but xmlpp doesn't offer an interface. if (ignoreEmptyTextNodes) removeWhitespaceNodes(root); addDefaultNamespace(root, default_ns); return root; } LOG(LOG_ERROR, "XML parsing failed, creating text node"); //If everything fails, create a fake document and add a single text string child if (default_ns.empty()) buf=""; else buf=""; parser.parse_memory_raw((const unsigned char*)buf.c_str(), buf.size()); return parser.get_document()->get_root_node()->add_child_text(str); // TODO: node's parent (root) should be inaccessible from AS code } void XMLBase::addDefaultNamespace(xmlpp::Element *root, const string& default_ns) { if(default_ns.empty() || !root->get_namespace_uri().empty()) return; xmlNodePtr node = root->cobj(); xmlNsPtr ns = xmlNewNs(node, BAD_CAST default_ns.c_str(), NULL); addDefaultNamespaceRecursive(node, ns); } void XMLBase::addDefaultNamespaceRecursive(xmlNodePtr node, xmlNsPtr ns) { //Set the default namespace to nodes by descending until we //encounter another namespace. if ((node->type != XML_ELEMENT_NODE) || (node->ns != NULL)) return; xmlSetNs(node, ns); xmlNodePtr child=node->children; while(child) { addDefaultNamespaceRecursive(child, ns); child = child->next; } } xmlpp::Node* XMLBase::buildCopy(const xmlpp::Node* src) { const xmlpp::TextNode* textnode=dynamic_cast(src); if(textnode) { return buildFromString(textnode->get_content(), false); } else { return parser.get_document()->create_root_node_by_import(src); } } // Adobe player's XML parser accepts many strings which are not valid // XML according to the specs. This function attempts to massage // invalid-but-accepted-by-Adobe strings into valid XML so that // libxml++ parser doesn't throw an error. string XMLBase::parserQuirks(const string& str) { string buf = quirkCData(str); buf = quirkXMLDeclarationInMiddle(buf); return buf; } string XMLBase::quirkCData(const string& str) { //if this is a CDATA node replace CDATA tags to make it look like a text-node //for compatibility with the Adobe player if (str.compare(0, 9, ""+str.substr(9, str.size()-12)+""; } else return str; } string XMLBase::quirkXMLDeclarationInMiddle(const string& str) { string buf(str); // Adobe player ignores XML declarations in the middle of a // string. while (true) { size_t start = buf.find("", start+5); if (end == buf.npos) break; end += 2; buf.erase(start, end-start); } return buf; } void XMLBase::removeWhitespaceNodes(xmlpp::Element *node) { xmlpp::Node::NodeList children = node->get_children(); xmlpp::Node::NodeList::iterator it; for (it=children.begin(); it!=children.end(); ++it) { xmlpp::Element *element = dynamic_cast(*it); xmlNode *xmlnode = (*it)->cobj(); if (xmlnode->type == XML_TEXT_NODE && xmlIsBlankNode(xmlnode)) { node->remove_child(*it); } else if (element) { removeWhitespaceNodes(element); } } } lightspark-0.7.2/src/backends/xml_support.h000066400000000000000000000051411212105246600207760ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2012-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef BACKENDS_XML_SUPPORT_H #define BACKENDS_XML_SUPPORT_H 1 #include #include #include //For xmlCreateFileParserCtxt(). #include namespace lightspark { #ifdef XMLPP_2_35_1 //Create a utility derived class from xmlpp::DomParser since we want to use the recovery mode class RecoveryDomParser:public xmlpp::DomParser { public: void parse_memory_raw(const unsigned char* contents, size_type bytes_count); }; //Also create a utility derived class from xmlpp::Document to access the protected constructor class RecoveryDocument: public xmlpp::Document { public: RecoveryDocument(_xmlDoc* d); }; typedef RecoveryDomParser LSDomParser; #else typedef xmlpp::DomParser LSDomParser; #endif /* * Base class for both XML and XMLNode */ class XMLBase { protected: //The parser will destroy the document and all the childs on destruction LSDomParser parser; xmlpp::Node* buildFromString(const std::string& str, bool ignoreEmptyTextnodes, const std::string& default_ns=std::string()); void addDefaultNamespace(xmlpp::Element *root, const std::string& default_ns); void addDefaultNamespaceRecursive(xmlNodePtr node, xmlNsPtr ns); // Set the root to be a copy of src. If src is a text node, // create a new element node with the same content. xmlpp::Node* buildCopy(const xmlpp::Node* node); static std::string parserQuirks(const std::string& str); static std::string quirkCData(const std::string& str); static std::string quirkXMLDeclarationInMiddle(const std::string& str); void removeWhitespaceNodes(xmlpp::Element *node); }; }; #endif /* BACKENDS_XML_SUPPORT_H */ lightspark-0.7.2/src/compat.cpp000066400000000000000000000216441212105246600164540ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "compat.h" #include #include #include "logger.h" #include #ifdef _WIN32 # ifndef NOMINMAX # define NOMINMAX # endif # define WIN32_LEAN_AND_MEAN # include # undef DOUBLE_CLICK # undef RGB # undef VOID # ifndef PATH_MAX # define PATH_MAX 260 # endif #endif using namespace std; uint64_t compat_msectiming() { #ifdef _WIN32 return GetTickCount(); //TODO: use GetTickCount64 #else timespec t; clock_gettime(CLOCK_MONOTONIC,&t); return (t.tv_sec*1000 + t.tv_nsec/1000000); #endif } int kill_child(GPid childPid) { #ifdef _WIN32 TerminateProcess(childPid, 0); #else kill(childPid, SIGTERM); g_spawn_close_pid(childPid); #endif return 0; } #ifndef _WIN32 #include "timer.h" uint64_t timespecToUsecs(timespec t) { uint64_t ret=0; ret+=(t.tv_sec*1000000LL); ret+=(t.tv_nsec/1000LL); return ret; } uint64_t compat_get_thread_cputime_us() { timespec tp; #ifndef _POSIX_THREAD_CPUTIME #error no thread clock available #endif clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp); return timespecToUsecs(tp); } void aligned_malloc(void **memptr, size_t alignment, size_t size) { if(posix_memalign(memptr, alignment, size)) throw std::bad_alloc(); } void aligned_free(void *mem) { return free(mem); } #else uint64_t compat_get_thread_cputime_us() { // WINTODO: On Vista/7 we might want to use the processor cycles API FILETIME CreationTime, ExitTime, KernelTime, UserTime; GetThreadTimes(GetCurrentThread(), &CreationTime, &ExitTime, &KernelTime, &UserTime); uint64_t ret; ULARGE_INTEGER u; u.HighPart = KernelTime.dwHighDateTime; u.LowPart = KernelTime.dwLowDateTime; ret = u.QuadPart / 10; u.HighPart = UserTime.dwHighDateTime; u.LowPart = UserTime.dwLowDateTime; ret += u.QuadPart / 10; return ret; } #endif #ifdef _WIN32 /* If we are run from standalone, g_hinstance stays NULL. * In the plugin, DLLMain sets it to the dll's instance. */ HINSTANCE g_hinstance = NULL; #define DEFDLLMAIN(x) extern "C" BOOL WINAPI x##_DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) DEFDLLMAIN(gio); DEFDLLMAIN(glib); DEFDLLMAIN(atk); DEFDLLMAIN(pango); DEFDLLMAIN(gdk); DEFDLLMAIN(gtk); DEFDLLMAIN(cairo); #define RUNDLLMAIN(x) x##_DllMain(hinstDLL, fdwReason, lpvReserved) extern "C" BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { RUNDLLMAIN(gio); RUNDLLMAIN(glib); //RUNDLLMAIN(cairo); //taken care of by patches from mxe RUNDLLMAIN(atk); RUNDLLMAIN(pango); RUNDLLMAIN(gdk); RUNDLLMAIN(gtk); return TRUE; } const char* getExectuablePath() { static char path[MAX_PATH] = {0}; if(!path[0]) { size_t len = GetModuleFileNameA(g_hinstance, path, MAX_PATH); if(!len) return ""; char* delim = strrchr(path,'\\'); if(delim) *delim = '\0'; } return path; } /* Routine Description: This routine appends the given argument to a command line such that CommandLineToArgvW will return the argument string unchanged. Arguments in a command line should be separated by spaces; this function does not add these spaces. Arguments: Argument - Supplies the argument to encode. CommandLine - Supplies the command line to which we append the encoded argument string. Force - Supplies an indication of whether we should quote the argument even if it does not contain any characters that would ordinarily require quoting. Taken from http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx */ void ArgvQuote(const std::string& Argument, std::string& CommandLine, bool Force = false) { // // Unless we're told otherwise, don't quote unless we actually // need to do so --- hopefully avoid problems if programs won't // parse quotes properly // if (Force == false && Argument.empty () == false && Argument.find_first_of (" \t\n\v\"") == Argument.npos) { CommandLine.append (Argument); } else { CommandLine.push_back ('"'); for (auto It = Argument.begin () ; ; ++It) { unsigned NumberBackslashes = 0; while (It != Argument.end () && *It == '\\') { ++It; ++NumberBackslashes; } if (It == Argument.end ()) { // // Escape all backslashes, but let the terminating // double quotation mark we add below be interpreted // as a metacharacter. // CommandLine.append (NumberBackslashes * 2, '\\'); break; } else if (*It == '"') { // // Escape all backslashes and the following // double quotation mark. // CommandLine.append (NumberBackslashes * 2 + 1, '\\'); CommandLine.push_back (*It); } else { // // Backslashes aren't special here. // CommandLine.append (NumberBackslashes, '\\'); CommandLine.push_back (*It); } } CommandLine.push_back ('"'); } } #include /* * Spawns a process from the given args, * returns its process handle and writes * the file descriptor of its stdin to * stdinfd. * Returns NULL on error. */ HANDLE compat_spawn(char** arg, int* stdinfd) { /* Properly quote args into a command line */ string cmdline; int i=0; while(true) { ArgvQuote(arg[i],cmdline); if(arg[++i] == NULL) break; else cmdline += " "; } /* This is taken from http://msdn.microsoft.com/en-us/library/windows/desktop/ms682499%28v=vs.85%29.aspx */ SECURITY_ATTRIBUTES saAttr; HANDLE hChildStdin_Rd = NULL; HANDLE hChildStdin_Wr = NULL; saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; if(!CreatePipe(&hChildStdin_Rd, &hChildStdin_Wr, &saAttr, 0)) { LOG(LOG_ERROR,"CreatePipe"); return NULL; } // Ensure the write handle to the pipe for STDIN is not inherited. if(!SetHandleInformation(hChildStdin_Wr, HANDLE_FLAG_INHERIT, 0)) { LOG(LOG_ERROR,"SetHandleInformation"); return NULL; } // Create the child process. PROCESS_INFORMATION piProcInfo; STARTUPINFO siStartInfo; // Set up members of the PROCESS_INFORMATION structure. ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); // Set up members of the STARTUPINFO structure. // This structure specifies the STDIN and STDOUT handles for redirection. ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.hStdInput = hChildStdin_Rd; siStartInfo.dwFlags |= STARTF_USESTDHANDLES; // Create the child process. if(!CreateProcess(NULL, (LPSTR)cmdline.c_str(), // command line NULL, // process security attributes NULL, // primary thread security attributes TRUE, // handles are inherited 0, // creation flags NULL, // use parent's environment NULL, // use parent's current directory &siStartInfo, // STARTUPINFO pointer &piProcInfo)) // receives PROCESS_INFORMATION { LOG(LOG_ERROR,"CreateProcess"); return NULL; } CloseHandle(piProcInfo.hThread); *stdinfd = _open_osfhandle((intptr_t)hChildStdin_Wr, _O_RDONLY); if(*stdinfd == -1) { LOG(LOG_ERROR,"_open_osfhandle"); return NULL; } #if 0 HANDLE hInputFile = NULL; /* Write file to pipe */ hInputFile = CreateFile( stdinfile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); if(hInputFile == INVALID_HANDLE_VALUE ) { LOG(LOG_ERROR,"CreateFile"); return NULL; } DWORD dwRead, dwWritten; CHAR chBuf[BUFSIZE]; BOOL bSuccess; while(true) { bSuccess = ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL); if(!bSuccess || dwRead == 0 ) break; bSuccess = WriteFile(hChildStdin_Wr, chBuf, dwRead, &dwWritten, NULL); if(!bSuccess) break; } if(!CloseHandle(hChildStdin_Wr)) LOG(LOG_ERROR,"StdInWr CloseHandle"); #endif return piProcInfo.hProcess; } #endif lightspark-0.7.2/src/compat.h000066400000000000000000000134231212105246600161150ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef COMPAT_H #define COMPAT_H 1 #include #if BOOST_VERSION >= 104600 #define BOOST_FILESYSTEM_VERSION 3 #else #define BOOST_FILESYSTEM_VERSION 2 #endif #include #include #include #include #include #ifndef M_PI # define M_PI 3.14159265358979323846 #endif #ifdef _WIN32 #include //for ssize_t #include //for close(), unlink() #endif // TODO: This should be reworked to use CMake feature detection where possible /* gettext support */ #include #include #define _(STRING) gettext(STRING) #include #include #if defined(__GNUC__) && defined(_WIN32) /* There is a bug in mingw preventing those from being declared */ extern "C" { _CRTIMP int __cdecl __MINGW_NOTHROW _stricmp (const char*, const char*); _CRTIMP int __cdecl __MINGW_NOTHROW _strnicmp (const char*, const char*, size_t); _CRTIMP int __cdecl __MINGW_NOTHROW _close (int); _CRTIMP void * __cdecl __MINGW_NOTHROW _aligned_malloc (size_t, size_t); _CRTIMP void __cdecl __MINGW_NOTHROW _aligned_free (void*); _CRTIMP char* __cdecl __MINGW_NOTHROW _strdup (const char*) __MINGW_ATTRIB_MALLOC; } #define strncasecmp _strnicmp #define strcasecmp _stricmp #define strdup _strdup #endif #ifdef __GNUC__ # ifndef __STDC_LIMIT_MACROS # define __STDC_LIMIT_MACROS # endif # ifndef __STDC_CONSTANT_MACROS # define __STDC_CONSTANT_MACROS # endif #endif /* aligned_malloc */ #ifdef _WIN32 # include inline void aligned_malloc(void **memptr, std::size_t alignment, std::size_t size) { *memptr = _aligned_malloc(size, alignment); if(!*memptr) throw std::bad_alloc(); } inline void aligned_free(void *mem) { _aligned_free(mem); } #else void aligned_malloc(void **memptr, std::size_t alignment, std::size_t size); void aligned_free(void *mem); #endif #ifndef _WIN32 # define CALLBACK #endif //Support both atomic header ( gcc >= 4.6 ), and earlier ( stdatomic.h ) #ifdef HAVE_ATOMIC # include #else # include #endif #define ATOMIC_INT32(x) std::atomic x #define ATOMIC_INCREMENT(x) (x.fetch_add(1)+1) #define ATOMIC_DECREMENT(x) (x.fetch_sub(1)-1) #define ATOMIC_ADD(x, v) (x.fetch_add(v)+v) #define ATOMIC_SUB(x, v) (x.fetch_sub(v)-v) //Boolean type with acquire release barrier semantics #define ACQUIRE_RELEASE_FLAG(x) std::atomic_bool x #define ACQUIRE_READ(x) x.load(std::memory_order_acquire) #define RELEASE_WRITE(x, v) x.store(v, std::memory_order_release) /* DLL_LOCAL / DLL_PUBLIC */ /* When building on win32, DLL_PUBLIC is set to __declspec(dllexport) * during build of the audio plugins. * The browser plugin uses its own definitions from npapi. * And the liblightspark.dll is linked directly (without need for dllexport) */ #ifndef DLL_PUBLIC #if __GNUC__ >= 4 # define DLL_PUBLIC __attribute__ ((visibility("default"))) # define DLL_LOCAL __attribute__ ((visibility("hidden"))) #else # define DLL_PUBLIC # define DLL_LOCAL #endif #endif /* min/max */ template inline T minTmpl(T a, T b) { return (a inline T maxTmpl(T a, T b) { return (a>b)?a:b; } #define imin minTmpl #define imax maxTmpl #define dmin minTmpl #define dmax maxTmpl /* timing */ uint64_t compat_msectiming(); void compat_msleep(unsigned int time); uint64_t compat_get_thread_cputime_us(); /* byte order */ #if G_BYTE_ORDER == G_BIG_ENDIAN inline uint32_t LittleEndianToSignedHost24(uint32_t x) { uint32_t ret=GINT32_FROM_LE(x); assert(ret<0x1000000); //Sign extend if(ret&0x800000) ret|=0xff000000; return ret; } inline uint32_t LittleEndianToUnsignedHost24(uint32_t x) { assert(x<0x1000000); uint32_t ret=GINT32_FROM_LE(x); return ret; } inline uint32_t BigEndianToSignedHost24(uint32_t x) { //Sign extend x>>=8; assert(x<0x1000000); if(x&0x800000) x|=0xff000000; return x; } inline uint32_t BigEndianToUnsignedHost24(uint32_t x) { x>>=8; assert(x<0x1000000); return x; } #else //__BYTE_ORDER == __LITTLE_ENDIAN inline uint32_t LittleEndianToSignedHost24(uint32_t x) { assert(x<0x1000000); if(x&0x800000) x|=0xff000000; return x; } inline uint32_t LittleEndianToUnsignedHost24(uint32_t x) { assert(x<0x1000000); return x; } inline uint32_t BigEndianToSignedHost24(uint32_t x) { assert(x<0x1000000); //Discard the lowest byte, as it was the highest uint32_t ret=GINT32_FROM_BE(x)>>8; //Sign extend if(ret&0x800000) ret|=0xff000000; return ret; } inline uint32_t BigEndianToUnsignedHost24(uint32_t x) { assert(x<0x1000000); //Discard the lowest byte, as it was the highest uint32_t ret=GINT32_FROM_BE(x)>>8; return ret; } #endif // __BYTE_ORDER == __BIG_ENDIAN /* spawning */ #ifdef _WIN32 /* returns the path of the current executable */ const char* getExectuablePath(); typedef void* HANDLE; HANDLE compat_spawn(char** args, int* stdinfd); #endif int kill_child(GPid p); #endif /* COMPAT_H */ lightspark-0.7.2/src/errorconstants.cpp000066400000000000000000000341461212105246600202600ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ /* This file is generated by errorgen - DO NOT EDIT */ #include #include "errorconstants.h" #include "compat.h" namespace lightspark { const std::map errorMessages = { {kOutOfMemoryError, _("The system is out of memory.")}, {kNotImplementedError, _("The method %1 is not implemented.")}, {kInvalidPrecisionError, _("Number.toPrecision has a range of 1 to 21. Number.toFixed and Number.toExponential have a range of 0 to 20. Specified value is not within expected range.")}, {kInvalidRadixError, _("The radix argument must be between 2 and 36; got %1.")}, {kInvokeOnIncompatibleObjectError, _("Method %1 was invoked on an incompatible object.")}, {kArrayIndexNotIntegerError, _("Array index is not a positive integer (%1).")}, {kCallOfNonFunctionError, _("%1 is not a function.")}, {kConstructOfNonFunctionError, _("Instantiation attempted on a non-constructor.")}, {kAmbiguousBindingError, _("%1 is ambiguous; Found more than one matching binding.")}, {kConvertNullToObjectError, _("Cannot access a property or method of a null object reference.")}, {kConvertUndefinedToObjectError, _("A term is undefined and has no properties.")}, {kIllegalOpcodeError, _("Method %1 contained illegal opcode %2 at offset %3.")}, {kLastInstExceedsCodeSizeError, _("The last instruction exceeded code size.")}, {kFindVarWithNoScopeError, _("Cannot call OP_findproperty when scopeDepth is 0.")}, {kClassNotFoundError, _("Class %1 could not be found.")}, {kIllegalSetDxns, _("Method %1 cannot set default xml namespace")}, {kDescendentsError, _("Descendants operator (..) not supported on type %1.")}, {kScopeStackOverflowError, _("Scope stack overflow occurred.")}, {kScopeStackUnderflowError, _("Scope stack underflow occurred.")}, {kGetScopeObjectBoundsError, _("Getscopeobject %1 is out of bounds.")}, {kCannotFallOffMethodError, _("Code cannot fall off the end of a method.")}, {kInvalidBranchTargetError, _("At least one branch target was not on a valid instruction in the method.")}, {kIllegalVoidError, _("Type void may only be used as a function return type.")}, {kStackOverflowError, _("Stack overflow occurred.")}, {kStackUnderflowError, _("Stack underflow occurred.")}, {kInvalidRegisterError, _("An invalid register %1 was accessed.")}, {kSlotExceedsCountError, _("Slot %1 exceeds slotCount=%2 of %3.")}, {kMethodInfoExceedsCountError, _("Method_info %1 exceeds method_count=%2.")}, {kDispIdExceedsCountError, _("Disp_id %1 exceeds max_disp_id=%2 of %3.")}, {kDispIdUndefinedError, _("Disp_id %1 is undefined on %2.")}, {kStackDepthUnbalancedError, _("Stack depth is unbalanced. %1 != %2.")}, {kScopeDepthUnbalancedError, _("Scope depth is unbalanced. %1 != %2.")}, {kCpoolIndexRangeError, _("Cpool index %1 is out of range %2.")}, {kCpoolEntryWrongTypeError, _("Cpool entry %1 is wrong type.")}, {kCheckTypeFailedError, _("Type Coercion failed: cannot convert %1 to %2.")}, {kIllegalSuperCallError, _("Illegal super expression found in method %1.")}, {kCannotAssignToMethodError, _("Cannot assign to a method %1 on %2.")}, {kRedefinedError, _("%1 is already defined.")}, {kCannotVerifyUntilReferencedError, _("Cannot verify method until it is referenced.")}, {kCantUseInstanceofOnNonObjectError, _("The right-hand side of instanceof must be a class or function.")}, {kIsTypeMustBeClassError, _("The right-hand side of operator must be a class.")}, {kInvalidMagicError, _("Not an ABC file. major_version=%1 minor_version=%2.")}, {kInvalidCodeLengthError, _("Invalid code_length=%1.")}, {kInvalidMethodInfoFlagsError, _("MethodInfo-%1 unsupported flags=%2.")}, {kUnsupportedTraitsKindError, _("Unsupported traits kind=%1.")}, {kMethodInfoOrderError, _("MethodInfo-%1 referenced before definition.")}, {kMissingEntryPointError, _("No entry point was found.")}, {kPrototypeTypeError, _("Prototype objects must be vanilla Objects.")}, {kConvertToPrimitiveError, _("Cannot convert %1 to primitive.")}, {kIllegalEarlyBindingError, _("Illegal early binding access to %1.")}, {kInvalidURIError, _("Invalid URI passed to %1 function.")}, {kIllegalOverrideError, _("Illegal override of %1 in %2.")}, {kIllegalExceptionHandlerError, _("Illegal range or target offsets in exception handler.")}, {kWriteSealedError, _("Cannot create property %1 on %2.")}, {kIllegalSlotError, _("%1 can only contain methods.")}, {kIllegalOperandTypeError, _("Illegal operand type: %1 must be %2.")}, {kClassInfoOrderError, _("ClassInfo-%1 is referenced before definition.")}, {kClassInfoExceedsCountError, _("ClassInfo %1 exceeds class_count=%2.")}, {kNumberOutOfRangeError, _("The value %1 cannot be converted to %2 without losing precision.")}, {kWrongArgumentCountError, _("Argument count mismatch on %1. Expected %2, got %3.")}, {kCannotCallMethodAsConstructor, _("Cannot call method %1 as constructor.")}, {kUndefinedVarError, _("Variable %1 is not defined.")}, {kFunctionConstructorError, _("The form function('function body') is not supported.")}, {kIllegalNativeMethodBodyError, _("Native method %1 has illegal method body.")}, {kCannotMergeTypesError, _("%1 and %2 cannot be reconciled.")}, {kReadSealedError, _("Property %1 not found on %2 and there is no default value.")}, {kCallNotFoundError, _("Method %1 not found on %2")}, {kAlreadyBoundError, _("Function %1 has already been bound to %2.")}, {kZeroDispIdError, _("Disp_id 0 is illegal.")}, {kDuplicateDispIdError, _("Non-override method %1 replaced because of duplicate disp_id %2.")}, {kConstWriteError, _("Illegal write to read-only property %1 on %2.")}, {kMathNotFunctionError, _("Math is not a function.")}, {kMathNotConstructorError, _("Math is not a constructor.")}, {kWriteOnlyError, _("Illegal read of write-only property %1 on %2.")}, {kIllegalOpMultinameError, _("Illegal opcode/multiname combination: %1<%2>.")}, {kIllegalNativeMethodError, _("Native methods are not allowed in loaded code.")}, {kIllegalNamespaceError, _("Illegal value for namespace.")}, {kReadSealedErrorNs, _("Property %1 not found on %2 and there is no default value.")}, {kNoDefaultNamespaceError, _("No default namespace has been set.")}, {kXMLPrefixNotBound, _("The prefix \"%1\" for element \"%2\" is not bound.")}, {kXMLBadQName, _("Element or attribute (\"%1\") does not match QName production: QName::=(NCName':')?NCName.")}, {kXMLUnterminatedElementTag, _("The element type \"%1\" must be terminated by the matching end-tag \"\".")}, {kXMLOnlyWorksWithOneItemLists, _("The %1 method only works on lists containing one item.")}, {kXMLAssignmentToIndexedXMLNotAllowed, _("Assignment to indexed XML is not allowed.")}, {kXMLMarkupMustBeWellFormed, _("The markup in the document following the root element must be well-formed.")}, {kXMLAssigmentOneItemLists, _("Assignment to lists with more than one item is not supported.")}, {kXMLMalformedElement, _("XML parser failure: element is malformed.")}, {kXMLUnterminatedCData, _("XML parser failure: Unterminated CDATA section.")}, {kXMLUnterminatedXMLDecl, _("XML parser failure: Unterminated XML declaration.")}, {kXMLUnterminatedDocTypeDecl, _("XML parser failure: Unterminated DOCTYPE declaration.")}, {kXMLUnterminatedComment, _("XML parser failure: Unterminated comment.")}, {kXMLUnterminatedAttribute, _("XML parser failure: Unterminated attribute.")}, {kXMLUnterminatedElement, _("XML parser failure: Unterminated element.")}, {kXMLUnterminatedProcessingInstruction, _("XML parser failure: Unterminated processing instruction.")}, {kXMLNamespaceWithPrefixAndNoURI, _("Illegal prefix %1 for no namespace.")}, {kRegExpFlagsArgumentError, _("Cannot supply flags when constructing one RegExp from another.")}, {kNoScopeError, _("Cannot verify method %1 with unknown scope.")}, {kIllegalDefaultValue, _("Illegal default value for type %1.")}, {kCannotExtendFinalClass, _("Class %1 cannot extend final base class.")}, {kXMLDuplicateAttribute, _("Attribute \"%1\" was already specified for element \"%2\".")}, {kCorruptABCError, _("The ABC data is corrupt, attempt to read out of bounds.")}, {kInvalidBaseClassError, _("The OP_newclass opcode was used with the incorrect base class.")}, {kDanglingFunctionError, _("Attempt to directly call unbound function %1 from method %2.")}, {kCannotExtendError, _("%1 cannot extend %2.")}, {kCannotImplementError, _("%1 cannot implement %2.")}, {kCoerceArgumentCountError, _("Argument count mismatch on class coercion. Expected 1, got %1.")}, {kInvalidNewActivationError, _("OP_newactivation used in method without NEED_ACTIVATION flag.")}, {kNoGlobalScopeError, _("OP_getglobalslot or OP_setglobalslot used with no global scope.")}, {kNotConstructorError, _("%1 is not a constructor.")}, {kApplyError, _("second argument to Function.prototype.apply must be an array.")}, {kXMLInvalidName, _("Invalid XML name: %1.")}, {kXMLIllegalCyclicalLoop, _("Illegal cyclical loop between nodes.")}, {kDeleteTypeError, _("Delete operator is not supported with operand of type %1.")}, {kDeleteSealedError, _("Cannot delete property %1 on %2.")}, {kDuplicateMethodBodyError, _("Method %1 has a duplicate method body.")}, {kIllegalInterfaceMethodBodyError, _("Interface method %1 has illegal method body.")}, {kFilterError, _("Filter operator not supported on type %1.")}, {kInvalidHasNextError, _("OP_hasnext2 requires object and index to be distinct registers.")}, {kOutOfRangeError, _("The index %1 is out of range %2.")}, {kVectorFixedError, _("Cannot change the length of a fixed Vector.")}, {kTypeAppOfNonParamType, _("Type application attempted on a non-parameterized type.")}, {kWrongTypeArgCountError, _("Incorrect number of type parameters for %1. Expected %2, got %3.")}, {kJSONCyclicStructure, _("Cyclic structure cannot be converted to JSON string.")}, {kJSONInvalidReplacer, _("Replacer argument to JSON stringifier must be an array or a two parameter function.")}, {kJSONInvalidParseInput, _("Invalid JSON parse input.")}, {kFileOpenError, _("Error occurred opening file %1.")}, {kFileWriteError, _("Error occurred writing to file %1.")}, {kScriptTimeoutError, _("A script has executed for longer than the default timeout period of 15 seconds.")}, {kScriptTerminatedError, _("A script failed to exit after 30 seconds and was terminated.")}, {kEndOfFileError, _("End of file.")}, {kStringIndexOutOfBoundsError, _("The string index %1 is out of bounds; must be in range %2 to %3.")}, {kInvalidRangeError, _("The specified range is invalid.")}, {kNullArgumentError, _("Argument %1 cannot be null.")}, {kInvalidArgumentError, _("The value specified for argument %1 is invalid.")}, {kArrayFilterNonNullObjectError, _("When the callback argument is a method of a class, the optional this argument must be null.")}, {kWorkerAlreadyStarted, _("Worker is already started.")}, {kFailedWorkerCannotBeRestarted, _("Starting a worker that already failed is not supported.")}, {kWorkerTerminated, _("Worker has terminated.\"")}, {kMutextNotLocked, _("unlock() with no preceding matching lock().")}, {kConditionInvalidTimeout, _("Invalid condition timeout value: %1.")}, {kConditionCannotNotify, _("Condition cannot notify if associated mutex is not owned.")}, {kConditionCannotNotifyAll, _("Condition cannot notifyAll if associated mutex is not owned.")}, {kConditionCannotWait, _("Condition cannot wait if associated mutex is not owned.")}, {kConditionCannotBeInitialized, _("Condition cannot be initialized.")}, {kMutexCannotBeInitialized, _("Mutex cannot be initialized.")}, {kWorkerIllegalCallToStart, _("Only the worker's parent may call start.")}, {kInvalidParamError, _("One of the parameters is invalid.")}, {kParamRangeError, _("The supplied index is out of bounds.")}, {kNullPointerError, _("Parameter %1 must be non-null.")}, {kInvalidEnumError, _("Parameter %1 must be one of the accepted values.")}, {kCantInstantiateError, _("%1 class cannot be instantiated.")}, {kEOFError, _("End of file was encountered.")}, {kCompressedDataError, _("There was an error decompressing the data.")}, {kEmptyStringError, _("Parameter %1 must be non-empty string.")}, {kProxyGetPropertyError, _("The Proxy class does not implement getProperty. It must be overridden by a subclass.")}, {kProxySetPropertyError, _("The Proxy class does not implement setProperty. It must be overridden by a subclass.")}, {kProxyCallPropertyError, _("The Proxy class does not implement callProperty. It must be overridden by a subclass.")}, {kProxyHasPropertyError, _("The Proxy class does not implement hasProperty. It must be overridden by a subclass.")}, {kProxyDeletePropertyError, _("The Proxy class does not implement deleteProperty. It must be overridden by a subclass.")}, {kProxyGetDescendantsError, _("The Proxy class does not implement getDescendants. It must be overridden by a subclass.")}, {kProxyNextNameIndexError, _("The Proxy class does not implement nextNameIndex. It must be overridden by a subclass.")}, {kProxyNextNameError, _("The Proxy class does not implement nextName. It must be overridden by a subclass.")}, {kProxyNextValueError, _("The Proxy class does not implement nextValue. It must be overridden by a subclass.")}, {kInvalidArrayLengthError, _("The value %1 is not a valid Array length.")}, {kReadExternalNotImplementedError, _("Unable to read object in stream. The class %1 does not implement flash.utils.IExternalizable but is aliased to an externalizable class.")}, }; }; lightspark-0.7.2/src/errorconstants.h000066400000000000000000000221011212105246600177110ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ /* This file is generated by errorgen - DO NOT EDIT */ #ifndef ERRORCONSTANTS_H #define ERRORCONSTANTS_H 1 #include namespace lightspark { enum { kOutOfMemoryError = 1000, kNotImplementedError = 1001, kInvalidPrecisionError = 1002, kInvalidRadixError = 1003, kInvokeOnIncompatibleObjectError = 1004, kArrayIndexNotIntegerError = 1005, kCallOfNonFunctionError = 1006, kConstructOfNonFunctionError = 1007, kAmbiguousBindingError = 1008, kConvertNullToObjectError = 1009, kConvertUndefinedToObjectError = 1010, kIllegalOpcodeError = 1011, kLastInstExceedsCodeSizeError = 1012, kFindVarWithNoScopeError = 1013, kClassNotFoundError = 1014, kIllegalSetDxns = 1015, kDescendentsError = 1016, kScopeStackOverflowError = 1017, kScopeStackUnderflowError = 1018, kGetScopeObjectBoundsError = 1019, kCannotFallOffMethodError = 1020, kInvalidBranchTargetError = 1021, kIllegalVoidError = 1022, kStackOverflowError = 1023, kStackUnderflowError = 1024, kInvalidRegisterError = 1025, kSlotExceedsCountError = 1026, kMethodInfoExceedsCountError = 1027, kDispIdExceedsCountError = 1028, kDispIdUndefinedError = 1029, kStackDepthUnbalancedError = 1030, kScopeDepthUnbalancedError = 1031, kCpoolIndexRangeError = 1032, kCpoolEntryWrongTypeError = 1033, kCheckTypeFailedError = 1034, kIllegalSuperCallError = 1035, kCannotAssignToMethodError = 1037, kRedefinedError = 1038, kCannotVerifyUntilReferencedError = 1039, kCantUseInstanceofOnNonObjectError = 1040, kIsTypeMustBeClassError = 1041, kInvalidMagicError = 1042, kInvalidCodeLengthError = 1043, kInvalidMethodInfoFlagsError = 1044, kUnsupportedTraitsKindError = 1045, kMethodInfoOrderError = 1046, kMissingEntryPointError = 1047, kPrototypeTypeError = 1049, kConvertToPrimitiveError = 1050, kIllegalEarlyBindingError = 1051, kInvalidURIError = 1052, kIllegalOverrideError = 1053, kIllegalExceptionHandlerError = 1054, kWriteSealedError = 1056, kIllegalSlotError = 1057, kIllegalOperandTypeError = 1058, kClassInfoOrderError = 1059, kClassInfoExceedsCountError = 1060, kNumberOutOfRangeError = 1061, kWrongArgumentCountError = 1063, kCannotCallMethodAsConstructor = 1064, kUndefinedVarError = 1065, kFunctionConstructorError = 1066, kIllegalNativeMethodBodyError = 1067, kCannotMergeTypesError = 1068, kReadSealedError = 1069, kCallNotFoundError = 1070, kAlreadyBoundError = 1071, kZeroDispIdError = 1072, kDuplicateDispIdError = 1073, kConstWriteError = 1074, kMathNotFunctionError = 1075, kMathNotConstructorError = 1076, kWriteOnlyError = 1077, kIllegalOpMultinameError = 1078, kIllegalNativeMethodError = 1079, kIllegalNamespaceError = 1080, kReadSealedErrorNs = 1081, kNoDefaultNamespaceError = 1082, kXMLPrefixNotBound = 1083, kXMLBadQName = 1084, kXMLUnterminatedElementTag = 1085, kXMLOnlyWorksWithOneItemLists = 1086, kXMLAssignmentToIndexedXMLNotAllowed = 1087, kXMLMarkupMustBeWellFormed = 1088, kXMLAssigmentOneItemLists = 1089, kXMLMalformedElement = 1090, kXMLUnterminatedCData = 1091, kXMLUnterminatedXMLDecl = 1092, kXMLUnterminatedDocTypeDecl = 1093, kXMLUnterminatedComment = 1094, kXMLUnterminatedAttribute = 1095, kXMLUnterminatedElement = 1096, kXMLUnterminatedProcessingInstruction = 1097, kXMLNamespaceWithPrefixAndNoURI = 1098, kRegExpFlagsArgumentError = 1100, kNoScopeError = 1101, kIllegalDefaultValue = 1102, kCannotExtendFinalClass = 1103, kXMLDuplicateAttribute = 1104, kCorruptABCError = 1107, kInvalidBaseClassError = 1108, kDanglingFunctionError = 1109, kCannotExtendError = 1110, kCannotImplementError = 1111, kCoerceArgumentCountError = 1112, kInvalidNewActivationError = 1113, kNoGlobalScopeError = 1114, kNotConstructorError = 1115, kApplyError = 1116, kXMLInvalidName = 1117, kXMLIllegalCyclicalLoop = 1118, kDeleteTypeError = 1119, kDeleteSealedError = 1120, kDuplicateMethodBodyError = 1121, kIllegalInterfaceMethodBodyError = 1122, kFilterError = 1123, kInvalidHasNextError = 1124, kOutOfRangeError = 1125, kVectorFixedError = 1126, kTypeAppOfNonParamType = 1127, kWrongTypeArgCountError = 1128, kJSONCyclicStructure = 1129, kJSONInvalidReplacer = 1131, kJSONInvalidParseInput = 1132, kFileOpenError = 1500, kFileWriteError = 1501, kScriptTimeoutError = 1502, kScriptTerminatedError = 1503, kEndOfFileError = 1504, kStringIndexOutOfBoundsError = 1505, kInvalidRangeError = 1506, kNullArgumentError = 1507, kInvalidArgumentError = 1508, kArrayFilterNonNullObjectError = 1510, kWorkerAlreadyStarted = 1511, kFailedWorkerCannotBeRestarted = 1512, kWorkerTerminated = 1513, kMutextNotLocked = 1514, kConditionInvalidTimeout = 1515, kConditionCannotNotify = 1516, kConditionCannotNotifyAll = 1517, kConditionCannotWait = 1518, kConditionCannotBeInitialized = 1519, kMutexCannotBeInitialized = 1520, kWorkerIllegalCallToStart = 1521, kInvalidParamError = 2004, kParamRangeError = 2006, kNullPointerError = 2007, kInvalidEnumError = 2008, kCantInstantiateError = 2012, kEOFError = 2030, kCompressedDataError = 2058, kEmptyStringError = 2085, kProxyGetPropertyError = 2088, kProxySetPropertyError = 2089, kProxyCallPropertyError = 2090, kProxyHasPropertyError = 2091, kProxyDeletePropertyError = 2092, kProxyGetDescendantsError = 2093, kProxyNextNameIndexError = 2105, kProxyNextNameError = 2106, kProxyNextValueError = 2107, kInvalidArrayLengthError = 2108, kReadExternalNotImplementedError = 2173, }; extern const std::map errorMessages; }; #endif /* ERRORCONSTANTS_H */ lightspark-0.7.2/src/exceptions.h000066400000000000000000000056521212105246600170200ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef EXCEPTIONS_H #define EXCEPTIONS_H 1 #include "compat.h" #include #include #define STRINGIFY(n) #n #define TOSTRING(x) STRINGIFY(x) #define assert_and_throw(cond) if(!(cond)) \ { \ throw AssertionException(#cond " " __FILE__ ":" TOSTRING(__LINE__)); \ } namespace lightspark { class LightsparkException: public std::exception { public: std::string cause; LightsparkException(const std::string& c):cause(c) { } ~LightsparkException() throw(){} }; class RunTimeException: public LightsparkException { public: RunTimeException(const std::string& c):LightsparkException(c) { } const char* what() const throw() { if(cause.length() == 0) return "Lightspark error"; else return cause.c_str(); } }; class UnsupportedException: public LightsparkException { public: UnsupportedException(const std::string& c):LightsparkException(c) { } const char* what() const throw() { if(cause.length() == 0) return "Lightspark unsupported operation"; else return cause.c_str(); } }; class ParseException: public LightsparkException { public: ParseException(const std::string& c):LightsparkException(c) { } const char* what() const throw() { if(cause.length() == 0) return "Lightspark invalid file"; else return cause.c_str(); } }; class AssertionException: public LightsparkException { public: AssertionException(const std::string& c):LightsparkException(c) { } const char* what() const throw() { if(cause.length() == 0) return "Lightspark hit an unexpected condition"; else return cause.c_str(); } }; class JobTerminationException: public std::exception { public: const char* what() const throw() { return "Job terminated"; } }; class ConfigException: public LightsparkException { public: ConfigException(const std::string& c):LightsparkException(c) { } const char* what() const throw() { if(cause.length() == 0) return "Lightspark invalid configuration file"; else return cause.c_str(); } }; }; #endif /* EXCEPTIONS_H */ lightspark-0.7.2/src/lightspark.expmap000066400000000000000000000011301212105246600200350ustar00rootroot00000000000000{ global: extern "C++" { lightspark::*; Log::*; *zlib_file_filter*; *zlib_filter*; *sync_stream*; *lightspark::Class_base*; *lightspark::Event*; *lightspark::Downloader*; *lightspark::DownloadManager*; *lightspark::StandaloneDownloadManager*; *lightspark::ExtVariant*; *lightspark::ExtIdentifier*; *lightspark::ExtObject*; *lightspark::ExtCallback*; *lightspark::ExtASCallback*; *lightspark::ExtBuiltinCallback*; *lightspark::ExtScriptObject*; *lightspark::EngineData*; rt; sys; pt; NP_*; *tiny_string*; }; local: extern "C++" { *std::*; }; *; }; lightspark-0.7.2/src/lightspark.frag000066400000000000000000000013031212105246600174640ustar00rootroot00000000000000#ifdef GL_ES precision highp float; #endif uniform sampler2D g_tex1, g_tex2; uniform float yuv; uniform float alpha; uniform float direct; varying vec4 ls_TexCoords[2]; varying vec4 ls_FrontColor; const mat3 YUVtoRGB = mat3(1, 1, 1, //First coloumn 0, -0.344, 1.772, //Second coloumn 1.402, -0.714, 0); //Third coloumn void main() { //Tranform the value from YUV to RGB vec4 vbase = texture2D(g_tex1,ls_TexCoords[0].xy); #ifdef GL_ES vbase.rgb = vbase.bgr; #endif vbase *= alpha; vec4 val = vbase.bgra-vec4(0,0.5,0.5,0); val.rgb = YUVtoRGB*(val.rgb); //Select the right value if (direct == 1.0) { gl_FragColor = ls_FrontColor; } else { gl_FragColor=(vbase*(1.0-yuv))+(val*yuv); } } lightspark-0.7.2/src/lightspark.vert000066400000000000000000000010471212105246600175320ustar00rootroot00000000000000attribute vec4 ls_Color; attribute vec2 ls_Vertex; attribute vec2 ls_TexCoord; uniform mat4 ls_ProjectionMatrix; uniform mat4 ls_ModelViewMatrix; uniform vec2 texScale; varying vec4 ls_TexCoords[2]; varying vec4 ls_FrontColor; void main() { // Transforming The Vertex gl_Position=ls_ProjectionMatrix * ls_ModelViewMatrix * vec4(ls_Vertex,0,1); ls_FrontColor=ls_Color; vec4 t=vec4(0,0,0,1); //Position is in normalized screen coords t.xy=((gl_Position.xy+vec2(1,1))/2.0)*texScale; ls_TexCoords[0]=vec4(ls_TexCoord, 0, 1); ls_TexCoords[1]=t; } lightspark-0.7.2/src/logger.cpp000066400000000000000000000034421212105246600164440ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include #include "logger.h" #include "threading.h" using namespace lightspark; static StaticMutex mutex; LOG_LEVEL Log::log_level=LOG_INFO; const char* Log::level_names[]={"ERROR", "INFO","NOT_IMPLEMENTED","CALLS","TRACE"}; int Log::calls_indent = 0; Log::Log(LOG_LEVEL l) { if(l<=log_level) { cur_level=l; valid=true; if(l >= LOG_CALLS) message << std::string(2*calls_indent,' '); } else valid=false; } Log::~Log() { if(valid) { Mutex::Lock l(mutex); std::cerr << level_names[cur_level] << ": " << message.str(); } } std::ostream& Log::operator()() { return message; } void Log::print(const std::string& s) { Mutex::Lock l(mutex); std::cout << s << std::endl; } void Log::redirect(std::string filename) { Mutex::Lock l(mutex); static std::ofstream file(filename); std::cout.rdbuf(file.rdbuf()); std::cerr.rdbuf(file.rdbuf()); } lightspark-0.7.2/src/logger.h000066400000000000000000000046571212105246600161220ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef LOGGER_H #define LOGGER_H 1 #include "compat.h" #include #include #include #include enum LOG_LEVEL { LOG_ERROR=0, LOG_INFO=1, LOG_NOT_IMPLEMENTED=2,LOG_CALLS=3,LOG_TRACE=4}; #define LOG(level,esp) \ do { \ if(level<=Log::getLevel()) \ { \ Log l(level); \ l() << esp << std::endl; \ } \ } while(0) class Log { private: static const char* level_names[]; static LOG_LEVEL log_level DLL_PUBLIC; std::stringstream message; LOG_LEVEL cur_level; bool valid; public: static void print(const std::string& s); Log(LOG_LEVEL l) DLL_PUBLIC; ~Log() DLL_PUBLIC; std::ostream& operator()() DLL_PUBLIC; operator bool() { return valid; } static void setLogLevel(LOG_LEVEL l) { log_level = l; }; static LOG_LEVEL getLevel() {return log_level;} static int calls_indent; /* redirect logging and print() to that file */ static void redirect(std::string filename) DLL_PUBLIC; }; template std::ostream& printContainer(std::ostream& os, const T& v) { os << "["; for (typename T::const_iterator i = v.begin(); i != v.end(); ++i) { if(i != v.begin()) os << " "; os << *i; } os << "]"; return os; } /* convenience function to log std containers */ namespace std { template std::ostream& operator<<(std::ostream& os, const std::vector& v) { return printContainer(os,v); } template std::ostream& operator<<(std::ostream& os, const std::set& v) { return printContainer(os,v); } } #endif /* LOGGER_H */ lightspark-0.7.2/src/main.cpp000066400000000000000000000224131212105246600161100ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2008-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "version.h" #include "backends/security.h" #include "swf.h" #include "logger.h" #include "platforms/engineutils.h" #ifndef _WIN32 # include # include #endif #include "compat.h" using namespace std; using namespace lightspark; class StandaloneEngineData: public EngineData { guint destroyHandlerId; public: StandaloneEngineData() : destroyHandlerId(0) { #ifndef _WIN32 visual = XVisualIDFromVisual(gdk_x11_visual_get_xvisual(gdk_visual_get_system())); #endif } static void destroyWidget(GtkWidget* widget) { gdk_threads_enter(); gtk_widget_destroy(widget); gdk_threads_leave(); } ~StandaloneEngineData() { if(widget) { if(destroyHandlerId) g_signal_handler_disconnect(widget, destroyHandlerId); runInGtkThread(sigc::bind(&destroyWidget,widget)); } } static void StandaloneDestroy(GtkWidget *widget, gpointer data) { StandaloneEngineData* e = reinterpret_cast(data); RecMutex::Lock l(e->mutex); /* no need to destroy it - it's already done */ e->widget = NULL; getSys()->setShutdownFlag(); } GtkWidget* createGtkWidget() { GtkWidget* window=gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title((GtkWindow*)window,"Lightspark"); destroyHandlerId = g_signal_connect(window,"destroy",G_CALLBACK(StandaloneDestroy),this); return window; } GdkNativeWindow getWindowForGnash() { /* passing and invalid window id to gnash makes * it create its own window */ return 0; } void stopMainDownload() {} bool isSizable() const { return true; } void grabFocus() { /* Nothing to do because the standalone main window is * always focused */ } void openPageInBrowser(const tiny_string& url, const tiny_string& window) { LOG(LOG_NOT_IMPLEMENTED, "openPageInBrowser not implemented in the standalone mode"); } }; int main(int argc, char* argv[]) { char* fileName=NULL; char* url=NULL; char* paramsFileName=NULL; #ifdef PROFILING_SUPPORT char* profilingFileName=NULL; #endif char *HTTPcookie=NULL; SecurityManager::SANDBOXTYPE sandboxType=SecurityManager::LOCAL_WITH_FILE; bool useInterpreter=true; bool useFastInterpreter=false; bool useJit=false; SystemState::ERROR_TYPE exitOnError=SystemState::ERROR_PARSING; LOG_LEVEL log_level=LOG_INFO; SystemState::FLASH_MODE flashMode=SystemState::FLASH; setlocale(LC_ALL, ""); #ifdef _WIN32 const char* localedir = getExectuablePath(); #else const char* localedir = "/usr/share/locale"; #endif bindtextdomain("lightspark", localedir); textdomain("lightspark"); LOG(LOG_INFO,"Lightspark version " << VERSION << " Copyright 2009-2013 Alessandro Pignotti and others"); //Make GTK thread enabled #ifdef HAVE_G_THREAD_INIT g_thread_init(NULL); #endif gdk_threads_init(); //Give GTK a chance to parse its own options gtk_init (&argc, &argv); for(int i=1;i"); exit(1); } #ifndef _WIN32 struct rlimit rl; getrlimit(RLIMIT_AS,&rl); rl.rlim_cur=400000000; rl.rlim_max=rl.rlim_cur; //setrlimit(RLIMIT_AS,&rl); #endif Log::setLogLevel(log_level); ifstream f(fileName, ios::in|ios::binary); f.seekg(0, ios::end); uint32_t fileSize=f.tellg(); f.seekg(0, ios::beg); if(!f) { LOG(LOG_ERROR, argv[0] << ": " << fileName << ": No such file or directory"); exit(2); } f.exceptions ( istream::eofbit | istream::failbit | istream::badbit ); cout.exceptions( ios::failbit | ios::badbit); cerr.exceptions( ios::failbit | ios::badbit); SystemState::staticInit(); EngineData::startGTKMain(); //NOTE: see SystemState declaration SystemState* sys = new SystemState(fileSize, flashMode); ParseThread* pt = new ParseThread(f, sys->mainClip); setTLSSys(sys); sys->setDownloadedPath(fileName); //This setting allows qualifying filename-only paths to fully qualified paths //When the URL parameter is set, set the root URL to the given parameter if(url) { sys->mainClip->setOrigin(url, fileName); sys->parseParametersFromURL(sys->mainClip->getOrigin()); sandboxType = SecurityManager::REMOTE; } #ifndef _WIN32 //When running in a local sandbox, set the root URL to the current working dir else if(sandboxType != SecurityManager::REMOTE) { char * cwd = get_current_dir_name(); string cwdStr = string("file://") + string(cwd); free(cwd); cwdStr += "/"; sys->mainClip->setOrigin(cwdStr, fileName); } #endif else { sys->mainClip->setOrigin(string("file://") + fileName); LOG(LOG_INFO, _("Warning: running with no origin URL set.")); } //One of useInterpreter or useJit must be enabled if(!(useInterpreter || useJit)) { LOG(LOG_ERROR,_("No execution model enabled")); exit(1); } sys->useInterpreter=useInterpreter; sys->useFastInterpreter=useFastInterpreter; sys->useJit=useJit; sys->exitOnError=exitOnError; if(paramsFileName) sys->parseParametersFromFile(paramsFileName); #ifdef PROFILING_SUPPORT if(profilingFileName) sys->setProfilingOutput(profilingFileName); #endif if(HTTPcookie) sys->setCookies(HTTPcookie); sys->setParamsAndEngine(new StandaloneEngineData(), true); sys->securityManager->setSandboxType(sandboxType); if(sandboxType == SecurityManager::REMOTE) LOG(LOG_INFO, _("Running in remote sandbox")); else if(sandboxType == SecurityManager::LOCAL_WITH_NETWORK) LOG(LOG_INFO, _("Running in local-with-networking sandbox")); else if(sandboxType == SecurityManager::LOCAL_WITH_FILE) LOG(LOG_INFO, _("Running in local-with-filesystem sandbox")); else if(sandboxType == SecurityManager::LOCAL_TRUSTED) LOG(LOG_INFO, _("Running in local-trusted sandbox")); sys->downloadManager=new StandaloneDownloadManager(); //Start the parser sys->addJob(pt); /* Destroy blocks until the 'terminated' flag is set by * SystemState::setShutdownFlag. */ sys->destroy(); delete pt; delete sys; SystemState::staticDeinit(); EngineData::quitGTKMain(); return 0; } lightspark-0.7.2/src/memory_support.cpp000066400000000000000000000022531212105246600202700ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "memory_support.h" #include "swf.h" using namespace lightspark; #ifdef MEMORY_USAGE_PROFILING MemoryAccount* lightspark::getUnaccountedMemoryAccount() { if(getSys()) return getSys()->unaccountedMemory; else return NULL; } #endif lightspark-0.7.2/src/memory_support.h000066400000000000000000000122171212105246600177360ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef MEMORY_SUPPORT_H #define MEMORY_SUPPORT_H 1 #include "compat.h" #include "tiny_string.h" #include namespace lightspark { #ifdef MEMORY_USAGE_PROFILING class MemoryAccount { public: tiny_string name; ATOMIC_INT32(bytes); /* * The name pointer is not copied and must survive */ MemoryAccount(const tiny_string& n):name(n),bytes(0){} void addBytes(uint32_t b) { ATOMIC_ADD(this->bytes, b); } void removeBytes(uint32_t b) { ATOMIC_SUB(this->bytes, b); } }; //Since global overloaded delete can't be called explicitly, memory reporting is only //enabled using class inheritance class memory_reporter { private: struct objData { uint32_t objSize; MemoryAccount* memoryAccount; }; public: //Placement new and delete inline void* operator new( size_t size, void *p ) { return p; } inline void operator delete( void*, void* ) { } //Regular allocator inline void* operator new( size_t size, MemoryAccount* m) { //Prepend some internal data. //Adding the data to the object itself would not work //since it can be reset by the constructors objData* ret=reinterpret_cast(malloc(size+sizeof(objData))); m->addBytes(size); ret->objSize = size; ret->memoryAccount = m; return ret+1; } inline void operator delete( void* obj ) { //Get back the metadata objData* th=reinterpret_cast(obj)-1; th->memoryAccount->removeBytes(th->objSize); free(th); } }; DLL_PUBLIC MemoryAccount* getUnaccountedMemoryAccount(); template class reporter_allocator: protected std::allocator { template friend class reporter_allocator; template friend bool operator==(const reporter_allocator& a, const reporter_allocator& b); template friend bool operator!=(const reporter_allocator& a, const reporter_allocator& b); private: MemoryAccount* memoryAccount; reporter_allocator(); public: typedef typename std::allocator::size_type size_type; typedef typename std::allocator::value_type value_type; typedef typename std::allocator::difference_type difference_type; typedef typename std::allocator::pointer pointer; typedef typename std::allocator::const_pointer const_pointer; typedef typename std::allocator::reference reference; typedef typename std::allocator::const_reference const_reference; template struct rebind { typedef reporter_allocator other; }; reporter_allocator(MemoryAccount* m):memoryAccount(m) { } template reporter_allocator(const reporter_allocator& o):std::allocator(o), memoryAccount(o.memoryAccount) { } pointer allocate(size_type n, std::allocator::const_pointer hint=0) { if(memoryAccount==NULL) memoryAccount=getUnaccountedMemoryAccount(); memoryAccount->addBytes(n*sizeof(T)); return (pointer)malloc(n*sizeof(T)); } void deallocate(pointer p, size_type n) { memoryAccount->removeBytes(n*sizeof(T)); free(p); } template void construct(pointer p, args&&... vals) { new ((void*)p) T (std::forward(vals)...); } void destroy(pointer p) { (reinterpret_cast(p))->~T(); } size_type max_size() const { return 0x7fffffff; } }; template bool operator==(const reporter_allocator& a, const reporter_allocator& b) { return a.memoryAccount == b.memoryAccount; } template bool operator!=(const reporter_allocator& a, const reporter_allocator& b) { return a.memoryAccount != b.memoryAccount; } #else //MEMORY_USAGE_PROFILING class MemoryAccount; class memory_reporter { public: //Placement new and delete inline void* operator new( size_t size, void *p ) { return p; } inline void operator delete( void*, void* ) { } //Regular allocator inline void* operator new( size_t size, MemoryAccount* m) { return malloc(size); } inline void operator delete( void* obj ) { free(obj); } }; template class reporter_allocator: public std::allocator { public: template struct rebind { typedef reporter_allocator other; }; reporter_allocator(MemoryAccount* m) { } template reporter_allocator(const reporter_allocator& o):std::allocator(o) { } }; #endif //MEMORY_USAGE_PROFILING }; #endif /* MEMORY_SUPPORT_H */ lightspark-0.7.2/src/packed_begin.h000066400000000000000000000017601212105246600172260ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #undef PACKED #define PACKED __attribute__ ((__packed__)) lightspark-0.7.2/src/packed_end.h000066400000000000000000000017041212105246600167060ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #undef PACKED lightspark-0.7.2/src/parsing/000077500000000000000000000000001212105246600161215ustar00rootroot00000000000000lightspark-0.7.2/src/parsing/amf3_generator.cpp000066400000000000000000000213341212105246600215240ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "parsing/amf3_generator.h" #include "scripting/toplevel/toplevel.h" #include "scripting/toplevel/Array.h" #include "scripting/toplevel/ASString.h" #include "scripting/class.h" #include "scripting/flash/xml/flashxml.h" #include "toplevel/XML.h" #include #include using namespace std; using namespace lightspark; _R Amf3Deserializer::readObject() const { vector stringMap; vector objMap; vector traitsMap; return parseValue(stringMap, objMap, traitsMap); } _R Amf3Deserializer::parseInteger() const { uint32_t tmp; if(!input->readU29(tmp)) throw ParseException("Not enough data to parse integer"); return _MR(abstract_i(tmp)); } _R Amf3Deserializer::parseDouble() const { union { uint64_t dummy; double val; } tmp; uint8_t* tmpPtr=reinterpret_cast(&tmp.dummy); for(uint32_t i=0;i<8;i++) { if(!input->readByte(tmpPtr[i])) throw ParseException("Not enough data to parse double"); } tmp.dummy=GINT64_FROM_BE(tmp.dummy); return _MR(abstract_d(tmp.val)); } tiny_string Amf3Deserializer::parseStringVR(std::vector& stringMap) const { uint32_t strRef; if(!input->readU29(strRef)) throw ParseException("Not enough data to parse string"); if((strRef&0x01)==0) { //Just a reference if(stringMap.size() <= (strRef >> 1)) throw ParseException("Invalid string reference in AMF3 data"); return stringMap[strRef >> 1]; } uint32_t strLen=strRef>>1; string retStr; for(uint32_t i=0;ireadByte(c)) throw ParseException("Not enough data to parse string"); retStr.push_back(c); } //Add string to the map, if it's not the empty one if(retStr.size()) stringMap.emplace_back(retStr); return retStr; } _R Amf3Deserializer::parseArray(std::vector& stringMap, std::vector& objMap, std::vector& traitsMap) const { uint32_t arrayRef; if(!input->readU29(arrayRef)) throw ParseException("Not enough data to parse AMF3 array"); if((arrayRef&0x01)==0) { //Just a reference if(objMap.size() <= (arrayRef >> 1)) throw ParseException("Invalid object reference in AMF3 data"); ASObject* ret=objMap[arrayRef >> 1]; ret->incRef(); return _MR(ret); } _R ret=_MR(Class::getInstanceS()); //Add object to the map objMap.push_back(ret.getPtr()); int32_t denseCount = arrayRef >> 1; //Read name, value pairs while(1) { const tiny_string& varName=parseStringVR(stringMap); if(varName=="") break; _R value=parseValue(stringMap, objMap, traitsMap); value->incRef(); ret->setVariableByQName(varName,"",value.getPtr(), DYNAMIC_TRAIT); } //Read the dense portion for(int32_t i=0;i value=parseValue(stringMap, objMap, traitsMap); ret->push(value); } return ret; } _R Amf3Deserializer::parseObject(std::vector& stringMap, std::vector& objMap, std::vector& traitsMap) const { uint32_t objRef; if(!input->readU29(objRef)) throw ParseException("Not enough data to parse AMF3 object"); if((objRef&0x01)==0) { //Just a reference if(objMap.size() <= (objRef >> 1)) throw ParseException("Invalid object reference in AMF3 data"); ASObject* ret=objMap[objRef >> 1]; ret->incRef(); return _MR(ret); } if((objRef&0x07)==0x07) { //Custom serialization const tiny_string& className=parseStringVR(stringMap); assert_and_throw(!className.empty()); const auto it=getSys()->aliasMap.find(className); assert_and_throw(it!=getSys()->aliasMap.end()); Class_base* type=it->second.getPtr(); traitsMap.push_back(TraitsRef(type)); _R ret=_MR(type->getInstance(true, NULL, 0)); //Invoke readExternal multiname readExternalName(NULL); readExternalName.name_type=multiname::NAME_STRING; readExternalName.name_s_id=getSys()->getUniqueStringId("readExternal"); readExternalName.ns.push_back(nsNameAndKind("",NAMESPACE)); readExternalName.isAttribute = false; _NR o=ret->getVariableByMultiname(readExternalName,ASObject::SKIP_IMPL); assert_and_throw(!o.isNull() && o->getObjectType()==T_FUNCTION); IFunction* f=o->as(); ret->incRef(); input->incRef(); ASObject* const tmpArg[1] = {input}; f->call(ret.getPtr(), tmpArg, 1); return ret; } TraitsRef traits(NULL); if((objRef&0x02)==0) { uint32_t traitsRef=objRef>>2; if(traitsMap.size() <= traitsRef) throw ParseException("Invalid traits reference in AMF3 data"); traits=traitsMap[traitsRef]; } else { traits.dynamic = objRef&0x08; uint32_t traitsCount=objRef>>4; const tiny_string& className=parseStringVR(stringMap); //Add the type to the traitsMap for(uint32_t i=0;ialiasMap.find(className); if(it!=getSys()->aliasMap.end()) traits.type=it->second.getPtr(); traitsMap.emplace_back(traits); } _R ret=_MR((traits.type)?traits.type->getInstance(true, NULL, 0): Class::getInstanceS()); //Add object to the map objMap.push_back(ret.getPtr()); for(uint32_t i=0;i value=parseValue(stringMap, objMap, traitsMap); value->incRef(); multiname name(NULL); name.name_type=multiname::NAME_STRING; name.name_s_id=getSys()->getUniqueStringId(traits.traitsNames[i]); name.ns.push_back(nsNameAndKind("",NAMESPACE)); name.isAttribute=false; ret->setVariableByMultiname(name,value.getPtr(),ASObject::CONST_ALLOWED,traits.type); } //Read dynamic name, value pairs while(traits.dynamic) { const tiny_string& varName=parseStringVR(stringMap); if(varName=="") break; _R value=parseValue(stringMap, objMap, traitsMap); value->incRef(); ret->setVariableByQName(varName,"",value.getPtr(),DYNAMIC_TRAIT); } return ret; } _R Amf3Deserializer::parseXML(std::vector& objMap, bool legacyXML) const { uint32_t xmlRef; if(!input->readU29(xmlRef)) throw ParseException("Not enough data to parse XML"); if((xmlRef&0x01)==0) { //Just a reference if(objMap.size() <= (xmlRef >> 1)) throw ParseException("Invalid XML reference in AMF3 data"); ASObject *xmlObj = objMap[xmlRef >> 1]; xmlObj->incRef(); return _MR(xmlObj); } uint32_t strLen=xmlRef>>1; string xmlStr; for(uint32_t i=0;ireadByte(c)) throw ParseException("Not enough data to parse string"); xmlStr.push_back(c); } ASObject *xmlObj; if(legacyXML) xmlObj=Class::getInstanceS(xmlStr); else xmlObj=Class::getInstanceS(xmlStr); objMap.push_back(xmlObj); return _MR(xmlObj); } _R Amf3Deserializer::parseValue(std::vector& stringMap, std::vector& objMap, std::vector& traitsMap) const { //Read the first byte as it contains the object marker uint8_t marker; if(!input->readByte(marker)) throw ParseException("Not enough data to parse AMF3 object"); switch(marker) { case null_marker: return _MR(getSys()->getNullRef()); case undefined_marker: return _MR(getSys()->getUndefinedRef()); case false_marker: return _MR(abstract_b(false)); case true_marker: return _MR(abstract_b(true)); case integer_marker: return parseInteger(); case double_marker: return parseDouble(); case string_marker: return _MR(Class::getInstanceS(parseStringVR(stringMap))); case xml_doc_marker: return parseXML(objMap, true); case array_marker: return parseArray(stringMap, objMap, traitsMap); case object_marker: return parseObject(stringMap, objMap, traitsMap); case xml_marker: return parseXML(objMap, false); default: LOG(LOG_ERROR,"Unsupported marker " << (uint32_t)marker); throw UnsupportedException("Unsupported marker"); } } lightspark-0.7.2/src/parsing/amf3_generator.h000066400000000000000000000047361212105246600212000ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) Copyright (C) 2010 Ennio Barbaro (e.barbaro@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef PARSING_AMF3_GENERATOR_H #define PARSING_AMF3_GENERATOR_H 1 #include #include #include "compat.h" #include "swftypes.h" #include "smartrefs.h" #include "asobject.h" namespace lightspark { class ASObject; class ByteArray; enum markers_type { undefined_marker = 0x0, null_marker = 0x1, false_marker = 0x2, true_marker = 0x3, integer_marker = 0x4, double_marker = 0x5, string_marker = 0x6, xml_doc_marker = 0x7, date_marker = 0x8, array_marker = 0x9, object_marker = 0xa, xml_marker = 0xb }; class TraitsRef { public: Class_base* type; std::vector traitsNames; bool dynamic; TraitsRef(Class_base* t):type(t),dynamic(false){} }; class Amf3Deserializer { private: ByteArray* input; tiny_string parseStringVR(std::vector& stringMap) const; _R parseObject(std::vector& stringMap, std::vector& objMap, std::vector& traitsMap) const; _R parseArray(std::vector& stringMap, std::vector& objMap, std::vector& traitsMap) const; _R parseValue(std::vector& stringMap, std::vector& objMap, std::vector& traitsMap) const; _R parseInteger() const; _R parseDouble() const; _R parseXML(std::vector& objMap, bool legacyXML) const; public: Amf3Deserializer(ByteArray* i):input(i) {} _R readObject() const; }; }; #endif /* PARSING_AMF3_GENERATOR_H */ lightspark-0.7.2/src/parsing/config.cpp000066400000000000000000000063011212105246600200720ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "parsing/config.h" #include "compat.h" using namespace lightspark; ConfigParser::ConfigParser(const std::string& filename): valid(true),file(g_key_file_new()), groups(NULL),groupCount(0),currentGroup(0), keys(NULL),keyCount(0),currentKey(0), group(NULL),key(NULL) { if(!g_key_file_load_from_file(file, filename.c_str(), G_KEY_FILE_NONE, NULL)) valid = false; else groups = g_key_file_get_groups(file, &groupCount); } ConfigParser::~ConfigParser() { if(groups != NULL) g_strfreev(groups); if(keys != NULL) g_strfreev(keys); if(file != NULL) g_key_file_free(file); } bool ConfigParser::read() { //This parser is invalid or there are no groups if(!valid || groupCount == 0) return false; //We encountered the first group or have handled the last key in a group if((currentGroup == 0 && currentKey == 0) || (currentKey == keyCount && currentGroup < groupCount-1)) { if(currentGroup == 0 && currentKey == 0) keys = g_key_file_get_keys(file, groups[currentGroup], &keyCount, NULL); else { currentKey = 0; ++currentGroup; g_strfreev(keys); keys = g_key_file_get_keys(file, groups[currentGroup], &keyCount, NULL); } while(keyCount == 0 && currentGroup < groupCount-1) { ++currentGroup; g_strfreev(keys); keys = g_key_file_get_keys(file, groups[currentGroup], &keyCount, NULL); } group = groups[currentGroup]; } //We encountered the end of the file if(currentGroup == groupCount-1 && currentKey == keyCount) return false; //We have a valid currentKey/currentGroup pair, lets set the current key key = keys[currentKey]; //Increment currentKey for next round of reading ++currentKey; return true; } std::string ConfigParser::getValue() { char *val = g_key_file_get_value(file, group, key, NULL); std::string ret(val); free(val); return ret; } std::string ConfigParser::getValueString() { char *val = g_key_file_get_string(file, group, key, NULL); std::string ret(val); free(val); return ret; } std::vector ConfigParser::getValueStringList() { std::vector ret; gsize length; gchar **valarr = g_key_file_get_string_list(file, group, key, &length, NULL); if(!valarr) return ret; for(gsize i=0; i. **************************************************************************/ #ifndef PARSING_CONFIG_H #define PARSING_CONFIG_H 1 #include #include #include namespace lightspark { class ConfigParser { private: bool valid; GKeyFile* file; char** groups; gsize groupCount; gsize currentGroup; char** keys; gsize keyCount; gsize currentKey; //Status char* group; char* key; public: //Load a config from a file ConfigParser(const std::string& filename); ~ConfigParser(); bool isValid() { return valid; } bool read(); //These properties and their return types are only valid until the next read() //They should be copied before use std::string getGroup() { return group; } std::string getKey() { return key; } std::string getValue(); std::string getValueString(); std::vector getValueStringList(); bool getValueBoolean() { return (bool)g_key_file_get_boolean(file, group, key, NULL); } bool* getValueBooleanList(gsize* length) { return (bool*)g_key_file_get_boolean_list(file, group, key, length, NULL); } int getValueInteger() { return g_key_file_get_integer(file, group, key, NULL); } const int* getValueIntegerList(gsize* length) { return g_key_file_get_integer_list(file, group, key, length, NULL); } double getValueDouble() { return g_key_file_get_double(file, group, key, NULL); } const double* getValueDoubleList(gsize* length) { return g_key_file_get_double_list(file, group, key, length, NULL); } }; } #endif /* PARSING_CONFIG_H */ lightspark-0.7.2/src/parsing/crossdomainpolicy.cpp000066400000000000000000000102071212105246600223660ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "parsing/crossdomainpolicy.h" using namespace lightspark; CrossDomainPolicy::CrossDomainPolicy(const unsigned char* buffer, size_t length, POLICYFILETYPE _type, POLICYFILESUBTYPE _subtype, bool _master): xml(buffer, length),type(_type),subtype(_subtype),master(_master),siteControlFound(false) { } CrossDomainPolicy::ELEMENT CrossDomainPolicy::getNextElement() { try { while(xml.read()) { depth = xml.get_depth(); tagName = xml.get_name(); attrCount = xml.get_attribute_count(); //We only handle elements if(xml.get_node_type() != xmlpp::TextReader::Element) continue; //Some reasons for marking this file as invalid (extraneous content) if(depth > 1 || xml.has_value() || (depth == 0 && tagName != "cross-domain-policy")) { return INVALID; } //The root element doesn't need handling if(depth == 0 && tagName == "cross-domain-policy") continue; //We are inside the cross-domain-policy tag so lets handle elements. //Handle the site-control element, if this is a master file and if the element has attributes if(tagName == "site-control") { if(!siteControlFound && master && attrCount == 1) { siteControlFound = true; permittedPolicies = xml.get_attribute("permitted-cross-domain-policies"); //Found the required attribute, passing control if(permittedPolicies != "") return SITE_CONTROL; else return INVALID; } else return INVALID; } //Handle the allow-access-from element if the element has attributes else if(tagName == "allow-access-from") { if(attrCount >= 1 && attrCount <= 3) { domain = xml.get_attribute("domain"); toPorts = xml.get_attribute("to-ports"); secure = false; secureSpecified = false; if(xml.get_attribute("secure") == "false") { secure = false; secureSpecified = true; } else if(xml.get_attribute("secure") == "true") { secure = true; secureSpecified = true; } //We found one of the required attributes, passing control if(type == URL && domain != "") return ALLOW_ACCESS_FROM; else if(type == SOCKET && domain != "" && toPorts != "") return ALLOW_ACCESS_FROM; else return INVALID; } else return INVALID; } //Handle the allow-http-request-headers-from element if the element has attributes and if the policy file type is HTTP(S) else if(tagName == "allow-http-request-headers-from") { if(type == URL && (subtype == HTTP || subtype == HTTPS) && attrCount >= 2 && attrCount <= 3) { domain = xml.get_attribute("domain"); headers = xml.get_attribute("headers"); secure = false; secureSpecified = false; if(xml.get_attribute("secure") == "false") { secure = false; secureSpecified = true; } else if(xml.get_attribute("secure") == "true") { secure = true; secureSpecified = true; } //We found the required attributes, passing control if(domain != "" && headers != "") return ALLOW_HTTP_REQUEST_HEADERS_FROM; else return INVALID; } else return INVALID; } } } catch (xmlpp::parse_error&) { // Invalid XML return INVALID; } return END; } lightspark-0.7.2/src/parsing/crossdomainpolicy.h000066400000000000000000000051371212105246600220410ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2010-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef PARSING_CROSSDOMAINPOLICY_H #define PARSING_CROSSDOMAINPOLICY_H 1 #include #include #include "compat.h" #include #include "swftypes.h" namespace lightspark { class CrossDomainPolicy { public: enum POLICYFILETYPE { URL, SOCKET }; enum POLICYFILESUBTYPE { NONE, HTTP, HTTPS, FTP }; private: xmlpp::TextReader xml; POLICYFILETYPE type; POLICYFILESUBTYPE subtype; bool master; //Ease-of-use variables int depth; std::string tagName; int attrCount; std::string attrValue; bool siteControlFound; //Parsed element attributes //site-control std::string permittedPolicies; //allow-access-from & allow-http-request-headers-from std::string domain; bool secure; bool secureSpecified; //allow-access-from std::string toPorts; //allow-http-request-headers-from std::string headers; public: CrossDomainPolicy(const unsigned char* buffer, size_t length, POLICYFILETYPE _type, POLICYFILESUBTYPE _subtype, bool _master); enum ELEMENT { END, INVALID, SITE_CONTROL, ALLOW_ACCESS_FROM, ALLOW_HTTP_REQUEST_HEADERS_FROM }; ELEMENT getNextElement(); //site-control const std::string& getPermittedPolicies() const { return permittedPolicies; } //allow-access-from & allow-http-request-headers-from const std::string& getDomain() const { return domain; } bool getSecure() const { return secure; }; bool getSecureSpecified() const { return secureSpecified; } //allow-access-from const std::string& getToPorts() const { return toPorts; } //allow-http-request-headers-from const std::string& getHeaders() const { return headers; } }; } #endif /* PARSING_CROSSDOMAINPOLICY_H */ lightspark-0.7.2/src/parsing/flv.cpp000066400000000000000000000155601212105246600174230ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "parsing/flv.h" #include "swftypes.h" #include "compat.h" using namespace lightspark; using namespace std; FLV_HEADER::FLV_HEADER(std::istream& in):dataOffset(0),_hasAudio(false),_hasVideo(false) { UI8 Signature[3]; UI8 Version; UI32_FLV DataOffset; in >> Signature[0] >> Signature[1] >> Signature[2] >> Version; version=Version; if(Signature[0]=='F' && Signature[1]=='L' && Signature[2]=='V') { LOG(LOG_INFO, _("PARSING: FLV file: Version ") << (int)Version); valid=true; } else { LOG(LOG_INFO,_("PARSING: No FLV file signature found")); valid=false; return; } BitStream bs(in); if(UB(5, bs)!=0) { valid=false; return; } _hasAudio=UB(1, bs); if(UB(1, bs)!=0) { valid=false; return; } _hasVideo=UB(1, bs); in >> DataOffset; dataOffset = DataOffset; assert_and_throw(dataOffset==9); } VideoTag::VideoTag(istream& s) { //Read dataSize UI24_FLV DataSize; s >> DataSize; dataSize=DataSize; //Read and assemble timestamp UI24_FLV Timestamp; s >> Timestamp; UI8 TimestampExtended; s >> TimestampExtended; timestamp=Timestamp|(TimestampExtended<<24); UI24_FLV StreamID; s >> StreamID; assert_and_throw(StreamID==0); } ScriptDataTag::ScriptDataTag(istream& s):VideoTag(s) { unsigned int start=s.tellg(); tiny_string methodName; //Specs talks about an arbitrary number of stuff, actually just a string and an array are expected UI8 Type; s >> Type; if(Type!=2) throw ParseException("Unexpected type in FLV"); ScriptDataString String(s); methodName=String.getString(); s >> Type; if(Type!=8) throw ParseException("Unexpected type in FLV"); ScriptECMAArray ecmaArray(s, this); //Compute totalLen unsigned int end=s.tellg(); totalLen=(end-start)+11; } ScriptDataString::ScriptDataString(std::istream& s) { UI16_FLV Length; s >> Length; size=Length; //TODO: use resize on tiny_string char* buf=new char[Length+1]; s.read(buf,Length); buf[Length]=0; val=tiny_string(buf,true); delete[] buf; } ScriptECMAArray::ScriptECMAArray(std::istream& s, ScriptDataTag* tag) { //numVar is an 'approximation' of array size UI32_FLV numVar; s >> numVar; while(1) { ScriptDataString varName(s); //cout << varName.getString() << endl; UI8 Type; s >> Type; switch(Type) { case 0: //double (big-endian) { union { uint64_t i; double d; } tmp; s.read((char*)&tmp.i,8); tmp.i=GINT64_FROM_BE(tmp.i); tag->metadataDouble[varName.getString()] = tmp.d; //cout << "FLV metadata double: " << varName.getString() << " = " << tmp.d << endl; break; } case 1: //integer { UI8 b; s >> b; tag->metadataInteger[varName.getString()] = int(b); //cout << "FLV metadata int: " << varName.getString() << " = " << (int)b << endl; break; } case 2: //string { ScriptDataString String(s); tag->metadataString[varName.getString()] = String.getString(); //cout << "FLV metadata string: " << varName.getString() << " = " << String.getString() << endl; break; } case 9: //End of array { return; } default: LOG(LOG_ERROR,"Unknown type in flv parsing: " << (int)Type); throw ParseException("Unexpected type in FLV"); } } } VideoDataTag::VideoDataTag(istream& s):VideoTag(s),_isHeader(false),packetData(NULL) { unsigned int start=s.tellg(); UI8 typeAndCodec; s >> typeAndCodec; frameType=(typeAndCodec>>4); int codecId=(typeAndCodec&0xf); if(frameType!=1 && frameType!=2) throw ParseException("Unexpected frameType in FLV"); assert_and_throw(codecId==2 || codecId==4 || codecId==7); if(codecId==2) { codec=H263; //H263 video packet //Compute lenght of raw data packetLen=dataSize-1; aligned_malloc((void**)&packetData, 16, packetLen+16); //Ensure no overrun happens when doing aligned reads s.read((char*)packetData,packetLen); memset(packetData+packetLen,0,16); } else if(codecId==4) { codec=VP6; //VP6 video packet uint8_t adjustment; s.read((char*)&adjustment,1); //TODO: support adjustment (FFMPEG accept extradata for it) assert(adjustment==0); //Compute lenght of raw data packetLen=dataSize-2; aligned_malloc((void**)&packetData, 16, packetLen+16); //Ensure no overrun happens when doing aligned reads s.read((char*)packetData,packetLen); memset(packetData+packetLen,0,16); } else if(codecId==7) { codec=H264; //AVCVideoPacket UI8 packetType; s >> packetType; switch(packetType) { case 0: //Sequence header _isHeader=true; break; case 1: //NALU case 2: //End of sequence break; default: throw UnsupportedException("Unexpected packet type in FLV"); } SI24_FLV CompositionTime; s >> CompositionTime; assert_and_throw(CompositionTime==0); //TODO: what are composition times //Compute lenght of raw data packetLen=dataSize-5; aligned_malloc((void**)&packetData, 16, packetLen+16); //Ensure no overrun happens when doing aligned reads s.read((char*)packetData,packetLen); memset(packetData+packetLen,0,16); } //Compute totalLen unsigned int end=s.tellg(); totalLen=(end-start)+11; } VideoDataTag::~VideoDataTag() { aligned_free(packetData); } AudioDataTag::AudioDataTag(std::istream& s):VideoTag(s),_isHeader(false) { unsigned int start=s.tellg(); BitStream bs(s); SoundFormat=(LS_AUDIO_CODEC)(int)UB(4,bs); switch(UB(2,bs)) { case 0: SoundRate=5500; break; case 1: SoundRate=11000; break; case 2: SoundRate=22000; break; case 3: SoundRate=44000; break; } is16bit=UB(1,bs); isStereo=UB(1,bs); uint32_t headerConsumed=1; //Special handling for AAC data if(SoundFormat==AAC) { UI8 t; s >> t; _isHeader=(t==0); headerConsumed++; } packetLen=dataSize-headerConsumed; aligned_malloc((void**)&packetData, 16, packetLen+16); //Ensure no overrun happens when doing aligned reads s.read((char*)packetData,packetLen); memset(packetData+packetLen,0,16); //Compute totalLen unsigned int end=s.tellg(); totalLen=(end-start)+11; } AudioDataTag::~AudioDataTag() { aligned_free(packetData); } lightspark-0.7.2/src/parsing/flv.h000066400000000000000000000056631212105246600170730ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #ifndef PARSING_FLV_H #define PARSING_FLV_H 1 #include "compat.h" #include #include #include "swftypes.h" #include "backends/decoder.h" namespace lightspark { class FLV_HEADER { private: unsigned int dataOffset; unsigned int version; bool valid; bool _hasAudio; bool _hasVideo; public: FLV_HEADER(std::istream& in); unsigned int skipAmount() const {return dataOffset;} bool isValid() const { return valid; } bool hasAudio() const { return _hasAudio; } bool hasVideo() const { return _hasVideo; } }; class VideoTag { protected: uint32_t dataSize; uint32_t timestamp; uint32_t totalLen; public: VideoTag() {}; VideoTag(std::istream& s); uint32_t getDataSize() const { return dataSize; } uint32_t getTotalLen() const { return totalLen; } }; class ScriptDataTag: public VideoTag { public: //Metadatas std::map metadataDouble; std::map metadataInteger; std::map metadataString; ScriptDataTag() {}; ScriptDataTag(std::istream& s); }; class ScriptDataString { private: uint32_t size; tiny_string val; public: ScriptDataString(std::istream& s); const tiny_string& getString() const { return val; } uint32_t getSize() const { return size; } }; class ScriptECMAArray { public: ScriptECMAArray(std::istream& s, ScriptDataTag* tag); }; class VideoDataTag: public VideoTag { private: bool _isHeader; public: int frameType; LS_VIDEO_CODEC codec; uint8_t* packetData; uint32_t packetLen; VideoDataTag(std::istream& s); void releaseBuffer() { packetData=NULL; packetLen=0; } ~VideoDataTag(); bool isHeader() const { return _isHeader; } }; class AudioDataTag: public VideoTag { private: bool _isHeader; public: LS_AUDIO_CODEC SoundFormat; uint32_t SoundRate; bool is16bit; bool isStereo; uint8_t* packetData; uint32_t packetLen; AudioDataTag(std::istream& s); ~AudioDataTag(); void releaseBuffer() { packetData=NULL; packetLen=0; } bool isHeader() const { return _isHeader; } }; }; #endif /* PARSING_FLV_H */ lightspark-0.7.2/src/parsing/streams.cpp000066400000000000000000000170261212105246600203110ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2009-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include "parsing/streams.h" #include "logger.h" #include "exceptions.h" #include "compat.h" #include "class.h" #include "toplevel/Error.h" #include #include #include #define LZMA_PROP_LENGTH 5 using namespace std; uncompressing_filter::uncompressing_filter(streambuf* b):backend(b),consumed(0),eof(false) { } int uncompressing_filter::underflow() { assert(gptr()==egptr()); if(eof) return -1; //First of all we add the length of the buffer to the consumed variable consumed+=(gptr()-eback()); int available=fillBuffer(); setg(buffer,buffer,buffer+available); //Cast to unsigned, otherwise 0xff would become eof return (unsigned char)buffer[0]; } streampos uncompressing_filter::seekoff(off_type off, ios_base::seekdir dir,ios_base::openmode mode) { assert(off==0); assert(dir==ios_base::cur); //The current offset is the amount of byte completely consumed plus the amount used in the buffer int ret=consumed+(gptr()-eback()); return ret; } zlib_filter::zlib_filter(streambuf* b):uncompressing_filter(b) { strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = 0; strm.next_in = Z_NULL; int ret = inflateInit(&strm); if (ret != Z_OK) throw lightspark::RunTimeException("Failed to initialize ZLib"); setg(buffer,buffer,buffer); consumed+=pubseekoff(0, ios_base::cur, ios_base::in); } zlib_filter::~zlib_filter() { inflateEnd(&strm); } int zlib_filter::fillBuffer() { strm.avail_out = sizeof(buffer); strm.next_out = (unsigned char*)buffer; do { if(strm.avail_in==0) { int real_count=backend->sgetn(compressed_buffer,sizeof(compressed_buffer)); if(real_count==0) { //File is not big enough throw lightspark::ParseException("Unexpected end of file"); } strm.next_in=(unsigned char*)compressed_buffer; strm.avail_in=real_count; } int ret=inflate(&strm, Z_NO_FLUSH); if(ret==Z_STREAM_END) { //The stream ended, close the buffer here eof=true; break; } else if (ret!=Z_OK) throw lightspark::ParseException("Unexpected Zlib error"); } while(strm.avail_out!=0); return sizeof(buffer) - strm.avail_out; } bytes_buf::bytes_buf(const uint8_t* b, int l):buf(b),offset(0),len(l) { setg((char*)buf,(char*)buf,(char*)buf+len); } bytes_buf::pos_type bytes_buf::seekoff(off_type off, ios_base::seekdir dir,ios_base::openmode mode) { assert(off==0); //The current offset is the amount used in the buffer int ret=(gptr()-eback()); return ret; } liblzma_filter::liblzma_filter(streambuf* b):uncompressing_filter(b) { strm = LZMA_STREAM_INIT; lzma_ret ret = lzma_alone_decoder(&strm, UINT64_MAX); if (ret != LZMA_OK) throw lightspark::RunTimeException("Failed to initialize lzma decoder"); setg((char*)buffer, (char*)buffer, (char*)buffer); consumed+=pubseekoff(0, ios_base::cur, ios_base::in); // First 32 bit uint is the compressed file length, which we // ignore streamsize nbytes=backend->sgetn((char *)compressed_buffer,sizeof(uint32_t)); if (nbytes != sizeof(uint32_t)) throw lightspark::ParseException("Unexpected end of file"); /* SWF uses a deprecated (pre-5.0?) LZMA SDK stream format, * which differs slightly from the newer liblzma's lzma_alone * format. The both begin with 5 byte property data. The * lzma_alone continues with a 64 bit int uncompressed file * length variable, which is missing from the older format. * And then both contain the compressed LZMA data, which ends * with a LZMA end-of-payload marker. * * To process the stream with liblzma, we append the length * variable here manually. A special value 0xFFFF FFFF FFFF * FFFF means that the uncompressed length is unknown. */ assert(LZMA_PROP_LENGTH + sizeof(int64_t) < sizeof(compressed_buffer)); nbytes=backend->sgetn((char *)compressed_buffer,LZMA_PROP_LENGTH); if (nbytes != LZMA_PROP_LENGTH) throw lightspark::ParseException("Unexpected end of file"); for (unsigned int i=0; isgetn((char *)compressed_buffer,sizeof(compressed_buffer)); if(real_count==0) { //File is not big enough throw lightspark::ParseException("Unexpected end of file"); } strm.next_in=compressed_buffer; strm.avail_in=real_count; } lzma_ret ret=lzma_code(&strm, LZMA_RUN); if(ret==LZMA_STREAM_END) { //The stream ended, close the buffer here eof=true; break; } else if(ret!=LZMA_OK) { char errmsg[64]; snprintf(errmsg, 64, "lzma decoder error %d", (int)ret); throw lightspark::ParseException(errmsg); } } while(strm.avail_out!=0); return sizeof(buffer) - strm.avail_out; } memorystream::memorystream(const char* const b, unsigned int l) : code(b), len(l), pos(0), read_past_end(false) { } unsigned int memorystream::tellg() const { return pos; } void memorystream::seekg(unsigned int offset) { if (offset > len) pos = len; else pos = offset; } unsigned int memorystream::size() const { return len; } void memorystream::read(char *out, unsigned int nbytes) { if ((nbytes == 1) && (pos+1 > len)) { // fastpath for one bytes reads *out = code[pos]; pos++; } else if (pos+nbytes > len) { memcpy(out, code+pos, len-pos); pos = len; read_past_end = true; } else { memcpy(out, code+pos, nbytes); pos += nbytes; } } bool memorystream::eof() const { return read_past_end; } memorystream& lightspark::operator>>(memorystream& in, lightspark::u8& v) { uint8_t t; in.read((char*)&t,1); v.val= t; return in; } memorystream& lightspark::operator>>(memorystream& in, lightspark::s24& v) { uint32_t ret=0; in.read((char*)&ret,3); v.val=LittleEndianToSignedHost24(ret); return in; } memorystream& lightspark::operator>>(memorystream& in, lightspark::u30& v) { lightspark::u32 vv; in >> vv; uint32_t val = vv; if(val&0xc0000000) throw lightspark::Class::getInstanceS("Invalid u30"); v.val = val; return in; } memorystream& lightspark::operator>>(memorystream& in, lightspark::u32& v) { int i=0; uint32_t val=0; uint8_t t; do { in.read((char*)&t,1); //No more than 5 bytes should be read if(i==28) { //Only the first 4 bits should be used to reach 32 bits if((t&0xf0)) LOG(LOG_ERROR,"Error in u32"); uint8_t t2=(t&0xf); val|=(t2<. **************************************************************************/ #ifndef PARSING_STREAMS_H #define PARSING_STREAMS_H 1 #include "compat.h" #include "abctypes.h" #include "swftypes.h" #include #include #include #include #include class uncompressing_filter: public std::streambuf { protected: static const unsigned int BUFFER_LENGTH = 4096; // The compressed input data stream std::streambuf* backend; // Current uncompressed bytes (accessible input sequence in // std::streambuf terminology) char buffer[BUFFER_LENGTH]; // Total number of uncompressed read bytes not including the // bytes read from the current buffer. int consumed; bool eof; virtual int underflow(); virtual std::streampos seekoff(off_type, std::ios_base::seekdir, std::ios_base::openmode); // Abstract function that fills buffer by uncompressing bytes // from backend. buffer is empty when this is called. Returns // number of bytes written to buffer. virtual int fillBuffer()=0; public: uncompressing_filter(std::streambuf* b); }; class zlib_filter: public uncompressing_filter { private: z_stream strm; // Temporary buffer for data before it is uncompressed char compressed_buffer[BUFFER_LENGTH]; protected: virtual int fillBuffer(); public: zlib_filter(std::streambuf* b); ~zlib_filter(); }; class liblzma_filter: public uncompressing_filter { private: lzma_stream strm; // Temporary buffer for data before it is uncompressed uint8_t compressed_buffer[BUFFER_LENGTH]; protected: virtual int fillBuffer(); public: liblzma_filter(std::streambuf* b); ~liblzma_filter(); }; class bytes_buf:public std::streambuf { private: const uint8_t* buf; int offset; int len; public: bytes_buf(const uint8_t* b, int l); virtual pos_type seekoff(off_type, std::ios_base::seekdir, std::ios_base::openmode); }; // A lightweight, istream-like interface for reading from a memory // buffer. // // This is used in the interpreter for reading bytecode because this // is faster than istringstream. class memorystream { private: const char* const code; unsigned int len; unsigned int pos; bool read_past_end; public: // Create a stream from a buffer b. // // The buffer is not copied, so b must continue to exists for // the life-time of this memorystream instance. memorystream(const char* const b, unsigned int l); unsigned int size() const; unsigned int tellg() const; void seekg(unsigned int offset); void read(char *out, unsigned int nbytes); bool eof() const; }; memorystream& lightspark::operator>>(memorystream& in, lightspark::u8& v); memorystream& lightspark::operator>>(memorystream& in, lightspark::s24& v); memorystream& lightspark::operator>>(memorystream& in, lightspark::u30& v); memorystream& lightspark::operator>>(memorystream& in, lightspark::u32& v); #endif /* PARSING_STREAMS_H */ lightspark-0.7.2/src/parsing/tags.cpp000066400000000000000000001256101212105246600175700ustar00rootroot00000000000000/************************************************************************** Lightspark, a free flash player implementation Copyright (C) 2008-2013 Alessandro Pignotti (a.pignotti@sssup.it) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . **************************************************************************/ #include #include #include #include #include #include #include "scripting/abc.h" #include "parsing/tags.h" #include "backends/geometry.h" #include "backends/security.h" #include "swftypes.h" #include "logger.h" #include "compat.h" #include "parsing/streams.h" #include "scripting/flash/display/BitmapData.h" #include "scripting/flash/text/flashtext.h" #include "scripting/flash/media/flashmedia.h" #undef RGB // BitmapFormat values in DefineBitsLossless(2) tag #define LOSSLESS_BITMAP_PALETTE 3 #define LOSSLESS_BITMAP_RGB15 4 #define LOSSLESS_BITMAP_RGB24 5 using namespace std; using namespace lightspark; uint8_t* JPEGTablesTag::JPEGTables = NULL; int JPEGTablesTag::tableSize = 0; Tag* TagFactory::readTag(RootMovieClip* root) { RECORDHEADER h; //Catch eofs try { f >> h; } catch (ifstream::failure& e) { if(!f.eof()) //Only handle eof throw; f.clear(); LOG(LOG_INFO,"Simulating EndTag at EOF @ " << f.tellg()); return new EndTag(h,f); } unsigned int expectedLen=h.getLength(); unsigned int start=f.tellg(); Tag* ret=NULL; LOG(LOG_TRACE,_("Reading tag type: ") << h.getTagType() << _(" at byte ") << start << _(" with length ") << expectedLen << _(" bytes")); switch(h.getTagType()) { case 0: ret=new EndTag(h,f); break; case 1: ret=new ShowFrameTag(h,f); break; case 2: ret=new DefineShapeTag(h,f,root); break; // case 4: // ret=new PlaceObjectTag(h,f); case 6: ret=new DefineBitsTag(h,f,root); break; case 7: ret=new DefineButtonTag(h,f,1,root); break; case 8: ret=new JPEGTablesTag(h,f); break; case 9: ret=new SetBackgroundColorTag(h,f); break; case 10: ret=new DefineFontTag(h,f,root); break; case 11: ret=new DefineTextTag(h,f,root); break; case 13: ret=new DefineFontInfoTag(h,f); break; case 14: ret=new DefineSoundTag(h,f,root); break; case 15: ret=new StartSoundTag(h,f); break; case 18: ret=new SoundStreamHeadTag(h,f); break; case 19: ret=new SoundStreamBlockTag(h,f); break; case 20: ret=new DefineBitsLosslessTag(h,f,1,root); break; case 21: ret=new DefineBitsJPEG2Tag(h,f,root); break; case 22: ret=new DefineShape2Tag(h,f,root); break; case 24: ret=new ProtectTag(h,f); break; case 26: ret=new PlaceObject2Tag(h,f,root); break; case 28: ret=new RemoveObject2Tag(h,f); break; case 32: ret=new DefineShape3Tag(h,f,root); break; case 33: ret=new DefineText2Tag(h,f,root); break; case 34: ret=new DefineButtonTag(h,f,2,root); break; case 35: ret=new DefineBitsJPEG3Tag(h,f,root); break; case 36: ret=new DefineBitsLosslessTag(h,f,2,root); break; case 37: ret=new DefineEditTextTag(h,f,root); break; case 39: ret=new DefineSpriteTag(h,f,root); break; case 41: ret=new ProductInfoTag(h,f); break; case 43: ret=new FrameLabelTag(h,f); break; case 45: ret=new SoundStreamHead2Tag(h,f); break; case 46: ret=new DefineMorphShapeTag(h,f,root); break; case 48: ret=new DefineFont2Tag(h,f,root); break; case 58: ret=new EnableDebuggerTag(h,f); break; case 60: ret=new DefineVideoStreamTag(h,f,root); break; case 63: ret=new DebugIDTag(h,f); break; case 64: ret=new EnableDebugger2Tag(h,f); break; case 65: ret=new ScriptLimitsTag(h,f); break; case 69: //FileAttributes tag is mandatory on version>=8 and must be the first tag if(!firstTag) LOG(LOG_ERROR,_("FileAttributes tag not in the beginning")); ret=new FileAttributesTag(h,f); break; case 70: ret=new PlaceObject3Tag(h,f,root); break; case 72: ret=new DoABCTag(h,f); break; case 73: ret=new DefineFontAlignZonesTag(h,f); break; case 74: ret=new CSMTextSettingsTag(h,f); break; case 75: ret=new DefineFont3Tag(h,f,root); break; case 76: ret=new SymbolClassTag(h,f); break; case 77: ret=new MetadataTag(h,f); break; case 78: ret=new DefineScalingGridTag(h,f); break; case 82: ret=new DoABCDefineTag(h,f); break; case 83: ret=new DefineShape4Tag(h,f,root); break; case 84: ret=new DefineMorphShape2Tag(h,f,root); break; case 86: ret=new DefineSceneAndFrameLabelDataTag(h,f); break; case 87: ret=new DefineBinaryDataTag(h,f,root); break; case 88: ret=new DefineFontNameTag(h,f); break; case 91: ret=new DefineFont4Tag(h,f,root); break; default: LOG(LOG_NOT_IMPLEMENTED,_("Unsupported tag type ") << h.getTagType()); ret=new UnimplementedTag(h,f); } firstTag=false; unsigned int end=f.tellg(); unsigned int actualLen=end-start; if(actualLenexpectedLen) { LOG(LOG_ERROR,_("Error while reading tag ") << h.getTagType() << _(". Size=") << actualLen << _(" expected: ") << expectedLen); throw ParseException("Malformed SWF file"); } return ret; } RemoveObject2Tag::RemoveObject2Tag(RECORDHEADER h, std::istream& in):DisplayListTag(h) { in >> Depth; LOG(LOG_TRACE,_("RemoveObject2 Depth: ") << Depth); } void RemoveObject2Tag::execute(DisplayObjectContainer* parent) const { parent->deleteLegacyChildAt(Depth); } SetBackgroundColorTag::SetBackgroundColorTag(RECORDHEADER h, std::istream& in):ControlTag(h) { in >> BackgroundColor; } DefineEditTextTag::DefineEditTextTag(RECORDHEADER h, std::istream& in, RootMovieClip* root):DictionaryTag(h,root) { //setVariableByName("text",SWFObject(new Integer(0))); in >> CharacterID >> Bounds; LOG(LOG_TRACE,_("DefineEditTextTag ID ") << CharacterID); BitStream bs(in); HasText=UB(1,bs); WordWrap=UB(1,bs); Multiline=UB(1,bs); Password=UB(1,bs); ReadOnly=UB(1,bs); HasTextColor=UB(1,bs); HasMaxLength=UB(1,bs); HasFont=UB(1,bs); HasFontClass=UB(1,bs); AutoSize=UB(1,bs); HasLayout=UB(1,bs); NoSelect=UB(1,bs); Border=UB(1,bs); WasStatic=UB(1,bs); HTML=UB(1,bs); UseOutlines=UB(1,bs); if(HasFont) { in >> FontID; if(HasFontClass) in >> FontClass; in >> FontHeight; textData.fontSize = twipsToPixels(FontHeight); } if(HasTextColor) { in >> TextColor; textData.textColor.Red = TextColor.Red; textData.textColor.Green = TextColor.Green; textData.textColor.Blue = TextColor.Blue; } if(HasMaxLength) in >> MaxLength; if(HasLayout) { in >> Align >> LeftMargin >> RightMargin >> Indent >> Leading; } in >> VariableName; LOG(LOG_NOT_IMPLEMENTED,_("Sync to variable name ") << VariableName); if(HasText) { in >> InitialText; textData.text = (const char*)InitialText; } textData.wordWrap = WordWrap; textData.multiline = Multiline; textData.border = Border; if (AutoSize) textData.autoSize = TextData::AS_LEFT; LOG(LOG_NOT_IMPLEMENTED, "DefineEditTextTag does not parse many attributes"); } ASObject* DefineEditTextTag::instance(Class_base* c) const { if(c==NULL) c=Class::getClass(); //TODO: check assert_and_throw(bindedTo==NULL); TextField* ret=new (c->memoryAccount) TextField(c, textData, !NoSelect, ReadOnly); if (HTML) ret->setHtmlText((const char*)InitialText); return ret; } DefineSpriteTag::DefineSpriteTag(RECORDHEADER h, std::istream& in, RootMovieClip* root):DictionaryTag(h,root) { in >> SpriteID >> FrameCount; LOG(LOG_TRACE,"DefineSprite ID: " << SpriteID); //Create a non top level TagFactory TagFactory factory(in, false); Tag* tag; bool done=false; bool empty=true; do { tag=factory.readTag(root); /* We need no locking here, because the vm can only * access this object after construction */ switch(tag->getType()) { case DICT_TAG: delete tag; throw ParseException("Dictionary tag inside a sprite. Should not happen."); case DISPLAY_LIST_TAG: addToFrame(static_cast(tag)); empty=false; break; case SHOW_TAG: { delete tag; frames.emplace_back(Frame()); empty=true; break; } case SYMBOL_CLASS_TAG: case ABC_TAG: case CONTROL_TAG: delete tag; throw ParseException("Control tag inside a sprite. Should not happen."); case FRAMELABEL_TAG: addFrameLabel(frames.size()-1,static_cast(tag)->Name); delete tag; empty=false; break; case TAG: delete tag; LOG(LOG_NOT_IMPLEMENTED,_("Unclassified tag inside Sprite?")); break; case END_TAG: delete tag; done=true; if(empty && frames.size()!=FrameCount) frames.pop_back(); break; } } while(!done); if(frames.size()!=FrameCount) { //This condition is not critical as Sprites are not executed while being parsed LOG(LOG_CALLS,_("Inconsistent frame count in Sprite ID ") << SpriteID); } setFramesLoaded(frames.size()); } DefineSpriteTag::~DefineSpriteTag() { //This is the actual parsed tag so it also has to clean up the tag in the FrameContainer for(auto it=frames.begin();it!=frames.end();++it) it->destroyTags(); } ASObject* DefineSpriteTag::instance(Class_base* c) const { Class_base* retClass=NULL; if(c) retClass=c; else if(bindedTo) retClass=bindedTo; else retClass=Class::getClass(); return new (retClass->memoryAccount) MovieClip(retClass, *this, true); } void lightspark::ignore(istream& i, int count) { char* buf=new char[count]; i.read(buf,count); delete[] buf; } DefineFontTag::DefineFontTag(RECORDHEADER h, std::istream& in, RootMovieClip* root):FontTag(h, 20, root) { LOG(LOG_TRACE,_("DefineFont")); in >> FontID; UI16_SWF t; int NumGlyphs=0; in >> t; OffsetTable.push_back(t); NumGlyphs=t/2; for(int i=1;i> t; OffsetTable.push_back(t); } for(int i=0;i> t; GlyphShapeTable.push_back(t); } } ASObject* DefineFontTag::instance(Class_base* c) const { tiny_string fontname(""); Class_base* retClass=NULL; if(c) retClass=c; else if(bindedTo) retClass=bindedTo; else retClass=Class::getClass(); ASFont* ret=new (retClass->memoryAccount) ASFont(retClass); LOG(LOG_NOT_IMPLEMENTED,"DefineFontTag::instance doesn't handle all font properties"); ret->SetFont(fontname,false,false,true,false); return ret; } DefineFont2Tag::DefineFont2Tag(RECORDHEADER h, std::istream& in, RootMovieClip* root):FontTag(h, 20, root) { LOG(LOG_TRACE,_("DefineFont2")); in >> FontID; BitStream bs(in); FontFlagsHasLayout = UB(1,bs); FontFlagsShiftJIS = UB(1,bs); FontFlagsSmallText = UB(1,bs); FontFlagsANSI = UB(1,bs); FontFlagsWideOffsets = UB(1,bs); FontFlagsWideCodes = UB(1,bs); FontFlagsItalic = UB(1,bs); FontFlagsBold = UB(1,bs); in >> LanguageCode >> FontNameLen; for(int i=0;i> t; FontName.push_back(t); } in >> NumGlyphs; if(FontFlagsWideOffsets) { UI32_SWF t; for(int i=0;i> t; OffsetTable.push_back(t); } in >> t; CodeTableOffset=t; } else { UI16_SWF t; for(int i=0;i> t; OffsetTable.push_back(t); } in >> t; CodeTableOffset=t; } for(int i=0;i> t; GlyphShapeTable.push_back(t); } if(FontFlagsWideCodes) { for(int i=0;i> t; CodeTable.push_back(t); } } else { for(int i=0;i> t; CodeTable.push_back(t); } } if(FontFlagsHasLayout) { in >> FontAscent >> FontDescent >> FontLeading; for(int i=0;i> t; FontAdvanceTable.push_back(t); } for(int i=0;i> t; FontBoundsTable.push_back(t); } in >> KerningCount; } //TODO: implmented Kerning support ignore(in,KerningCount*4); } ASObject* DefineFont2Tag::instance(Class_base* c) const { tiny_string fontname((const char*)FontName.data(),true); Class_base* retClass=NULL; if(c) retClass=c; else if(bindedTo) retClass=bindedTo; else retClass=Class::getClass(); ASFont* ret=new (retClass->memoryAccount) ASFont(retClass); LOG(LOG_NOT_IMPLEMENTED,"DefineFont2Tag::instance doesn't handle all font properties"); ret->SetFont(fontname,FontFlagsBold,FontFlagsItalic,true,false); return ret; } DefineFont3Tag::DefineFont3Tag(RECORDHEADER h, std::istream& in, RootMovieClip* root):FontTag(h, 1, root),CodeTableOffset(0) { LOG(LOG_TRACE,_("DefineFont3")); in >> FontID; BitStream bs(in); FontFlagsHasLayout = UB(1,bs); FontFlagsShiftJIS = UB(1,bs); FontFlagsSmallText = UB(1,bs); FontFlagsANSI = UB(1,bs); FontFlagsWideOffsets = UB(1,bs); FontFlagsWideCodes = UB(1,bs); FontFlagsItalic = UB(1,bs); FontFlagsBold = UB(1,bs); in >> LanguageCode >> FontNameLen; for(int i=0;i> t; FontName.push_back(t); } in >> NumGlyphs; streampos offsetReference = in.tellg(); if(FontFlagsWideOffsets) { UI32_SWF t; for(int i=0;i> t; OffsetTable.push_back(t); } //CodeTableOffset is missing with zero NumGlyphs if(NumGlyphs) { in >> t; CodeTableOffset=t; } } else { UI16_SWF t; for(int i=0;i> t; OffsetTable.push_back(t); } //CodeTableOffset is missing with zero NumGlyphs if(NumGlyphs) { in >> t; CodeTableOffset=t; } } GlyphShapeTable.resize(NumGlyphs); for(int i=0;i> GlyphShapeTable[i]; } //sanity check the stream position streampos expectedPos = offsetReference + (streampos)CodeTableOffset; if (in.tellg() != expectedPos) { LOG(LOG_ERROR, "Malformed SWF file: unexpected offset in DefineFont3 tag"); if (in.tellg() < expectedPos) { //Read too few bytes => We can still continue ignore(in, expectedPos-in.tellg()); } else { //Read too many bytes => fail assert(in.tellg() == expectedPos); } } for(int i=0;i> t; CodeTable.push_back(t); } if(FontFlagsHasLayout) { in >> FontAscent >> FontDescent >> FontLeading; for(int i=0;i> t; FontAdvanceTable.push_back(t); } for(int i=0;i> t; FontBoundsTable.push_back(t); } in >> KerningCount; } //TODO: implment Kerning support ignore(in,KerningCount*4); } ASObject* DefineFont3Tag::instance(Class_base* c) const { tiny_string fontname((const char*)FontName.data(),true); Class_base* retClass=NULL; if(c) retClass=c; else if(bindedTo) retClass=bindedTo; else retClass=Class::getClass(); ASFont* ret=new (retClass->memoryAccount) ASFont(retClass); LOG(LOG_NOT_IMPLEMENTED,"DefineFont3Tag::instance doesn't handle all font properties"); ret->SetFont(fontname,FontFlagsBold,FontFlagsItalic,true,false); return ret; } DefineFont4Tag::DefineFont4Tag(RECORDHEADER h, std::istream& in, RootMovieClip* root):DictionaryTag(h,root) { LOG(LOG_TRACE,_("DefineFont4")); int dest=in.tellg(); dest+=h.getLength(); in >> FontID; BitStream bs(in); UB(5,bs); /* reserved */ FontFlagsHasFontData = UB(1,bs); FontFlagsItalic = UB(1,bs); FontFlagsBold = UB(1,bs); in >> FontName; if(FontFlagsHasFontData) LOG(LOG_NOT_IMPLEMENTED,"DefineFont4Tag with FontData"); ignore(in,dest-in.tellg()); } ASObject* DefineFont4Tag::instance(Class_base* c) const { tiny_string fontname = FontName; Class_base* retClass=NULL; if(c) retClass=c; else if(bindedTo) retClass=bindedTo; else retClass=Class::getClass(); ASFont* ret=new (retClass->memoryAccount) ASFont(retClass); LOG(LOG_NOT_IMPLEMENTED,"DefineFont4Tag::instance doesn't handle all font properties"); ret->SetFont(fontname,FontFlagsBold,FontFlagsItalic,FontFlagsHasFontData,false); return ret; } BitmapTag::BitmapTag(RECORDHEADER h,RootMovieClip* root):DictionaryTag(h,root),bitmap(_MR(new BitmapContainer(getSys()->tagsMemory))) { } _R BitmapTag::getBitmap() const { return bitmap; } DefineBitsLosslessTag::DefineBitsLosslessTag(RECORDHEADER h, istream& in, int version, RootMovieClip* root):BitmapTag(h,root),BitmapColorTableSize(0) { int dest=in.tellg(); dest+=h.getLength(); in >> CharacterId >> BitmapFormat >> BitmapWidth >> BitmapHeight; if(BitmapFormat==LOSSLESS_BITMAP_PALETTE) in >> BitmapColorTableSize; string cData; size_t cSize = dest-in.tellg(); //rest of this tag cData.resize(cSize); in.read(&cData[0], cSize); istringstream cDataStream(cData); zlib_filter zf(cDataStream.rdbuf()); istream zfstream(&zf); if (BitmapFormat == LOSSLESS_BITMAP_RGB15 || BitmapFormat == LOSSLESS_BITMAP_RGB24) { size_t size = BitmapWidth * BitmapHeight * 4; uint8_t* inData=new(nothrow) uint8_t[size]; zfstream.read((char*)inData,size); assert(!zfstream.fail() && !zfstream.eof()); BitmapContainer::BITMAP_FORMAT format; if (BitmapFormat == LOSSLESS_BITMAP_RGB15) format = BitmapContainer::RGB15; else if (version == 1) format = BitmapContainer::RGB24; else format = BitmapContainer::ARGB32; bitmap->fromRGB(inData, BitmapWidth, BitmapHeight, format); } else if (BitmapFormat == LOSSLESS_BITMAP_PALETTE) { unsigned numColors = BitmapColorTableSize+1; /* Bitmap rows are 32 bit aligned */ uint32_t stride = BitmapWidth; while (stride % 4 != 0) stride++; unsigned int paletteBPP; if (version == 1) paletteBPP = 3; else paletteBPP = 4; size_t size = paletteBPP*numColors + stride*BitmapHeight; uint8_t* inData=new(nothrow) uint8_t[size]; zfstream.read((char*)inData,size); assert(!zfstream.fail() && !zfstream.eof()); uint8_t *palette = inData; uint8_t *pixelData = inData + paletteBPP*numColors; bitmap->fromPalette(pixelData, BitmapWidth, BitmapHeight, stride, palette, numColors, paletteBPP); delete[] inData; } else { LOG(LOG_NOT_IMPLEMENTED,"DefineBitsLossless(2)Tag with unsupported BitmapFormat " << BitmapFormat); } } ASObject* BitmapTag::instance(Class_base* c) const { //Flex imports bitmaps using BitmapAsset as the base class, which is derived from bitmap //Also BitmapData is used in the wild though, so support both cases Class_base* realClass=(c)?c:bindedTo; Class_base* classRet = Class::getClass(); if(!realClass) return new (classRet->memoryAccount) BitmapData(classRet, bitmap); if(realClass->isSubClass(Class::getClass())) { BitmapData* ret=new (classRet->memoryAccount) BitmapData(classRet, bitmap); Bitmap* bitmapRet=new (realClass->memoryAccount) Bitmap(realClass,_MR(ret)); return bitmapRet; } if(realClass->isSubClass(Class::getClass())) { classRet = realClass; } return new (classRet->memoryAccount) BitmapData(classRet, bitmap); } DefineTextTag::DefineTextTag(RECORDHEADER h, istream& in, RootMovieClip* root,int v):DictionaryTag(h,root), tokens(reporter_allocator(getSys()->tagsMemory)),version(v) { in >> CharacterId >> TextBounds >> TextMatrix >> GlyphBits >> AdvanceBits; assert(v==1 || v==2); if(v==1) LOG(LOG_TRACE,"DefineText ID " << CharacterId); else if(v==2) LOG(LOG_TRACE,"DefineText2 ID " << CharacterId); TEXTRECORD t(this); while(1) { in >> t; if(t.TextRecordType+t.StyleFlagsHasFont+t.StyleFlagsHasColor+t.StyleFlagsHasYOffset+t.StyleFlagsHasXOffset==0) break; TextRecords.push_back(t); } } ASObject* DefineTextTag::instance(Class_base* c) const { /* we cannot call computeCached in the constructor * because loadedFrom is not available there for dictionary lookups */ if(tokens.empty()) computeCached(); if(c==NULL) c=Class::getClass(); StaticText* ret=new (c->memoryAccount) StaticText(c, tokens); return ret; } void DefineTextTag::computeCached() const { if(!tokens.empty()) return; const FontTag* curFont = NULL; std::list fillStyles; Vector2 curPos; FILLSTYLE fs(1); fs.FillStyleType = SOLID_FILL; fs.Color = RGBA(0,0,0,255); fillStyles.push_back(fs); /* * All coordinates are scaled into 1024*20*20 units per pixel. * This is scaled back to pixels by cairo. (1024 is the glyph * EM square scale, 20 is twips-per-pixel and the second 20 * comes from TextHeight, which is also in twips) */ const int twipsScaling = 1024*20; const int pixelScaling = 1024*20*20; // Scale the translation component of TextMatrix. -1 because // removes the unscaled translation first. MATRIX scaledTextMatrix = TextMatrix; scaledTextMatrix.translate((pixelScaling-1)*TextMatrix.getTranslateX(), (pixelScaling-1)*TextMatrix.getTranslateY()); for(size_t i=0; i< TextRecords.size();++i) { if(TextRecords[i].StyleFlagsHasFont) { const DictionaryTag* it3=loadedFrom->dictionaryLookup(TextRecords[i].FontID); curFont=dynamic_cast(it3); assert_and_throw(curFont); } assert_and_throw(curFont); if(TextRecords[i].StyleFlagsHasColor) { fillStyles.front().Color = TextRecords[i].TextColor; } if(TextRecords[i].StyleFlagsHasXOffset) { curPos.x = TextRecords[i].XOffset; } if(TextRecords[i].StyleFlagsHasYOffset) { curPos.y = TextRecords[i].YOffset; } /* * In DefineFont3Tags, shape's coordinates are 1024*20 times pixels size, * in all former DefineFont*Tags, its just 1024 times. We scale everything here * to 1024*20, so curFont->scaling=20 for DefineFont2Tags and DefineFontTags. * And, of course, scale by the TextHeight. */ int scaling = TextRecords[i].TextHeight * curFont->scaling; for(uint32_t j=0;j& sr = curFont->getGlyphShapes().at(ge.GlyphIndex).ShapeRecords; Vector2 glyphPos = curPos*twipsScaling; MATRIX glyphMatrix(scaling, scaling, 0, 0, glyphPos.x, glyphPos.y); //Apply glyphMatrix first, then scaledTextMatrix glyphMatrix = scaledTextMatrix.multiplyMatrix(glyphMatrix); TokenContainer::FromShaperecordListToShapeVector(sr,tokens,fillStyles,glyphMatrix); curPos.x += ge.GlyphAdvance; } } } DefineShapeTag::DefineShapeTag(RECORDHEADER h,int v,RootMovieClip* root):DictionaryTag(h,root),Shapes(v), tokens(reporter_allocator(getSys()->tagsMemory)) { } DefineShapeTag::DefineShapeTag(RECORDHEADER h, std::istream& in,RootMovieClip* root):DictionaryTag(h,root),Shapes(1), tokens(reporter_allocator(getSys()->tagsMemory)) { LOG(LOG_TRACE,_("DefineShapeTag")); in >> ShapeId >> ShapeBounds >> Shapes; TokenContainer::FromShaperecordListToShapeVector(Shapes.ShapeRecords,tokens,Shapes.FillStyles.FillStyles); } DefineShape2Tag::DefineShape2Tag(RECORDHEADER h, std::istream& in,RootMovieClip* root):DefineShapeTag(h,2,root) { LOG(LOG_TRACE,_("DefineShape2Tag")); in >> ShapeId >> ShapeBounds >> Shapes; TokenContainer::FromShaperecordListToShapeVector(Shapes.ShapeRecords,tokens,Shapes.FillStyles.FillStyles); } DefineShape3Tag::DefineShape3Tag(RECORDHEADER h, std::istream& in,RootMovieClip* root):DefineShape2Tag(h,3,root) { LOG(LOG_TRACE,"DefineShape3Tag"); in >> ShapeId >> ShapeBounds >> Shapes; TokenContainer::FromShaperecordListToShapeVector(Shapes.ShapeRecords,tokens,Shapes.FillStyles.FillStyles); } DefineShape4Tag::DefineShape4Tag(RECORDHEADER h, std::istream& in, RootMovieClip* root):DefineShape3Tag(h,4,root) { LOG(LOG_TRACE,"DefineShape4Tag"); in >> ShapeId >> ShapeBounds >> EdgeBounds; BitStream bs(in); UB(5,bs); UsesFillWindingRule=UB(1,bs); UsesNonScalingStrokes=UB(1,bs); UsesScalingStrokes=UB(1,bs); in >> Shapes; TokenContainer::FromShaperecordListToShapeVector(Shapes.ShapeRecords,tokens,Shapes.FillStyles.FillStyles); } DefineMorphShapeTag::DefineMorphShapeTag(RECORDHEADER h, std::istream& in, RootMovieClip* root):DictionaryTag(h, root), MorphLineStyles(1) { LOG(LOG_TRACE,"DefineMorphShapeTag"); UI32_SWF Offset; in >> CharacterId >> StartBounds >> EndBounds >> Offset >> MorphFillStyles >> MorphLineStyles; try { in >> StartEdges >> EndEdges; } catch(LightsparkException& e) { LOG(LOG_ERROR,_("Invalid data for morph shape")); } } ASObject* DefineMorphShapeTag::instance(Class_base* c) const { assert_and_throw(bindedTo==NULL); if(c==NULL) c=Class::getClass(); LOG(LOG_NOT_IMPLEMENTED, _("MorphShape not really supported")); return Class::getInstanceS(c); } DefineMorphShape2Tag::DefineMorphShape2Tag(RECORDHEADER h, std::istream& in, RootMovieClip* root):DefineMorphShapeTag(h, root, 2) { LOG(LOG_TRACE,"DefineMorphShape2Tag"); UI32_SWF Offset; in >> CharacterId >> StartBounds >> EndBounds >> StartEdgeBounds >> EndEdgeBounds; BitStream bs(in); UB(6,bs); UsesNonScalingStrokes=UB(1,bs); UsesScalingStrokes=UB(1,bs); in >> Offset >> MorphFillStyles >> MorphLineStyles; try { in >> StartEdges >> EndEdges; } catch(LightsparkException& e) { LOG(LOG_ERROR,_("Invalid data for morph shape")); } } //void DefineFont3Tag::genGlyphShape(vector& s, int glyph) //{ // SHAPE& shape=GlyphShapeTable[glyph]; // FromShaperecordListToShapeVector(shape.ShapeRecords,s); /* for(unsigned int i=0;istate.validFill0) { if(i->state.fill0!=1) LOG(ERROR,_("Not valid fill style for font")); } if(i->state.validFill1) { LOG(ERROR,_("Not valid fill style for font")); } if(i->state.validStroke) { if(i->state.stroke) { s.back().graphic.stroked=true; LOG(ERROR,_("Not valid stroke style for font")); // shapes.back().graphic.stroke_color=Shapes.LineStyles.LineStyles[i->state->stroke-1].Color; } else s.back().graphic.stroked=false; } else s.back().graphic.stroked=false;*/ //} //void DefineFont2Tag::genGlyphShape(vector& s, int glyph) //{ //SHAPE& shape=GlyphShapeTable[glyph]; //FromShaperecordListToShapeVector(shape.ShapeRecords,s); /*for(unsigned int i=0;istate.validFill0) { if(i->state.fill0!=1) LOG(ERROR,_("Not valid fill style for font")); } if(i->state.validFill1) { LOG(ERROR,_("Not valid fill style for font")); } if(i->state.validStroke) { if(i->state.stroke) { s.back().graphic.stroked=true; LOG(ERROR,_("Not valid stroke style for font")); // shapes.back().graphic.stroke_color=Shapes.LineStyles.LineStyles[i->state->stroke-1].Color; } else s.back().graphic.stroked=false; } else s.back().graphic.stroked=false;*/ //} //void DefineFontTag::genGlyphShape(vector& s,int glyph) //{ /*SHAPE& shape=GlyphShapeTable[glyph]; FromShaperecordListToShapeVector(shape.ShapeRecords,s); for(unsigned int i=0;iColorTransform=ColorTransform; if(PlaceFlagHasRatio) obj->Ratio=Ratio; if(PlaceFlagHasClipDepth) obj->ClipDepth=ClipDepth; if(PlaceFlagHasName) { //Set a variable on the parent to link this object LOG(LOG_INFO,_("Registering ID ") << CharacterId << _(" with name ") << Name); if(!PlaceFlagMove) { obj->name = (const char*)Name; } else LOG(LOG_ERROR, _("Moving of registered objects not really supported")); } else if (!PlaceFlagMove) { //Remove the automatic name set by the DisplayObject constructor obj->name = ""; } } void PlaceObject2Tag::execute(DisplayObjectContainer* parent) const { //TODO: support clipping if(ClipDepth!=0) { LOG(LOG_ERROR,"ClipDepth is not supported"); return; } if(!PlaceFlagHasCharacter && !PlaceFlagMove) { LOG(LOG_ERROR,_("Invalid PlaceObject2Tag that does nothing")); return; } if(PlaceFlagHasCharacter) { //A new character must be placed LOG(LOG_TRACE,_("Placing ID ") << CharacterId); if(placedTag==NULL) throw RunTimeException("No tag to place"); //We can create the object right away ASObject *instance = placedTag->instance(); DisplayObject* toAdd=dynamic_cast(instance); if(!toAdd && instance) { //We ignore weird tags. I have seen ASFont //(from a DefineFont) being added by PlaceObject2. LOG(LOG_NOT_IMPLEMENTED, "Adding non-DisplayObject to display list"); instance->decRef(); return; } assert_and_throw(toAdd); //The matrix must be set before invoking the constructor toAdd->setLegacyMatrix(Matrix); setProperties(toAdd, parent); if( parent->hasLegacyChildAt(Depth) ) { if(PlaceFlagMove) { parent->deleteLegacyChildAt(Depth); /* parent becomes the owner of toAdd */ parent->insertLegacyChildAt(Depth,toAdd); } else LOG(LOG_ERROR,_("Invalid PlaceObject2Tag that overwrites an object without moving")); } else { /* parent becomes the owner of toAdd */ parent->insertLegacyChildAt(Depth,toAdd); } } else { parent->transformLegacyChildAt(Depth,Matrix); } } PlaceObject2Tag::PlaceObject2Tag(RECORDHEADER h, std::istream& in, RootMovieClip* root):DisplayListTag(h),placedTag(NULL) { LOG(LOG_TRACE,_("PlaceObject2")); BitStream bs(in); PlaceFlagHasClipAction=UB(1,bs); PlaceFlagHasClipDepth=UB(1,bs); PlaceFlagHasName=UB(1,bs); PlaceFlagHasRatio=UB(1,bs); PlaceFlagHasColorTransform=UB(1,bs); PlaceFlagHasMatrix=UB(1,bs); PlaceFlagHasCharacter=UB(1,bs); PlaceFlagMove=UB(1,bs); in >> Depth; if(PlaceFlagHasCharacter) in >> CharacterId; if(PlaceFlagHasMatrix) in >> Matrix; if(PlaceFlagHasColorTransform) in >> ColorTransform; if(PlaceFlagHasRatio) in >> Ratio; if(PlaceFlagHasName) in >> Name; if(PlaceFlagHasClipDepth) in >> ClipDepth; if(PlaceFlagHasClipAction) in >> ClipActions; assert_and_throw(!(PlaceFlagHasCharacter && CharacterId==0)); if(PlaceFlagHasCharacter) placedTag=root->dictionaryLookup(CharacterId); } PlaceObject3Tag::PlaceObject3Tag(RECORDHEADER h, std::istream& in, RootMovieClip* root):PlaceObject2Tag(h) { LOG(LOG_TRACE,_("PlaceObject3")); BitStream bs(in); PlaceFlagHasClipAction=UB(1,bs); PlaceFlagHasClipDepth=UB(1,bs); PlaceFlagHasName=UB(1,bs); PlaceFlagHasRatio=UB(1,bs); PlaceFlagHasColorTransform=UB(1,bs); PlaceFlagHasMatrix=UB(1,bs); PlaceFlagHasCharacter=UB(1,bs); PlaceFlagMove=UB(1,bs); UB(3,bs); //Reserved PlaceFlagHasImage=UB(1,bs); PlaceFlagHasClassName=UB(1,bs); PlaceFlagHasCacheAsBitmap=UB(1,bs); PlaceFlagHasBlendMode=UB(1,bs); PlaceFlagHasFilterList=UB(1,bs); in >> Depth; if(PlaceFlagHasClassName || (PlaceFlagHasImage && PlaceFlagHasCharacter)) throw ParseException("ClassName in PlaceObject3 not yet supported"); if(PlaceFlagHasCharacter) in >> CharacterId; if(PlaceFlagHasMatrix) in >> Matrix; if(PlaceFlagHasColorTransform) in >> ColorTransform; if(PlaceFlagHasRatio) in >> Ratio; if(PlaceFlagHasName) in >> Name; if(PlaceFlagHasClipDepth) in >> ClipDepth; if(PlaceFlagHasFilterList) in >> SurfaceFilterList; if(PlaceFlagHasBlendMode) in >> BlendMode; if(PlaceFlagHasCacheAsBitmap) in >> BitmapCache; if(PlaceFlagHasClipAction) in >> ClipActions; assert_and_throw(!(PlaceFlagHasCharacter && CharacterId==0)) if(PlaceFlagHasCharacter) placedTag=root->dictionaryLookup(CharacterId); } void SetBackgroundColorTag::execute(RootMovieClip* root) const { root->setBackground(BackgroundColor); } ProductInfoTag::ProductInfoTag(RECORDHEADER h, std::istream& in):Tag(h) { LOG(LOG_TRACE,_("ProductInfoTag Tag")); in >> ProductId >> Edition >> MajorVersion >> MinorVersion >> MinorBuild >> MajorBuild >> CompileTimeLo >> CompileTimeHi; uint64_t longlongTime = CompileTimeHi; longlongTime<<=32; longlongTime|=CompileTimeLo; LOG(LOG_INFO,_("SWF Info:") << endl << "\tProductId:\t\t" << ProductId << endl << "\tEdition:\t\t" << Edition << endl << "\tVersion:\t\t" << int(MajorVersion) << "." << int(MinorVersion) << "." << MajorBuild << "." << MinorBuild << endl << "\tCompileTime:\t\t" << longlongTime); } FrameLabelTag::FrameLabelTag(RECORDHEADER h, std::istream& in):Tag(h) { in >> Name; /* We only support SWF version >=6 */ UI8 NamedAnchor=in.peek(); if(NamedAnchor==1) in >> NamedAnchor; } DefineButtonTag::DefineButtonTag(RECORDHEADER h, std::istream& in, int version, RootMovieClip* root):DictionaryTag(h,root) { in >> ButtonId; if (version > 1) { BitStream bs(in); UB(7,bs); TrackAsMenu=UB(1,bs); in >> ActionOffset; } else { TrackAsMenu=false; ActionOffset=0; } BUTTONRECORD br(version); do { in >> br; if(br.isNull()) break; Characters.push_back(br); } while(true); if(ActionOffset || version == 1) LOG(LOG_NOT_IMPLEMENTED,"DefineButton(2)Tag: Actions are not supported"); } ASObject* DefineButtonTag::instance(Class_base* c) const { DisplayObject* states[4] = {NULL, NULL, NULL, NULL}; bool isSprite[4] = {false, false, false, false}; uint32_t curDepth[4]; /* There maybe multiple DisplayObjects for one state. The official * implementation seems to create a Sprite in that case with * all DisplayObjects as children. */ auto i = Characters.begin(); for(;i != Characters.end(); ++i) { for(int j=0;j<4;++j) { if(j==0 && !i->ButtonStateDown) continue; if(j==1 && !i->ButtonStateHitTest) continue; if(j==2 && !i->ButtonStateOver) continue; if(j==3 && !i->ButtonStateUp) continue; const DictionaryTag* dict=loadedFrom->dictionaryLookup(i->CharacterID); //We can create the object right away DisplayObject* state=dynamic_cast(dict->instance()); assert_and_throw(state); //The matrix must be set before invoking the constructor state->setLegacyMatrix(i->PlaceMatrix); /* * TODO: BlendMode, filerList, PlaceDepth, ColorTransfrom */ if(states[j] == NULL) { states[j] = state; curDepth[j] = i->PlaceDepth; } else { if(!isSprite[j]) { Sprite* spr = Class::getInstanceS(); spr->insertLegacyChildAt(curDepth[j],states[j]); states[j] = spr; spr->name = "Button_spr"; } Sprite* spr = Class::cast(states[j]); spr->insertLegacyChildAt(i->PlaceDepth,state); } } } if(c==NULL) c=Class::getClass(); SimpleButton* ret=new (c->memoryAccount) SimpleButton(c, states[0], states[1], states[2], states[3]); return ret; } DefineVideoStreamTag::DefineVideoStreamTag(RECORDHEADER h, std::istream& in, RootMovieClip* root):DictionaryTag(h, root) { LOG(LOG_INFO,"DefineVideoStreamTag"); in >> CharacterID >> NumFrames >> Width >> Height; BitStream bs(in); UB(4,bs); VideoFlagsDeblocking=UB(3,bs); VideoFlagsSmoothing=UB(1,bs); in >> CodecID; } ASObject* DefineVideoStreamTag::instance(Class_base* c) const { Class_base* classRet = NULL; if(c) classRet=c; else if(bindedTo) classRet=bindedTo; else classRet=Class