diff --git a/plugins/zynaddsubfx/CMakeLists.txt b/plugins/zynaddsubfx/CMakeLists.txt index 995d6df5e..34f171032 100644 --- a/plugins/zynaddsubfx/CMakeLists.txt +++ b/plugins/zynaddsubfx/CMakeLists.txt @@ -24,19 +24,6 @@ SET(ZYN_SRC_GUI ) -SET(MXML_SRC - ${CMAKE_CURRENT_SOURCE_DIR}/mxml/mxml-attr.c - ${CMAKE_CURRENT_SOURCE_DIR}/mxml/mxml-entity.c - ${CMAKE_CURRENT_SOURCE_DIR}/mxml/mxml-file.c - ${CMAKE_CURRENT_SOURCE_DIR}/mxml/mxml-index.c - ${CMAKE_CURRENT_SOURCE_DIR}/mxml/mxml-node.c - ${CMAKE_CURRENT_SOURCE_DIR}/mxml/mxml-private.c - ${CMAKE_CURRENT_SOURCE_DIR}/mxml/mxml-search.c - ${CMAKE_CURRENT_SOURCE_DIR}/mxml/mxml-set.c - ${CMAKE_CURRENT_SOURCE_DIR}/mxml/mxml-string.c -) - - # definitions for ZynAddSubFX IF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE) ADD_DEFINITIONS(-DOS_LINUX) @@ -60,7 +47,7 @@ IF(LMMS_BUILD_WIN32) ADD_DEFINITIONS(-DPTW32_STATIC_LIB) ENDIF(LMMS_BUILD_WIN32) -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/fltk/ ${CMAKE_CURRENT_SOURCE_DIR}/mxml ${CMAKE_CURRENT_SOURCE_DIR} ${FFTW3F_INCLUDE_DIRS}) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/fltk/ ${CMAKE_CURRENT_SOURCE_DIR} ${FFTW3F_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR} ) set(ZASF_CORE_LIBS zynaddsubfx_input @@ -72,7 +59,6 @@ set(ZASF_CORE_LIBS zynaddsubfx_params zynaddsubfx_dsp zynaddsubfx_samples - zynaddsubfx_controls ) macro(unit_test NAME CXX_FILE FILES) @@ -80,7 +66,6 @@ endmacro(unit_test) add_subdirectory(src/Misc) add_subdirectory(src/Input) -add_subdirectory(src/Controls) add_subdirectory(src/Synth) add_subdirectory(src/Output) add_subdirectory(src/Seq) @@ -89,8 +74,8 @@ add_subdirectory(src/Params) add_subdirectory(src/DSP) add_subdirectory(src/Samples) -ADD_LIBRARY(ZynAddSubFxCore SHARED LocalZynAddSubFx.cpp ${MXML_SRC}) -TARGET_LINK_LIBRARIES(ZynAddSubFxCore ${ZASF_CORE_LIBS} ${FFTW3F_LIBRARIES} -lz -lpthread) +ADD_LIBRARY(ZynAddSubFxCore SHARED LocalZynAddSubFx.cpp) +TARGET_LINK_LIBRARIES(ZynAddSubFxCore ${ZASF_CORE_LIBS} ${FFTW3F_LIBRARIES} ${QT_LIBRARIES} -lz -lpthread) IF(LMMS_BUILD_WIN32) TARGET_LINK_LIBRARIES(ZynAddSubFxCore -lws2_32) INSTALL(TARGETS ZynAddSubFxCore DESTINATION ${PLUGIN_DIR}) @@ -115,10 +100,7 @@ SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${PLUGIN_DIR}") SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) ADD_EXECUTABLE(RemoteZynAddSubFx RemoteZynAddSubFx.cpp ${ZYN_SRC_GUI} ${WINRC}) INSTALL(TARGETS RemoteZynAddSubFx RUNTIME DESTINATION ${PLUGIN_DIR}) -IF(LMMS_BUILD_LINUX) - SET(FONTCONFIG_LIBS -lfontconfig) -ENDIF(LMMS_BUILD_LINUX) -TARGET_LINK_LIBRARIES(RemoteZynAddSubFx -lpthread ${FONTCONFIG_LIBS} -L${CMAKE_CURRENT_BINARY_DIR} -lZynAddSubFxCore ${CMAKE_CURRENT_BINARY_DIR}/fltk/bin/libfltk.a) +TARGET_LINK_LIBRARIES(RemoteZynAddSubFx -lpthread -L${CMAKE_CURRENT_BINARY_DIR} -lZynAddSubFxCore ${CMAKE_CURRENT_BINARY_DIR}/fltk/lib/libfltk.a) ADD_DEPENDENCIES(RemoteZynAddSubFx ZynAddSubFxCore) # link system libraries when on win32 @@ -130,7 +112,7 @@ ENDIF(LMMS_BUILD_WIN32) IF(LMMS_BUILD_LINUX) FIND_PACKAGE(X11) FIND_PACKAGE(Freetype) - TARGET_LINK_LIBRARIES(RemoteZynAddSubFx ${X11_LIBRARIES} ${X11_Xft_LIB} ${FREETYPE_LIBRARY}) + TARGET_LINK_LIBRARIES(RemoteZynAddSubFx -ldl ${X11_LIBRARIES} ${X11_Xft_LIB} ${X11_Xinerama_LIB} ${FREETYPE_LIBRARY} -lfontconfig) ENDIF(LMMS_BUILD_LINUX) @@ -144,7 +126,7 @@ IF(LMMS_BUILD_WIN64) ELSEIF(LMMS_BUILD_WIN32) SET(FLTK_EXTRA_FLAGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_SOURCE_DIR}/cmake/modules/Win32Toolchain.cmake") ENDIF(LMMS_BUILD_WIN64) -ADD_CUSTOM_TARGET(libfltk COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/fltk && cd ${CMAKE_CURRENT_BINARY_DIR}/fltk && ${CMAKE_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}/fltk ${FLTK_EXTRA_FLAGS} -DCMAKE_MODULE_PATH=${CMAKE_SOURCE_DIR}/cmake/modules/ -DFLTK_USE_SYSTEM_ZLIB:BOOL=ON -DFLTK_USE_SYSTEM_JPEG:BOOL=ON -DFLTK_USE_SYSTEM_PNG:BOOL=ON -DUSE_OPENGL:BOOL=OFF -DBUILD_TESTING:BOOL=OFF -DCMAKE_BUILD_TYPE=release && ${CMAKE_BUILD_TOOL}) +ADD_CUSTOM_TARGET(libfltk COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/fltk && cd ${CMAKE_CURRENT_BINARY_DIR}/fltk && ${CMAKE_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}/fltk ${FLTK_EXTRA_FLAGS} -DCMAKE_MODULE_PATH=${CMAKE_SOURCE_DIR}/cmake/modules/ -DFLTK_USE_SYSTEM_ZLIB:BOOL=ON -DFLTK_USE_SYSTEM_JPEG:BOOL=ON -DFLTK_USE_SYSTEM_PNG:BOOL=ON -DOPTION_BUILD_EXAMPLES:BOOL=OFF -DCMAKE_BUILD_TYPE=release && ${CMAKE_BUILD_TOOL}) ADD_DEPENDENCIES(RemoteZynAddSubFx libfltk) ENDIF(LMMS_HAVE_FFTW3F) diff --git a/plugins/zynaddsubfx/ChangeLog b/plugins/zynaddsubfx/ChangeLog index 0e30d8dad..fb680430a 100644 --- a/plugins/zynaddsubfx/ChangeLog +++ b/plugins/zynaddsubfx/ChangeLog @@ -828,6 +828,8 @@ - Codul de recorder wav a fost rescris - Adaugata functia de export la sample-urile din PADsynth +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + 20 Feb 2009 (Mark McCurry) - Made several functions accept 'constant char' over 'char' to prevent warnings @@ -957,3 +959,18 @@ 09 Oct 2009 (Mark McCurry) - Restylized codebase with uncrustify + +28 Oct 2009 (Paul Nasca) + - Disable "bw" control on Reverb when Bandwidth mode is not enabled + +18 Nov 2009 (Mark McCurry) + - Fixed segfault in VirKeyBoard + +02 Dec 2009 (Paul Nasca) + - Fixed a small typo on Virtual Keyboard + +10 Dec 2009 (Mark McCurry) + - Separated out Presets and arrayed Presets to reduce warnings from + the Wextra flag + - Minor change to Filter_ and FormantFilter to reduce unwanted warnings + diff --git a/plugins/zynaddsubfx/LocalZynAddSubFx.cpp b/plugins/zynaddsubfx/LocalZynAddSubFx.cpp index 8f1a5e007..34663c2c3 100644 --- a/plugins/zynaddsubfx/LocalZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/LocalZynAddSubFx.cpp @@ -49,10 +49,9 @@ LocalZynAddSubFx::LocalZynAddSubFx() pthread_win32_thread_attach_np(); #endif - config.init(); - OSCIL_SIZE = config.cfg.OscilSize; + initConfig(); - config.cfg.GzipCompression = 0; + OSCIL_SIZE = config.cfg.OscilSize; srand( time( NULL ) ); denormalkillbuf = new REALTYPE[SOUND_BUFFER_SIZE]; @@ -83,6 +82,16 @@ LocalZynAddSubFx::~LocalZynAddSubFx() +void LocalZynAddSubFx::initConfig() +{ + config.init(); + + config.cfg.GzipCompression = 0; +} + + + + void LocalZynAddSubFx::setSampleRate( int _sampleRate ) { SAMPLE_RATE = _sampleRate; @@ -173,7 +182,8 @@ void LocalZynAddSubFx::setLmmsWorkingDir( const std::string & _dir ) free( config.workingDir ); } config.workingDir = strdup( _dir.c_str() ); - config.init(); + + initConfig(); } diff --git a/plugins/zynaddsubfx/LocalZynAddSubFx.h b/plugins/zynaddsubfx/LocalZynAddSubFx.h index 6ab045742..9d6d66345 100644 --- a/plugins/zynaddsubfx/LocalZynAddSubFx.h +++ b/plugins/zynaddsubfx/LocalZynAddSubFx.h @@ -35,6 +35,8 @@ public: LocalZynAddSubFx(); ~LocalZynAddSubFx(); + void initConfig(); + void setSampleRate( int _sampleRate ); void setBufferSize( int _bufferSize ); diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp index 50010981b..f5162077e 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp @@ -152,17 +152,12 @@ void ZynAddSubFxInstrument::saveSettings( QDomDocument & _doc, } m_pluginMutex.unlock(); QByteArray a = tf.readAll(); - // remove first blank line - a.remove( 0, -#ifdef LMMS_BUILD_WIN32 - 2 -#else - 1 -#endif - ); QDomDocument doc( "mydoc" ); - doc.setContent( a ); - _this.appendChild( doc.documentElement() ); + if( doc.setContent( a ) ) + { + QDomNode n = _doc.importNode( doc.documentElement(), true ); + _this.appendChild( n ); + } } } @@ -183,7 +178,6 @@ void ZynAddSubFxInstrument::loadSettings( const QDomElement & _this ) if( tf.open() ) { QByteArray a = doc.toString( 0 ).toUtf8(); - a.prepend( "\n" ); tf.write( a ); tf.flush(); @@ -316,17 +310,17 @@ void ZynAddSubFxInstrument::initPlugin() m_remotePlugin->lock(); m_remotePlugin->waitForInitDone( false ); + m_remotePlugin->sendMessage( + RemotePlugin::message( IdZasfLmmsWorkingDirectory ). + addString( + QSTR_TO_STDSTR( + QString( configManager::inst()->workingDir() ) ) ) ); m_remotePlugin->sendMessage( RemotePlugin::message( IdZasfPresetDirectory ). addString( QSTR_TO_STDSTR( QString( configManager::inst()->factoryPresetsDir() + QDir::separator() + "ZynAddSubFX" ) ) ) ); - m_remotePlugin->sendMessage( - RemotePlugin::message( IdZasfLmmsWorkingDirectory ). - addString( - QSTR_TO_STDSTR( - QString( configManager::inst()->workingDir() ) ) ) ); m_remotePlugin->showUI(); m_remotePlugin->unlock(); } diff --git a/plugins/zynaddsubfx/fltk/CHANGES b/plugins/zynaddsubfx/fltk/CHANGES index 9d9ba3427..dc7878b18 100644 --- a/plugins/zynaddsubfx/fltk/CHANGES +++ b/plugins/zynaddsubfx/fltk/CHANGES @@ -1,5 +1,50 @@ CHANGES IN FLTK 1.3.0 + - Fixed X11/XDBE double buffering (STR #2152, #2197) + - Added new label and image alignments (STR #2269) + - Added documentation for event delivery (STR #1983) + - Fixed menu and tooltip window animation bug under X11 (compiz) + by setting an appropriate window type (STR #2082) + - redesigned CMake files (STR #2317). + - Fixed max. fd calculation, if USE_POLL is enabled (STR #2324) + - Fixed clipping for offscreen rendering (OSX, STR #2330) + - Added printing support (Fl_Printer class and friends) for native + printing on Windows and Mac OS X, PostScript printing on X11 + with CUPS or lp, and PostScript file output on all platforms + - Added basic Fl_Device abstraction layer for all drawing functions + - Fixed possibility of wrong flags() in Fl_Window::iconlabel() + (STR #2161) + - Fixed Scrollbar events when max is less than min (STR #2283) + - Added argument-less constructor in Fuid Widget Class + - Fixed menu item counting issue in Fluid (STR #2322) + - Added Fl_Menu_::find_item by callback + - Removed redundant Fl_Group casts + - Added indexing to Fl_Preferences + - Integrated default menu into Demo test app + - Added automated Xcode IDE file generation to Fluid + - Fixed lost top item in Fluid's tree browser (STR #2233) + - Fixed crash in test/Editor when freeing buffer + too soon (STR #2294) + - Fixed Fl_Preferences Cygwin wide character bug (STR #2164) + - Fixed sorting in Fl_Browser - last item would not + be sorted (STR #2300) + - Fixed window levels in OS X Cocoa (STR #2316) + - Added jpeg support to Fluid image() element + - Added loading jpeg images from memory + - Added binary data type to Fluid + - File chosser preview would hang if a device was choosen + - Replaced _WIN32 symbols that had come with UTF-8 and the + new Fl_Table widget with WIN32 + - Fixed a buffer overflow in fl_utf8from_mb() (STR #2279) + - Fixed a Windows GDI leak when testing alpha blending capabilities + - Fixed a name conflict with new (VS 2008 Express) winsock2.h + versions and another conflict that produced compile errors + with VS 2008 Express (STR #2301) + - Widgets now remove stale entries from the default callback + queue when they are deleted (STR #2302) + - Moved OS X code base to the more moder Cocoa toolkit thanks + to the awesome work of Manolo Gouy (STR #2221) + - Added template to generate new projects with Xcode. - Managing all Widget flags in a single location now (STR #2161) - Fixed all color related call to Fl_Color type (STR #2208) - File chooser preview now recognizes utf8 encoded @@ -113,6 +158,9 @@ CHANGES IN FLTK 1.3.0 - hide() and show() methods are now virtual from Fl_Widget, was only virtual since Fl_Window derived classes before. So now widget->hide() will work if widget is a window. + - New widgets: Fl_Tree, Fl_Table, Fl_Native_File_Chooser + - added Fl_Menu_ methods: insert(), find_index(), clear_submenu() + - Bug reports/enhancements now refer to the STR form http://www.fltk.org/str.php CHANGES IN FLTK 1.1.9 diff --git a/plugins/zynaddsubfx/fltk/CMake/CheckFunctionWithHeaderExists.cmake b/plugins/zynaddsubfx/fltk/CMake/CheckFunctionWithHeaderExists.cmake deleted file mode 100644 index 46694e82a..000000000 --- a/plugins/zynaddsubfx/fltk/CMake/CheckFunctionWithHeaderExists.cmake +++ /dev/null @@ -1,54 +0,0 @@ -# -# Check if the symbol exists in include files -# -# CHECK_FUNCTIONWITHHEADER_EXISTS - macro which checks the symbol exists in include files. -# SYMBOL - symbol -# FILES - include files to check -# VARIABLE - variable to return result -# - -MACRO(CHECK_FUNCTIONWITHHEADER_EXISTS SYMBOL FILES VARIABLE) - IF("${VARIABLE}" MATCHES "^${VARIABLE}$") - SET(CHECK_SYMBOL_EXISTS_CONTENT "/* */\n") - SET(MACRO_CHECK_SYMBOL_EXISTS_FLAGS ${CMAKE_REQUIRED_FLAGS}) - IF(CMAKE_REQUIRED_LIBRARIES) - SET(CHECK_SYMBOL_EXISTS_LIBS - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") - ENDIF(CMAKE_REQUIRED_LIBRARIES) - FOREACH(FILE ${FILES}) - SET(CHECK_SYMBOL_EXISTS_CONTENT - "${CHECK_SYMBOL_EXISTS_CONTENT}#include <${FILE}>\n") - ENDFOREACH(FILE) - SET(CHECK_SYMBOL_EXISTS_CONTENT - "${CHECK_SYMBOL_EXISTS_CONTENT}\nint main()\n{\n${SYMBOL};return 0;\n}\n") - - FILE(WRITE ${CMAKE_BINARY_DIR}/CMakeTmp/CheckSymbolExists.c - "${CHECK_SYMBOL_EXISTS_CONTENT}") - - MESSAGE(STATUS "Looking for ${SYMBOL}") - TRY_COMPILE(${VARIABLE} - ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}/CMakeTmp/CheckSymbolExists.c - CMAKE_FLAGS - -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_SYMBOL_EXISTS_FLAGS} - "${CHECK_SYMBOL_EXISTS_LIBS}" - OUTPUT_VARIABLE OUTPUT) - IF(${VARIABLE}) - MESSAGE(STATUS "Looking for ${SYMBOL} - found") - SET(${VARIABLE} 1 CACHE INTERNAL "Have symbol ${SYMBOL}") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeOutput.log - "Determining if the ${SYMBOL} " - "exist passed with the following output:\n" - "${OUTPUT}\nFile ${CMAKE_BINARY_DIR}/CMakeTmp/CheckSymbolExists.c:\n" - "${CHECK_SYMBOL_EXISTS_CONTENT}\n") - ELSE(${VARIABLE}) - MESSAGE(STATUS "Looking for ${SYMBOL} - not found.") - SET(${VARIABLE} "" CACHE INTERNAL "Have symbol ${SYMBOL}") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeError.log - "Determining if the ${SYMBOL} " - "exist failed with the following output:\n" - "${OUTPUT}\nFile ${CMAKE_BINARY_DIR}/CMakeTmp/CheckSymbolExists.c:\n" - "${CHECK_SYMBOL_EXISTS_CONTENT}\n") - ENDIF(${VARIABLE}) - ENDIF("${VARIABLE}" MATCHES "^${VARIABLE}$") -ENDMACRO(CHECK_FUNCTIONWITHHEADER_EXISTS) diff --git a/plugins/zynaddsubfx/fltk/CMake/FLTKConfig.cmake.in b/plugins/zynaddsubfx/fltk/CMake/FLTKConfig.cmake.in index 3ed435b11..0501c6674 100644 --- a/plugins/zynaddsubfx/fltk/CMake/FLTKConfig.cmake.in +++ b/plugins/zynaddsubfx/fltk/CMake/FLTKConfig.cmake.in @@ -1,37 +1,38 @@ -#----------------------------------------------------------------------------- # # FLTKConfig.cmake - FLTK CMake configuration file for external projects. # # This file is configured by FLTK and used by the UseFLTK.cmake module # to load FLTK's settings for an external project. -# The FLTK source tree. -SET(FLTK_SOURCE_DIR "@FLTK_SOURCE_DIR@") +set(FLTK_FOUND TRUE) +set(FLTK_VERSION @FLTK_VERSION_FULL@) -# The FLTK include file directories. -SET(FLUID_COMMAND "@FLTK_FLUID_COMMAND@") -SET(FLTK_EXECUTABLE_DIRS "@FLTK_EXECUTABLE_DIRS@") -SET(FLTK_LIBRARY_DIRS "@FLTK_LIBRARY_DIRS@") -SET(FLTK_LIBRARIES "@FLTK_LIBRARIES@") -SET(FLTK_INCLUDE_DIRS "@FLTK_INCLUDE_DIRS@") +set(FLTK_FLUID_EXECUTABLE "@PREFIX_BIN@/fluid") -# The C and C++ flags added by FLTK to the cmake-configured flags. -SET(FLTK_REQUIRED_C_FLAGS "@FLTK_REQUIRED_C_FLAGS@") -SET(FLTK_REQUIRED_CXX_FLAGS "@FLTK_REQUIRED_CXX_FLAGS@") +if(NOT "@EXE_LINKER_FLAGS@" STREQUAL "") + set(FLTK_EXE_LINKER_FLAGS "@EXE_LINKER_FLAGS@") +endif(NOT "@EXE_LINKER_FLAGS@" STREQUAL "") -# The FLTK version number -SET(FLTK_VERSION_MAJOR "@FLTK_VERSION_MAJOR@") -SET(FLTK_VERSION_MINOR "@FLTK_VERSION_MINOR@") -SET(FLTK_VERSION_PATCH "@FLTK_VERSION_PATCH@") +set(FLTK_USE_FILE "@PREFIX_CONFIG@/UseFLTK.cmake") -# Is FLTK using shared libraries? -SET(FLTK_BUILD_SHARED_LIBS "@BUILD_SHARED_LIBS@") -SET(FLTK_BUILD_SETTINGS_FILE "@FLTK_BUILD_SETTINGS_FILE@") +set(FLTK_DIR "@PREFIX_CONFIG@") -# The location of the UseFLTK.cmake file. -SET(FLTK11_USE_FILE "@FLTK_USE_FILE@") +set(FLTK_BIN_DIR "@PREFIX_BIN@") +set(FLTK_LIB_DIR "@PREFIX_LIB@") +set(FLTK_INCLUDE_DIR "@PREFIX_INCLUDE@") +set(FLTK_DATA_DIR "@PREFIX_DATA@") +set(FLTK_DOC_DIR "@PREFIX_DOC@") -# The ExodusII library dependencies. -IF(NOT FLTK_NO_LIBRARY_DEPENDS) - INCLUDE("@FLTK_LIBRARY_DEPENDS_FILE@") -ENDIF(NOT FLTK_NO_LIBRARY_DEPENDS) +set(FLTK_SHARED_LIBS_FOUND @OPTION_BUILD_SHARED_LIBS@) +set(FLTK_CAIRO_FOUND @FLTK_CAIRO_FOUND@) +set(FLTK_GL_FOUND @FLTK_GL_FOUND@) +set(FLTK_THREADS_FOUND @FLTK_THREADS_FOUND@) +set(FLTK_PTHREADS_FOUND @FLTK_PTHREADS_FOUND@) +set(FLTK_BUILTIN_JPEG_FOUND @FLTK_BUILTIN_JPEG_FOUND@) +set(FLTK_BUILTIN_ZLIB_FOUND @FLTK_BUILTIN_ZLIB_FOUND@) +set(FLTK_BUILTIN_PNG_FOUND @FLTK_BUILTIN_PNG_FOUND@) +set(FLTK_XINERAMA_FOUND @FLTK_XINERAMA_FOUND@) +set(FLTK_XFT_FOUND @FLTK_XFT_FOUND@) +set(FLTK_XDBE_FOUND @FLTK_XDBE_FOUND@) + +include("@PREFIX_CONFIG@/FLTKLibraries.cmake") diff --git a/plugins/zynaddsubfx/fltk/CMake/FLTKUse.cmake b/plugins/zynaddsubfx/fltk/CMake/FLTKUse.cmake deleted file mode 100644 index 3512b5ef9..000000000 --- a/plugins/zynaddsubfx/fltk/CMake/FLTKUse.cmake +++ /dev/null @@ -1,68 +0,0 @@ -IF(NOT FLTK11_FOUND) - MESSAGE(FATAL_ERROR "Something went wrong. You are including FLTKUse.cmake but FLTK was not found") -ENDIF(NOT FLTK11_FOUND) - -# ------------------------------------------------------------- -# This macro automates wrapping of Fluid files -# Specify the output variable name and the list of sources -# The output variable can be directly added to the target. -# -# For example: -# FLTK_WRAP_FLUID(CubeView_SRCS CubeViewUI.fl) -# ADD_EXECUTABLE(CubeView CubeMain.cxx CubeView.cxx CubeView.h ${CubeView_SRCS}) -# ------------------------------------------------------------- -MACRO(FLTK_WRAP_FLUID VARIABLE) - FOREACH(src ${ARGN}) - IF("${src}" MATCHES ".fl$") - GET_FILENAME_COMPONENT(fname ${src} NAME_WE) - GET_FILENAME_COMPONENT(fpath ${src} PATH) - GET_SOURCE_FILE_PROPERTY(gen ${src} GENERATED) - IF(gen) - SET(fluid_name "${src}") - ELSE(gen) - SET(fluid_name "${CMAKE_CURRENT_SOURCE_DIR}/${fpath}/${fname}.fl") - IF(NOT EXISTS "${fluid_name}") - SET(fluid_name "${CMAKE_CURRENT_BINARY_DIR}/${fpath}/${fname}.fl") - IF(NOT EXISTS "${fluid_name}") - SET(fluid_name "${fpath}/${fname}.fl") - IF(NOT EXISTS "${fluid_name}") - MESSAGE(SEND_ERROR "Cannot find Fluid source file: ${fpath}/${fname}.fl") - ENDIF(NOT EXISTS "${fluid_name}") - ENDIF(NOT EXISTS "${fluid_name}") - ENDIF(NOT EXISTS "${fluid_name}") - ENDIF(gen) - SET(cxx_name "${CMAKE_CURRENT_BINARY_DIR}/${fname}.cxx") - SET(h_name "${CMAKE_CURRENT_BINARY_DIR}/${fname}.h") - SET(${VARIABLE} "${${VARIABLE}};${cxx_name}") - ADD_CUSTOM_COMMAND( - OUTPUT ${cxx_name} - DEPENDS "${fluid_name}" "${FLUID_COMMAND}" - COMMAND ${FLUID_COMMAND} - ARGS -c ${fluid_name}) - ADD_CUSTOM_COMMAND( - OUTPUT ${h_name} - DEPENDS "${fluid_name}" "${FLUID_COMMAND}" - COMMAND ${FLUID_COMMAND} - ARGS -c ${fluid_name}) - ENDIF("${src}" MATCHES ".fl$") - ENDFOREACH(src) -ENDMACRO(FLTK_WRAP_FLUID VARIABLE) - - -# Make FLTK easier to use -INCLUDE_DIRECTORIES(${FLTK_INCLUDE_DIRS}) -LINK_DIRECTORIES(${FLTK_LIBRARY_DIRS}) - -# Load the compiler settings used for FLTK. -IF(FLTK_BUILD_SETTINGS_FILE) - INCLUDE(CMakeImportBuildSettings) - CMAKE_IMPORT_BUILD_SETTINGS(${FLTK_BUILD_SETTINGS_FILE}) -ENDIF(FLTK_BUILD_SETTINGS_FILE) - -# Add compiler flags needed to use FLTK. -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLTK_REQUIRED_C_FLAGS}") -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLTK_REQUIRED_CXX_FLAGS}") -SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLTK_REQUIRED_EXE_LINKER_FLAGS}") -SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FLTK_REQUIRED_SHARED_LINKER_FLAGS}") -SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FLTK_REQUIRED_MODULE_LINKER_FLAGS}") - diff --git a/plugins/zynaddsubfx/fltk/CMake/PlatformTests.cxx b/plugins/zynaddsubfx/fltk/CMake/PlatformTests.cxx deleted file mode 100644 index bfe97ac95..000000000 --- a/plugins/zynaddsubfx/fltk/CMake/PlatformTests.cxx +++ /dev/null @@ -1,81 +0,0 @@ -#ifdef HAVE_LIBZ - -#include - -int main() -{ - unsigned long compressedSize = 0; - unsigned char cd[100]; - const unsigned char ud[100] = ""; - unsigned long uncompressedSize = 0; - - // Call zlib's compress function. - if(compress(cd, &compressedSize, ud, uncompressedSize) != Z_OK) - { - return 0; - } - return 1; -} - - -#endif - -#ifdef HAVE_LIBJPEG - -#include -#include - -int main() -{ - struct jpeg_decompress_struct cinfo; - jpeg_create_decompress(&cinfo); - jpeg_read_header(&cinfo, TRUE); - return 1; -} - -#endif - -#ifdef HAVE_LIBPNG -#include -int main() -{ - png_structp png_ptr = png_create_read_struct - (PNG_LIBPNG_VER_STRING, (png_voidp)NULL, - NULL, NULL); - png_infop info_ptr = png_create_info_struct(png_ptr); - png_set_sig_bytes(png_ptr, 8); - png_read_info(png_ptr, info_ptr); - - return 0; -} -#endif - -#ifdef HAVE_PNG_H -#include -int main() { retunr 0;} -#endif - -#ifdef HAVE_PNG_GET_VALID -#include -int main() -{ - png_structp png_ptr = png_create_read_struct - (PNG_LIBPNG_VER_STRING, (png_voidp)NULL, - NULL, NULL); - png_infop info_ptr = png_create_info_struct(png_ptr); - png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS); - return 0; -} -#endif - -#ifdef HAVE_PNG_SET_TRNS_TO_ALPHA -#include -int main() -{ - png_structp png_ptr = png_create_read_struct - (PNG_LIBPNG_VER_STRING, (png_voidp)NULL, - NULL, NULL); - png_set_tRNS_to_alpha(png_ptr); - return 0; -} -#endif diff --git a/plugins/zynaddsubfx/fltk/CMake/UseFLTK.cmake.in b/plugins/zynaddsubfx/fltk/CMake/UseFLTK.cmake.in new file mode 100644 index 000000000..9518d26ba --- /dev/null +++ b/plugins/zynaddsubfx/fltk/CMake/UseFLTK.cmake.in @@ -0,0 +1,8 @@ +# +# automatically generated - do not edit + +include_directories("@PREFIX_INCLUDE@") + +if(FLTK_EXE_LINKER_FLAGS) + list(APPEND CMAKE_EXE_LINKER_FLAGS "${FLTK_EXE_LINKER_FLAGS}") +endif(FLTK_EXE_LINKER_FLAGS) diff --git a/plugins/zynaddsubfx/fltk/CMake/cmake_uninstall.cmake.in b/plugins/zynaddsubfx/fltk/CMake/cmake_uninstall.cmake.in new file mode 100644 index 000000000..ed3a5bdfd --- /dev/null +++ b/plugins/zynaddsubfx/fltk/CMake/cmake_uninstall.cmake.in @@ -0,0 +1,19 @@ +if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR + "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") +endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") + +foreach(file ${files}) +message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + exec_program("@CMAKE_COMMAND@" + ARGS "-E remove -f \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + endif(NOT "${rm_retval}" STREQUAL 0) +endforeach(file) diff --git a/plugins/zynaddsubfx/fltk/CMake/posixScandir.cxx b/plugins/zynaddsubfx/fltk/CMake/posixScandir.cxx new file mode 100644 index 000000000..ea57e9ce2 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/CMake/posixScandir.cxx @@ -0,0 +1,10 @@ + +#include + +int func (const char *d, dirent ***list, void *sort) { + int n = scandir(d, list, 0, (int(*)(const dirent **, const dirent **))sort); +} + +int main() { + return 0; +} diff --git a/plugins/zynaddsubfx/fltk/CMakeLists.txt b/plugins/zynaddsubfx/fltk/CMakeLists.txt index 5010016f3..e7231f6d9 100644 --- a/plugins/zynaddsubfx/fltk/CMakeLists.txt +++ b/plugins/zynaddsubfx/fltk/CMakeLists.txt @@ -1,427 +1,698 @@ +# +# "$Id: CMakeLists.txt 7461 2010-04-06 20:36:34Z AlbrechtS $" +# # Main CMakeLists.txt to build the FLTK project using CMake (www.cmake.org) # Written by Andy Cedilnik and Julien Jomier +# +# Copyright 1998-2010 by Bill Spitzak and others. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA. +# +# Please report all bugs and problems on the following page: +# +# http:#www.fltk.org/str.php +# -PROJECT(FLTK) -CMAKE_MINIMUM_REQUIRED(VERSION 2.0) +####################################################################### +# basic setup +####################################################################### +project(FLTK) +cmake_minimum_required(VERSION 2.6) # The FLTK version -SET(FLTK_VERSION_MAJOR "1") -SET(FLTK_VERSION_MINOR "3") -SET(FLTK_VERSION_PATCH "0") -SET(FLTK_VERSION "${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR}") -SET(FLTK_VERSION_FULL "${FLTK_VERSION}.${FLTK_VERSION_PATCH}") +set(FLTK_VERSION_MAJOR "1") +set(FLTK_VERSION_MINOR "3") +set(FLTK_VERSION_PATCH "0") +set(FLTK_VERSION "${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR}") +set(FLTK_VERSION_FULL "${FLTK_VERSION}.${FLTK_VERSION_PATCH}") -SET(FLTK_LIBRARIES "fltk_images;fltk;fltk_gl;fltk_forms") - -# Executables and libraries should just go to bin -SET(EXECUTABLE_OUTPUT_PATH "${FLTK_BINARY_DIR}/bin" CACHE INTERNAL - "Where to put the executables for FLTK" - ) -SET(LIBRARY_OUTPUT_PATH "${FLTK_BINARY_DIR}/bin" CACHE INTERNAL - "Where to put the libraries for FLTK" - ) - -# Allow building shared libraries -OPTION(BUILD_SHARED_LIBS "Build FLTK as a shared library" OFF) +set(EXECUTABLE_OUTPUT_PATH ${FLTK_BINARY_DIR}/bin) +set(LIBRARY_OUTPUT_PATH ${FLTK_BINARY_DIR}/lib) +set(ARCHIVE_OUTPUT_PATH ${FLTK_BINARY_DIR}/lib) # Search for modules in the FLTK source dir first -SET(CMAKE_MODULE_PATH ${FLTK_SOURCE_DIR}/CMake ${CMAKE_MODULE_PATH}) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${FLTK_SOURCE_DIR}/CMake) -#----------------------------------------------------------------------------- -# Test for some required system information. -FIND_PACKAGE(Threads) -SET (CMAKE_USE_PTHREADS - "${CMAKE_USE_PTHREADS_INIT}" CACHE BOOL "Use the pthreads library.") +include_directories(${FLTK_SOURCE_DIR} ${FLTK_BINARY_DIR}) -# We need ansi c-flags, especially on HP -SET(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}") -SET(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_CFLAGS}) - -IF(WIN32) - IF(NOT CYGWIN) - IF(BORLAND) - SET( FLTK_PLATFORM_DEPENDENT_LIBS import32 ) - ELSE(BORLAND) - SET( FLTK_PLATFORM_DEPENDENT_LIBS comctl32 ) - ENDIF(BORLAND) - ENDIF(NOT CYGWIN) -ELSE(WIN32) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") -ENDIF(WIN32) +# If this is out-of-source build, then copy FL directory +if(NOT ${FLTK_SOURCE_DIR} STREQUAL ${FLTK_BINARY_DIR}) + file(GLOB FLTK_HEADER_FILES ${FLTK_SOURCE_DIR}/FL/*.[hHr]) + foreach(file ${FLTK_HEADER_FILES}) + GET_FILENAME_COMPONENT(name ${file} NAME) + CONFIGURE_file(${file} ${FLTK_BINARY_DIR}/FL/${name} COPYONLY) + endforeach(file) +endif(NOT ${FLTK_SOURCE_DIR} STREQUAL ${FLTK_BINARY_DIR}) -IF(UNIX) - FIND_PACKAGE(X11) - SET(USE_X11 1) - SET( FLTK_PLATFORM_DEPENDENT_LIBS ${X11_LIBRARIES} -lm) - SET( FLTK_PLATFORM_DEPENDENT_LIBS ${X11_LIBRARIES} -lm) - SET(USE_XFT 0) - IF(X11_Xft_FOUND) - FIND_PACKAGE(Freetype) - IF(FREETYPE_FOUND) - SET(FOUND_XFT 1) - SET(FLTK_PLATFORM_DEPENDENT_LIBS ${FLTK_PLATFORM_DEPENDENT_LIBS} ${X11_Xft_LIB} ${FREETYPE_LIBRARIES}) - INCLUDE_DIRECTORIES(${FREETYPE_INCLUDE_DIRS} ${X11_Xft_INCLUDE_PATH}) - ENDIF(FREETYPE_FOUND) - ENDIF(X11_Xft_FOUND) -ENDIF(UNIX) +####################################################################### +# platform dependent information +####################################################################### +# On unix create backward compatibility symlinks +if(CMAKE_HOST_UNIX) + if(NOT EXISTS ${FLTK_BINARY_DIR}/Fl) + EXECUTE_PROCESS(COMMAND ln -s FL Fl + WORKING_DIRECTORY ${FLTK_BINARY_DIR} + ) + endif(NOT EXISTS ${FLTK_BINARY_DIR}/Fl) + file(GLOB FLTK_HEADER_FILES ${FLTK_BINARY_DIR}/FL/*.H) + foreach(file ${FLTK_HEADER_FILES}) + GET_FILENAME_COMPONENT(nameWE ${file} NAME_WE) + if(NOT EXISTS ${FLTK_BINARY_DIR}/FL/${nameWE}.h) + EXECUTE_PROCESS(COMMAND ln -s ${nameWE}.H ${nameWE}.h + WORKING_DIRECTORY ${FLTK_BINARY_DIR}/FL + ) + endif() + endforeach(file) +endif(CMAKE_HOST_UNIX) -# OS X with X11 is not currently supported! -SET(FLTK_X11 1) -SET(FLTK_APPLE 0) -IF(APPLE) - OPTION(FLTK_APPLE_X11 "Use X11 on Mac instead of Carbon" OFF) - MARK_AS_ADVANCED(FLTK_APPLE_X11) - IF(NOT FLTK_APPLE_X11) - SET(FLTK_APPLE 1) - SET(FLTK_X11 0) - SET(USE_X11 0) - OPTION(FLTK_QUARTZ "Use Quartz instead of Quickdraw" ON) - ENDIF(NOT FLTK_APPLE_X11) -ENDIF(APPLE) +include(TestBigEndian) +TEST_BIG_ENDIAN(WORDS_BIGENDIAN) -IF(APPLE AND NOT FLTK_APPLE_X11) - SET( FLTK_PLATFORM_DEPENDENT_LIBS - "-framework Carbon -framework Cocoa -framework ApplicationServices -lz") -ENDIF(APPLE AND NOT FLTK_APPLE_X11) +if(APPLE) + set(USE_QUARTZ ON) +endif(APPLE) -IF(CYGWIN) - ADD_DEFINITIONS(-DWIN32) - SET( FLTK_PLATFORM_DEPENDENT_LIBS ole32 uuid comctl32 supc++ -lm -lgdi32) -ENDIF(CYGWIN) +if(WIN32) + if(MSVC) + add_definitions(-DWIN32_LEAN_AND_MEAN) + add_definitions(-D_CRT_SECURE_NO_WARNINGS) + endif(MSVC) + if(CMAKE_C_COMPILER_ID STREQUAL GNU) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-subsystem,windows") + endif(CMAKE_C_COMPILER_ID STREQUAL GNU) + if(MINGW AND EXISTS /mingw) + list(APPEND CMAKE_PREFIX_PATH /mingw) + endif(MINGW AND EXISTS /mingw) +endif(WIN32) -IF(MINGW) - ADD_DEFINITIONS(-DWIN32) - SET( FLTK_PLATFORM_DEPENDENT_LIBS ole32 uuid comctl32 gdi32 comdlg32) -ENDIF(MINGW) - -INCLUDE(CheckIncludeFiles) -# Check if header file exists and add it to the list. -MACRO(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE) - CHECK_INCLUDE_FILES("${PROJECT_INCLUDES};${FILE}" ${VARIABLE}) - IF(${VARIABLE}) - SET(PROJECT_INCLUDES ${PROJECT_INCLUDES} ${FILE}) - ENDIF(${VARIABLE}) -ENDMACRO(CHECK_INCLUDE_FILE_CONCAT) -#CHECK_INCLUDE_FILE_CONCAT("GL/glu.h" HAVE_GL_GLU_H) -#CHECK_INCLUDE_FILE_CONCAT("OpenGL/glu.h" HAVE_OPENGL_GLU_H) -CHECK_INCLUDE_FILE_CONCAT("dirent.h" HAVE_DIRENT_H) -CHECK_INCLUDE_FILE_CONCAT("stdio.h" HAVE_STDIO_H) -CHECK_INCLUDE_FILE_CONCAT("strings.h" HAVE_STRINGS_H) -CHECK_INCLUDE_FILE_CONCAT("sys/dir.h" HAVE_SYS_DIR_H) -CHECK_INCLUDE_FILE_CONCAT("sys/ndir.h" HAVE_SYS_NDIR_H) -CHECK_INCLUDE_FILE_CONCAT("sys/select.h" HAVE_SYS_SELECT_H) -CHECK_INCLUDE_FILE_CONCAT("sys/stdtypes.h" HAVE_SYS_STDTYPES_H) -CHECK_INCLUDE_FILE("pthread.h" CMAKE_HAVE_PTHREAD_H) - -FIND_PACKAGE(ZLIB) -FIND_PACKAGE(PNG) -FIND_PACKAGE(JPEG) - -INCLUDE(CheckSymbolExists) -INCLUDE(CheckFunctionWithHeaderExists) - -CHECK_FUNCTIONWITHHEADER_EXISTS("int strcasecmp()" "${PROJECT_INCLUDES}" HAVE_STRCASECMP) - -CHECK_SYMBOL_EXISTS(strlcat "${PROJECT_INCLUDES}" HAVE_STRLCAT) -CHECK_SYMBOL_EXISTS(strlcpy "${PROJECT_INCLUDES}" HAVE_STRLCPY) -CHECK_SYMBOL_EXISTS(vsnprintf "${PROJECT_INCLUDES}" HAVE_VSNPRINTF) -CHECK_SYMBOL_EXISTS(snprintf "${PROJECT_INCLUDES}" HAVE_SNPRINTF) -CHECK_SYMBOL_EXISTS(scandir "${PROJECT_INCLUDES}" HAVE_SCANDIR) - -INCLUDE(CheckTypeSize) +####################################################################### +# size of ints +include(CheckTypeSize) CHECK_TYPE_SIZE(short SIZEOF_SHORT) CHECK_TYPE_SIZE(int SIZEOF_INT) CHECK_TYPE_SIZE(long SIZEOF_LONG) +CHECK_TYPE_SIZE("long long" HAVE_LONG_LONG) -IF(${SIZEOF_SHORT} MATCHES "^2$") - SET(U16 "unsigned short") -ENDIF(${SIZEOF_SHORT} MATCHES "^2$") +if(${SIZEOF_SHORT} MATCHES "^2$") + set(U16 "unsigned short") +endif(${SIZEOF_SHORT} MATCHES "^2$") -IF(${SIZEOF_INT} MATCHES "^4$") - SET(U32 "unsigned") -ELSE(${SIZEOF_INT} MATCHES "^4$") - IF(${SIZEOF_LONG} MATCHES "^4$") - SET(U32 "unsigned long") - ENDIF(${SIZEOF_LONG} MATCHES "^4$") -ENDIF(${SIZEOF_INT} MATCHES "^4$") +if(${SIZEOF_INT} MATCHES "^4$") + set(U32 "unsigned") +else() + if(${SIZEOF_LONG} MATCHES "^4$") + set(U32 "unsigned long") + endif(${SIZEOF_LONG} MATCHES "^4$") +endif(${SIZEOF_INT} MATCHES "^4$") -IF(${SIZEOF_INT} MATCHES "^8$") - SET(U64 "unsigned") -ELSE(${SIZEOF_INT} MATCHES "^8$") - IF(${SIZEOF_LONG} MATCHES "^8$") - SET(U64 "unsigned long") - ENDIF(${SIZEOF_LONG} MATCHES "^8$") -ENDIF(${SIZEOF_INT} MATCHES "^8$") +if(${SIZEOF_INT} MATCHES "^8$") + set(U64 "unsigned") +else() + if(${SIZEOF_LONG} MATCHES "^8$") + set(U64 "unsigned long") + endif(${SIZEOF_LONG} MATCHES "^8$") +endif(${SIZEOF_INT} MATCHES "^8$") -# Set an option to build FLTK with OpenGL support -SET(HAVE_GL 0) -OPTION(USE_OPENGL "OpenGL Support" ON) -IF(USE_OPENGL) - FIND_PACKAGE(OpenGL) - IF(OPENGL_FOUND) - SET(HAVE_GL 1) - INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR}) - ENDIF(OPENGL_FOUND) -ENDIF(USE_OPENGL) +####################################################################### +# check for headers, libraries and functions +####################################################################### +# set default search paths +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +# headers +find_file(HAVE_ALSA_ASOUNDLIB_H alsa/asoundlib.h) +find_file(HAVE_DIRENT_H dirent.h) +find_file(HAVE_DLFCN_H dlfcn.h) +find_file(HAVE_FREETYPE_H freetype.h PATH_SUFFIXES freetype2) +find_file(HAVE_GL_GL_H GL/gl.h) +find_file(HAVE_GL_GLU_H GL/glu.h) +find_file(HAVE_LIBPNG_PNG_H libpng/png.h) +find_file(HAVE_LOCALE_H locale.h) +find_file(HAVE_NDIR_H ndir.h) +find_file(HAVE_OPENGL_GLU_H OpenGL/glu.h) +find_file(HAVE_PNG_H png.h) +find_file(HAVE_PTHREAD_H pthread.h) +find_file(HAVE_STDIO_H stdio.h) +find_file(HAVE_STRINGS_H strings.h) +find_file(HAVE_SYS_DIR_H sys/dir.h) +find_file(HAVE_SYS_NDIR_H sys/ndir.h) +find_file(HAVE_SYS_SELECT_H sys/select.h) +find_file(HAVE_SYS_STDTYPES_H sys/stdtypes.h) +find_path(HAVE_XDBE_H Xdbe.h PATH_SUFFIXES X11/extensions extensions) -# -# Perform the FLTK specific test with status output -# -MACRO(PERFORM_CMAKE_TEST FILE TEST) - IF("${TEST}" MATCHES "^${TEST}$") - # Perform test - SET(MACRO_CHECK_FUNCTION_DEFINITIONS - "-D${TEST} ${CMAKE_REQUIRED_FLAGS}") - IF(CMAKE_REQUIRED_LIBRARIES) - SET(TEST_ADD_LIBRARIES - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") - ENDIF(CMAKE_REQUIRED_LIBRARIES) - MESSAGE(STATUS "Performing Test ${TEST}") +mark_as_advanced(HAVE_ALSA_ASOUNDLIB_H HAVE_DIRENT_H HAVE_DLFCN_H) +mark_as_advanced(HAVE_FREETYPE_H HAVE_GL_GL_H HAVE_GL_GLU_H) +mark_as_advanced(HAVE_LIBPNG_PNG_H HAVE_LOCALE_H HAVE_NDIR_H) +mark_as_advanced(HAVE_OPENGL_GLU_H HAVE_PNG_H HAVE_PTHREAD_H) +mark_as_advanced(HAVE_STDIO_H HAVE_STRINGS_H HAVE_SYS_DIR_H) +mark_as_advanced(HAVE_SYS_NDIR_H HAVE_SYS_SELECT_H) +mark_as_advanced(HAVE_SYS_STDTYPES_H HAVE_XDBE_H) - TRY_COMPILE(${TEST} - ${CMAKE_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/${FILE} - CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} - -DLINK_LIBRARIES:STRING=${CMAKE_TEST_SPECIAL_LIBRARIES} - "${TEST_ADD_LIBRARIES}" - OUTPUT_VARIABLE OUTPUT) - IF(${TEST}) - SET(${TEST} 1 CACHE INTERNAL "CMake test ${FUNCTION}") - MESSAGE(STATUS "Performing Test ${TEST} - Success") - ELSE(${TEST}) - MESSAGE(STATUS "Performing Test ${TEST} - Failed") - SET(${TEST} 0 CACHE INTERNAL "Test ${FUNCTION}") - WRITE_FILE(${CMAKE_BINARY_DIR}/CMakeError.log - "Performing Test ${TEST} failed with the following output:\n" - "${OUTPUT}\n" APPEND) - ENDIF(${TEST}) - ENDIF("${TEST}" MATCHES "^${TEST}$") -ENDMACRO(PERFORM_CMAKE_TEST FILE TEST) +# where to find freetype headers +find_path(FREETYPE_PATH freetype/config/ftheader.h PATH_SUFFIXES freetype2) +if(FREETYPE_PATH) + include_directories(${FREETYPE_PATH}) +endif(FREETYPE_PATH) +mark_as_advanced(FREETYPE_PATH) -# Set an option to build the zlib library or not -OPTION(FLTK_USE_SYSTEM_ZLIB "Use's system zlib" OFF) -IF(FLTK_USE_SYSTEM_ZLIB) - IF(ZLIB_FOUND) - SET(CMAKE_TEST_SPECIAL_LIBRARIES ${ZLIB_LIBRARIES}) - SET(FLTK_ZLIB_LIBRARIES ${ZLIB_LIBRARIES}) - PERFORM_CMAKE_TEST(CMake/PlatformTests.cxx HAVE_LIBZ) - ENDIF(ZLIB_FOUND) - # We build the fltk zlib -ELSE(FLTK_USE_SYSTEM_ZLIB) - MARK_AS_ADVANCED(ZLIB_INCLUDE_DIR) - MARK_AS_ADVANCED(ZLIB_LIBRARY) -# SUBDIRS(zlib) - SET(HAVE_LIBZ 1) - SET(FLTK_ZLIB_LIBRARIES fltk_zlib) - SET(FLTK_LIBRARIES "${FLTK_LIBRARIES};fltk_zlib") - INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/zlib") -ENDIF(FLTK_USE_SYSTEM_ZLIB) +####################################################################### +# libraries +find_library(LIB_CAIRO cairo) +find_library(LIB_fontconfig fontconfig) +find_library(LIB_freetype freetype) +find_library(LIB_GL GL) +find_library(LIB_MesaGL MesaGL) +find_library(LIB_jpeg jpeg) +find_library(LIB_png png) +find_library(LIB_zlib z) -# Set an option to build the jpeg library or not -OPTION(FLTK_USE_SYSTEM_JPEG "Use's system jpeg" OFF) -IF(FLTK_USE_SYSTEM_JPEG) - IF(JPEG_FOUND) - SET(CMAKE_TEST_SPECIAL_LIBRARIES ${JPEG_LIBRARIES}) - SET(FLTK_JPEG_LIBRARIES ${JPEG_LIBRARIES}) - PERFORM_CMAKE_TEST(CMake/PlatformTests.cxx HAVE_LIBJPEG) - ENDIF(JPEG_FOUND) - # We build the fltk png -ELSE(FLTK_USE_SYSTEM_JPEG) - MARK_AS_ADVANCED(JPEG_INCLUDE_DIR) - MARK_AS_ADVANCED(JPEG_LIBRARY) -# SUBDIRS(jpeg) - SET(HAVE_LIBJPEG 1) - SET(FLTK_JPEG_LIBRARIES fltk_jpeg) - SET(FLTK_LIBRARIES "${FLTK_LIBRARIES};fltk_jpeg") - INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/jpeg") -ENDIF(FLTK_USE_SYSTEM_JPEG) +mark_as_advanced(LIB_CAIRO LIB_fontconfig LIB_freetype) +mark_as_advanced(LIB_GL LIB_MesaGL) +mark_as_advanced(LIB_jpeg LIB_png LIB_zlib) -# Set an option to build the png library or not -OPTION(FLTK_USE_SYSTEM_PNG "Use's system png" OFF) -IF(FLTK_USE_SYSTEM_PNG) - IF(PNG_FOUND) - SET(CMAKE_TEST_SPECIAL_LIBRARIES ${PNG_LIBRARIES}) - SET(FLTK_PNG_LIBRARIES ${PNG_LIBRARIES}) - PERFORM_CMAKE_TEST(CMake/PlatformTests.cxx HAVE_LIBPNG) - PERFORM_CMAKE_TEST(CMake/PlatformTests.cxx HAVE_PNG_GET_VALID) - PERFORM_CMAKE_TEST(CMake/PlatformTests.cxx HAVE_PNG_SET_TRNS_TO_ALPHA) - SET(HAVE_PNG_H 1) - ENDIF(PNG_FOUND) - # We build the fltk png -ELSE(FLTK_USE_SYSTEM_PNG) - MARK_AS_ADVANCED(PNG_INCLUDE_DIR) - MARK_AS_ADVANCED(PNG_LIBRARY) -# SUBDIRS(png) - SET(HAVE_LIBPNG 1) - SET(HAVE_PNG_H 1) - SET(FLTK_PNG_LIBRARIES fltk_png) - SET(FLTK_LIBRARIES "${FLTK_LIBRARIES};fltk_png") - INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/png") -ENDIF(FLTK_USE_SYSTEM_PNG) +####################################################################### +# functions +include(CheckFunctionExists) -SET(FLTK_DATADIR "${CMAKE_INSTALL_PREFIX}/share/FLTK") -SET(FLTK_DOCDIR "${CMAKE_INSTALL_PREFIX}/share/doc/FLTK") +if(HAVE_DLFCN_H) + set(CMAKE_REQUIRED_LIBRARIES dl) +endif(HAVE_DLFCN_H) +CHECK_FUNCTION_EXISTS(dlsym HAVE_DLSYM) -# Write out configuration header file -CONFIGURE_FILE(${FLTK_SOURCE_DIR}/configh.cmake.in - ${FLTK_BINARY_DIR}/config.h) +CHECK_FUNCTION_EXISTS(localeconv HAVE_LOCALECONV) -# On unix create symlinks for backward compatibility -SET(FLTK_CREATE_SYMLINKS 1) -IF(WIN32) - IF(NOT UNIX) - SET(FLTK_CREATE_SYMLINKS 0) - ENDIF(NOT UNIX) -ENDIF(WIN32) +if(LIB_png) + set(CMAKE_REQUIRED_LIBRARIES png) +endif(LIB_png) +CHECK_FUNCTION_EXISTS(png_get_valid HAVE_PNG_GET_VALID) +CHECK_FUNCTION_EXISTS(png_set_tRNS_to_alpha HAVE_PNG_SET_TRNS_TO_ALPHA) -MACRO(SAFE_CREATE_SYMLINK SOURCE DESTINATION) - IF(EXISTS "${DESTINATION}") - ELSE(EXISTS "${DESTINATION}") - MESSAGE(STATUS "Create symlink from: \"${SOURCE}\" to \"${DESTINATION}\"") - # The quoting here does seems unnatural, but this is to prevent bug in CMake - EXEC_PROGRAM(ln ARGS - "-s \"${SOURCE}\" \"${DESTINATION}\"" OUTPUT_VARIABLE ln_output - RETURN_VALUE ln_retval) - IF("${ln_retval}" GREATER 0) - MESSAGE(FATAL_ERROR "Problem creatin symlink from \"${SOURCE}\" to \"${DESTINATION}\":\n${ln_output}") - ENDIF("${ln_retval}" GREATER 0) - ENDIF(EXISTS "${DESTINATION}") -ENDMACRO(SAFE_CREATE_SYMLINK SOURCE DESTINATION) +CHECK_FUNCTION_EXISTS(scandir HAVE_SCANDIR) +CHECK_FUNCTION_EXISTS(snprintf HAVE_SNPRINTF) -# If this is out-of-source build, then copy FL directory -FILE(GLOB FLTK_HEADER_FILES "${FLTK_SOURCE_DIR}/FL/*.[hHr]") -FOREACH(file ${FLTK_HEADER_FILES}) - GET_FILENAME_COMPONENT(ext "${file}" EXT) - GET_FILENAME_COMPONENT(namewe "${file}" NAME_WE) - GET_FILENAME_COMPONENT(name "${file}" NAME) - STRING(COMPARE EQUAL "${ext}" ".h" lower_case_h) - STRING(COMPARE EQUAL "${ext}" ".H" upper_case_h) - IF(lower_case_h OR upper_case_h) - SET(outfile_h "${FLTK_BINARY_DIR}/FL/${namewe}.h") - SET(outfile_H "${FLTK_BINARY_DIR}/FL/${namewe}.H") - CONFIGURE_FILE("${file}" "${outfile_H}" COPYONLY IMMEDIATE) - CONFIGURE_FILE("${file}" "${outfile_h}" COPYONLY IMMEDIATE) -# IF(FLTK_CREATE_SYMLINKS) -# SAFE_CREATE_SYMLINK("${outfile_H}" "${outfile_h}") -# ENDIF(FLTK_CREATE_SYMLINKS) - ELSE(lower_case_h OR upper_case_h) - STRING(COMPARE EQUAL "${ext}" ".r" mac_resource_file) - IF(mac_resource_file) - SET(outfile "${FLTK_BINARY_DIR}/FL/${name}") - CONFIGURE_FILE("${file}" "${outfile}" COPYONLY IMMEDIATE) - ENDIF(mac_resource_file) - ENDIF(lower_case_h OR upper_case_h) -ENDFOREACH(file) +# not really true but we convert strcasecmp calls to _stricmp calls in flstring.h +if(MSVC) + set(HAVE_STRCASECMP 1) +endif(MSVC) +CHECK_FUNCTION_EXISTS(strcasecmp HAVE_STRCASECMP) -IF(FLTK_CREATE_SYMLINKS) - SAFE_CREATE_SYMLINK( - "${FLTK_BINARY_DIR}/FL" - "${FLTK_BINARY_DIR}/Fl") +CHECK_FUNCTION_EXISTS(strlcat HAVE_STRLCAT) +CHECK_FUNCTION_EXISTS(strlcpy HAVE_STRLCPY) +CHECK_FUNCTION_EXISTS(strtoll HAVE_STRTOLL) +CHECK_FUNCTION_EXISTS(vsnprintf HAVE_VSNPRINTF) -# SAFE_CREATE_SYMLINK( -# "${FLTK_BINARY_DIR}/FL/gl.H" -# "${FLTK_BINARY_DIR}/FL/gl.h") +set(CMAKE_REQUIRED_LIBRARIES) - # Create the symlinks - FILE(READ ${FLTK_SOURCE_DIR}/fltk.list.in SYMLINKSFILE) - STRING(REGEX MATCHALL "(l 0000 root sys .includedir/)([^(\n)])+" - SYMLINKS ${SYMLINKSFILE}) - FOREACH(var ${SYMLINKS} ) - IF("${var}" MATCHES ".H") - STRING(REGEX MATCH "(/F)([^(\n)])+" tmp ${var}) - STRING(REGEX MATCH "(/F)([^( )])+" in ${tmp}) - STRING(REGEX MATCH "( )([^(\n)])+" out ${tmp}) - STRING(REGEX REPLACE "( )" "" out ${out}) - SAFE_CREATE_SYMLINK("${FLTK_BINARY_DIR}/FL/${out}" "${FLTK_BINARY_DIR}/${in}") - ENDIF("${var}" MATCHES ".H") - ENDFOREACH(var) -ENDIF(FLTK_CREATE_SYMLINKS) +if(HAVE_SCANDIR AND NOT HAVE_SCANDIR_POSIX) + set(MSG "POSIX compatible scandir") + message(STATUS "Looking for ${MSG}") + try_compile(V + ${FLTK_BINARY_DIR} + ${FLTK_SOURCE_DIR}/CMake/posixScandir.cxx + ) + if(V) + message(STATUS "${MSG} - found") + set(HAVE_SCANDIR_POSIX 1 CACHE INTERNAL "") + else() + message(STATUS "${MSG} - not found") + set(HAVE_SCANDIR_POSIX HAVE_SCANDIR_POSIX-NOTFOUND) + endif(V) +endif(HAVE_SCANDIR AND NOT HAVE_SCANDIR_POSIX) +mark_as_advanced(HAVE_SCANDIR_POSIX) +####################################################################### +# options +####################################################################### +set(OPTION_OPTIM "" + CACHE STRING + "custom optimization flags" + ) +add_definitions(${OPTION_OPTIM}) + +####################################################################### +set(OPTION_ARCHFLAGS "" + CACHE STRING + "custom architecture flags" + ) +add_definitions(${OPTION_ARCHFLAGS}) + +####################################################################### +set(OPTION_PREFIX_BIN "" + CACHE STRING + "where to install executables - leave empty to use {CMAKE_INSTALL_PREFIX}/bin" + ) + +if(OPTION_PREFIX_BIN) + set(PREFIX_BIN ${OPTION_PREFIX_BIN} CACHE INTERNAL "" FORCE) +else() + set(PREFIX_BIN ${CMAKE_INSTALL_PREFIX}/bin CACHE INTERNAL "" FORCE) +endif(OPTION_PREFIX_BIN) + +####################################################################### +set(OPTION_PREFIX_LIB "" + CACHE STRING + "where to install libraries - leave empty to use {CMAKE_INSTALL_PREFIX}/lib" + ) + +if(OPTION_PREFIX_LIB) + set(PREFIX_LIB ${OPTION_PREFIX_LIB} CACHE INTERNAL "" FORCE) +else() + set(PREFIX_LIB ${CMAKE_INSTALL_PREFIX}/lib CACHE INTERNAL "" FORCE) +endif(OPTION_PREFIX_LIB) + +####################################################################### +set(OPTION_PREFIX_INCLUDE "" + CACHE STRING + "where to install include files - leave empty to use {CMAKE_INSTALL_PREFIX}/include" + ) + +if(OPTION_PREFIX_INCLUDE) + set(PREFIX_INCLUDE ${OPTION_PREFIX_INCLUDE} CACHE INTERNAL "" FORCE) +else() + set(PREFIX_INCLUDE ${CMAKE_INSTALL_PREFIX}/include CACHE INTERNAL "" FORCE) +endif(OPTION_PREFIX_INCLUDE) + +####################################################################### +set(OPTION_PREFIX_DATA "" + CACHE STRING + "where to install data files - leave empty to use {CMAKE_INSTALL_PREFIX}/share/FLTK" + ) + +if(OPTION_PREFIX_DATA) + set(PREFIX_DATA ${OPTION_PREFIX_DATA} CACHE INTERNAL "" FORCE) +else() + set(PREFIX_DATA ${CMAKE_INSTALL_PREFIX}/share/FLTK CACHE INTERNAL "" FORCE) +endif(OPTION_PREFIX_DATA) + +####################################################################### +set(OPTION_PREFIX_DOC "" + CACHE STRING + "where to install doc files - leave empty to use {CMAKE_INSTALL_PREFIX}/share/doc/FLTK" + ) + +if(OPTION_PREFIX_DOC) + set(PREFIX_DOC ${OPTION_PREFIX_DOC} CACHE INTERNAL "" FORCE) +else() + set(PREFIX_DOC ${CMAKE_INSTALL_PREFIX}/share/doc/FLTK CACHE INTERNAL "" FORCE) +endif(OPTION_PREFIX_DOC) + +####################################################################### +if(WIN32) + set(DEFAULT_CONFIG "${CMAKE_INSTALL_PREFIX}/CMake") +elseif(APPLE) + set(DEFAULT_CONFIG "${CMAKE_INSTALL_PREFIX}/FLTK/.framework/Resources/CMake") +else() + set(DEFAULT_CONFIG "${CMAKE_INSTALL_PREFIX}/lib/FLTK-${FLTK_VERSION}") +endif(WIN32) + +set(OPTION_PREFIX_CONFIG "" + CACHE STRING + "where to install CMake config files - leave empty to use ${DEFAULT_CONFIG}" + ) + +if(OPTION_PREFIX_CONFIG) + set(PREFIX_CONFIG "${OPTION_PREFIX_CONFIG}" CACHE INTERNAL "" FORCE) +else() + set(PREFIX_CONFIG "${DEFAULT_CONFIG}" CACHE INTERNAL "" FORCE) +endif(OPTION_PREFIX_CONFIG) + +####################################################################### +if(CMAKE_HOST_UNIX) + set(OPTION_PREFIX_MAN "" + CACHE STRING + "where to install man files - leave empty to use {CMAKE_INSTALL_PREFIX}/man" + ) + + if(OPTION_PREFIX_MAN) + set(PREFIX_MAN ${OPTION_PREFIX_MAN} CACHE INTERNAL "" FORCE) + else() + set(PREFIX_MAN ${CMAKE_INSTALL_PREFIX}/man CACHE INTERNAL "" FORCE) + endif(OPTION_PREFIX_MAN) + +endif(CMAKE_HOST_UNIX) + +####################################################################### +if(APPLE) + option(OPTION_APPLE_X11 "use X11" OFF) +endif(APPLE) + +if(NOT APPLE OR OPTION_APPLE_X11) + include(FindX11) + if(X11_FOUND) + set(USE_X11 1) + list(APPEND FLTK_CFLAGS -DUSE_X11) + list(APPEND FLTK_LDLIBS -lX11) + endif(X11_FOUND) +endif(NOT APPLE OR OPTION_APPLE_X11) + +####################################################################### +option(OPTION_USE_POLL "use poll if available" OFF) + +if(OPTION_USE_POLL) + CHECK_FUNCTION_EXISTS(poll USE_POLL) +endif(OPTION_USE_POLL) + +####################################################################### +option(OPTION_BUILD_SHARED_LIBS "Build shared libraries" OFF) + +####################################################################### +option(OPTION_BUILD_EXAMPLES "build example programs" ON) + +####################################################################### +include(FindPkgConfig) + +option(OPTION_CAIRO "use lib Cairo" OFF) +option(OPTION_CAIROEXT + "use fltk code instrumentation for cairo extended use" OFF + ) + +if(OPTION_CAIRO OR OPTION_CAIROEXT AND LIB_CAIRO) + pkg_search_module(PKG_CAIRO cairo) +endif(OPTION_CAIRO OR OPTION_CAIROEXT AND LIB_CAIRO) + +if(PKG_CAIRO_FOUND) + set(HAVE_CAIRO 1) + add_subdirectory(cairo) + list(APPEND FLTK_LDLIBS -lcairo -lpixman-1) + include_directories(${PKG_CAIRO_INCLUDE_DIRS}) + string(REPLACE ";" " " CAIROFLAGS "${PKG_CAIRO_CFLAGS}") +endif(PKG_CAIRO_FOUND) + +if(LIB_CAIRO AND OPTION_CAIROEXT AND PKG_CAIRO_FOUND) + set(USE_CAIRO 1) + set(FLTK_CAIRO_FOUND TRUE) +else() + set(FLTK_CAIRO_FOUND FALSE) +endif(LIB_CAIRO AND OPTION_CAIROEXT AND PKG_CAIRO_FOUND) + +####################################################################### +set(HAVE_GL LIB_GL OR LIB_MesaGL) + +if(HAVE_GL) + option(OPTION_USE_GL "use OpenGL" ON) +endif(HAVE_GL) + +if(OPTION_USE_GL) + include(FindOpenGL) +endif(OPTION_USE_GL) + +if(OPENGL_FOUND) + set(CMAKE_REQUIRED_INCLUDES ${OPENGL_INCLUDE_DIR}/GL) + set(CMAKE_REQUIRED_LIBRARIES -lGLU -lGL) + CHECK_FUNCTION_EXISTS(glXGetProcAddressARB HAVE_GLXGETPROCADDRESSARB) + set(FLTK_GL_FOUND TRUE) +else() + set(FLTK_GL_FOUND FALSE) +endif(OPENGL_FOUND) + +####################################################################### +option(OPTION_USE_THREADS "use multi-threading" ON) + +if(OPTION_USE_THREADS) + include(FindThreads) +endif(OPTION_USE_THREADS) + +if(OPTION_USE_THREADS AND CMAKE_HAVE_THREADS_LIBRARY) + add_definitions("-D_THREAD_SAFE -D_REENTRANT") + set(USE_THREADS 1) + set(FLTK_THREADS_FOUND TRUE) +else() + set(FLTK_THREADS_FOUND FALSE) +endif(OPTION_USE_THREADS AND CMAKE_HAVE_THREADS_LIBRARY) + +if(OPTION_USE_THREADS AND CMAKE_USE_PTHREADS_INIT) + set(HAVE_PTHREAD 1) + list(APPEND FLTK_LDLIBS -lpthread) + list(APPEND FLTK_CFLAGS -D_THREAD_SAFE -D_REENTRANT) + set(FLTK_PTHREADS_FOUND TRUE) +else() + set(HAVE_PTHREAD 0) + set(HAVE_PTHREAD_H 0) + set(FLTK_PTHREADS_FOUND FALSE) +endif(OPTION_USE_THREADS AND CMAKE_USE_PTHREADS_INIT) + +####################################################################### +option(OPTION_LARGE_FILE "enable large file support" ON) + +if(OPTION_LARGE_FILE) + if(NOT MSVC) + add_definitions(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE) + list(APPEND FLTK_CFLAGS -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE) + endif(NOT MSVC) +endif(OPTION_LARGE_FILE) + +####################################################################### +option(OPTION_USE_SYSTEM_LIBJPEG "Use's system libjpeg" ON) + +if(OPTION_USE_SYSTEM_LIBJPEG AND LIB_jpeg) + include(FindJPEG) +endif(OPTION_USE_SYSTEM_LIBJPEG AND LIB_jpeg) + +if(OPTION_USE_SYSTEM_LIBJPEG AND JPEG_FOUND) + set(FLTK_JPEG_LIBRARIES ${JPEG_LIBRARIES}) + include_directories(${JPEG_INCLUDE_DIR}) + set(FLTK_BUILTIN_JPEG_FOUND FALSE) +else() + set(FLTK_JPEG_LIBRARIES fltk_jpeg) + include_directories(${FLTK_SOURCE_DIR}/jpeg) + set(FLTK_BUILTIN_JPEG_FOUND TRUE) +endif(OPTION_USE_SYSTEM_LIBJPEG AND JPEG_FOUND) + +if(OPTION_USE_SYSTEM_LIBJPEG AND NOT JPEG_FOUND) + message(STATUS "\ncannot find system jpeg library - using built-in\n") +endif(OPTION_USE_SYSTEM_LIBJPEG AND NOT JPEG_FOUND) + +set(HAVE_LIBJPEG 1) + +####################################################################### +option(OPTION_USE_SYSTEM_ZLIB "Use's system zlib" ON) + +if(OPTION_USE_SYSTEM_ZLIB AND LIB_zlib) + include(FindZLIB) +endif(OPTION_USE_SYSTEM_ZLIB AND LIB_zlib) + +if(OPTION_USE_SYSTEM_ZLIB AND ZLIB_FOUND) + set(FLTK_ZLIB_LIBRARIES ${ZLIB_LIBRARIES}) + include_directories(${ZLIB_INCLUDE_DIRS}) + set(FLTK_BUILTIN_ZLIB_FOUND FALSE) +else() + set(FLTK_ZLIB_LIBRARIES fltk_z) + set(ZLIB_INCLUDE_DIR ${FLTK_SOURCE_DIR}/zlib) + include_directories(${FLTK_SOURCE_DIR}/zlib) + set(FLTK_BUILTIN_ZLIB_FOUND TRUE) +endif(OPTION_USE_SYSTEM_ZLIB AND ZLIB_FOUND) + +if(OPTION_USE_SYSTEM_ZLIB AND NOT ZLIB_FOUND) + message(STATUS "\ncannot find system zlib library - using built-in\n") +endif(OPTION_USE_SYSTEM_ZLIB AND NOT ZLIB_FOUND) + +set(HAVE_LIBZ 1) + +####################################################################### +option(OPTION_USE_SYSTEM_LIBPNG "Use's system libpng" ON) + +if(OPTION_USE_SYSTEM_LIBPNG AND LIB_png) + include(FindPNG) +endif(OPTION_USE_SYSTEM_LIBPNG AND LIB_png) + +if(OPTION_USE_SYSTEM_LIBPNG AND PNG_FOUND) + set(FLTK_PNG_LIBRARIES ${PNG_LIBRARIES}) + include_directories(${PNG_INCLUDE_DIR}) + add_definitions(${PNG_DEFINITIONS}) + set(FLTK_BUILTIN_PNG_FOUND FALSE) +else() + set(FLTK_PNG_LIBRARIES fltk_png) + set(HAVE_PNG_H 1) + set(HAVE_PNG_GET_VALID 1) + set(HAVE_PNG_SET_TRNS_TO_ALPHA 1) + include_directories(${FLTK_SOURCE_DIR}/png) + set(FLTK_BUILTIN_PNG_FOUND TRUE) +endif(OPTION_USE_SYSTEM_LIBPNG AND PNG_FOUND) + +if(OPTION_USE_SYSTEM_LIBPNG AND NOT PNG_FOUND) + message(STATUS "\ncannot find system png library - using built-in\n") +endif(OPTION_USE_SYSTEM_LIBPNG AND NOT PNG_FOUND) + +set(HAVE_LIBPNG 1) + +####################################################################### +if(X11_Xinerama_FOUND) + option(OPTION_USE_XINERAMA "use lib Xinerama" ON) +endif(X11_Xinerama_FOUND) + +if(OPTION_USE_XINERAMA) + set(HAVE_XINERAMA X11_Xinerama_FOUND) + include_directories(${X11_Xinerama_INCLUDE_PATH}) + list(APPEND FLTK_LDLIBS -lXinerama) + set(FLTK_XINERAMA_FOUND TRUE) +else() + set(FLTK_XINERAMA_FOUND FALSE) +endif(OPTION_USE_XINERAMA) + +####################################################################### +if(X11_Xft_FOUND) + option(OPTION_USE_XFT "use lib Xft" ON) +endif(X11_Xft_FOUND) + +if(OPTION_USE_XFT) + set(USE_XFT X11_Xft_FOUND) + list(APPEND FLTK_LDLIBS -lXft) + set(FLTK_XFT_FOUND TRUE) +else() + set(FLTK_XFT_FOUND FALSE) +endif(OPTION_USE_XFT) + +####################################################################### +if(X11_FOUND) + option(OPTION_USE_XDBE "use lib Xdbe" ON) +endif(X11_FOUND) + +if(OPTION_USE_XDBE AND HAVE_XDBE_H) + set(HAVE_XDBE 1) + set(FLTK_XDBE_FOUND TRUE) +else() + set(FLTK_XDBE_FOUND FALSE) +endif(OPTION_USE_XDBE AND HAVE_XDBE_H) + +####################################################################### +# final setup and config +####################################################################### # Set the fluid executable path -#UTILITY_SOURCE(FLUID_COMMAND fluid fluid fluid.cxx) -#SET(FLUID_COMMAND "${FLUID_COMMAND}" CACHE INTERNAL "" FORCE) +if(CMAKE_CROSSCOMPILING) + find_file(FLUID_PATH + NAMES fluid fluid.exe + PATHS ENV PATH + NO_CMAKE_FIND_ROOT_PATH + ) + add_executable(fluid IMPORTED) + set(FLTK_FLUID_EXECUTABLE fluid) + set(FLTK_FLUID_PATH ${FLUID_PATH}) + set_target_properties(fluid + PROPERTIES IMPORTED_LOCATION ${FLUID_PATH} + ) +else() + set(FLTK_FLUID_EXECUTABLE fluid) + set(FLTK_FLUID_PATH ${EXECUTABLE_OUTPUT_PATH}/${FLTK_FLUID_EXECUTABLE}) +endif(CMAKE_CROSSCOMPILING) -# Include header files in fltk binary tree -INCLUDE_DIRECTORIES(${FLTK_BINARY_DIR}) +add_subdirectory(src) -# Do the build of fltk libraries and fluid -SUBDIRS(src) -#SUBDIRS(fluid) +# generate FLTKConfig.cmake +string(REPLACE ";" " " EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") +configure_file(${FLTK_SOURCE_DIR}/CMake/FLTKConfig.cmake.in + ${EXECUTABLE_OUTPUT_PATH}/FLTKConfig.cmake + @ONLY + ) +# generate UseFLTK.cmake +configure_file(${FLTK_SOURCE_DIR}/CMake/UseFLTK.cmake.in + ${EXECUTABLE_OUTPUT_PATH}/UseFLTK.cmake + @ONLY + ) -# Set an option to build the examples and testing -OPTION(BUILD_EXAMPLES "Build the tests" ON) -IF(BUILD_EXAMPLES) -# SUBDIRS(test) -ENDIF(BUILD_EXAMPLES) +# generate config.h +configure_file("${FLTK_SOURCE_DIR}/configh.cmake.in" + "${FLTK_BINARY_DIR}/config.h" @ONLY + ) -OPTION(BUILD_TESTING "Build testing of FLTK" ON) -IF(BUILD_TESTING) - ENABLE_TESTING() - INCLUDE(Dart) -ENDIF(BUILD_TESTING) +# generate fltk-config +get_filename_component(CC ${CMAKE_C_COMPILER} NAME) +get_filename_component(CXX ${CMAKE_CXX_COMPILER} NAME) -#----------------------------------------------------------------------------- -# Help outside projects build FLTK projects. -INCLUDE(CMakeExportBuildSettings) -EXPORT_LIBRARY_DEPENDENCIES(${FLTK_BINARY_DIR}/FLTKLibraryDepends.cmake) -CMAKE_EXPORT_BUILD_SETTINGS(${FLTK_BINARY_DIR}/FLTKBuildSettings.cmake) -SET(FL_MAJOR_VERSION "${FLTK_VERSION_MAJOR}") -SET(FL_MINOR_VERSION "${FLTK_VERSION_MINOR}") -SET(FL_PATCH_VERSION "${FLTK_VERSION_PATCH}") +string(REPLACE ";" " " C_FLAGS "${FLTK_CFLAGS}") -SET(CFLAGS "${CMAKE_C_FLAGS}") -SET(CXXFLAGS "${CMAKE_CXX_FLAGS}") -SET(CC "${CMAKE_C_COMPILER}") -SET(CXX "${CMAKE_CXX_COMPILER}") +if(X11_Xext_FOUND) + list(APPEND FLTK_LDLIBS -lXext) +endif(X11_Xext_FOUND) +string(REPLACE ";" " " LD_LIBS "${FLTK_LDLIBS}") -# For build tree usage -SET(FLTK_FLUID_COMMAND "${FLUID_COMMAND}") -SET(FLTK_LIBRARY_DEPENDS_FILE ${FLTK_BINARY_DIR}/FLTKLibraryDepends.cmake) -SET(FLTK_EXECUTABLE_DIRS ${EXECUTABLE_OUTPUT_PATH}) -SET(FLTK_LIBRARY_DIRS ${LIBRARY_OUTPUT_PATH}) -SET(FLTK_USE_FILE ${FLTK_SOURCE_DIR}/CMake/FLTKUse.cmake) -SET(FLTK_INCLUDE_DIRS "${FLTK_BINARY_DIR}/") -SET(FLTK_BUILD_SETTINGS_FILE ${FLTK_BINARY_DIR}/FLTKBuildSettings.cmake) -SET(prefix "${FLTK_BINARY_DIR}") -SET(exec_prefix "${prefix}") -SET(exec_prefix_set "no") -SET(bindir "${prefix}/bin") -SET(includedir "${prefix}") -SET(libdir "${prefix}/bin") -SET(srcdir "${FLTK_SOURCE_DIR}") +configure_file(${FLTK_SOURCE_DIR}/fltk-config.cmake.in + ${FLTK_BINARY_DIR}/fltk-config + ) +if(UNIX) + execute_process(COMMAND chmod 755 fltk-config + WORKING_DIRECTORY ${FLTK_BINARY_DIR} + ) +endif(UNIX) -CONFIGURE_FILE("${FLTK_SOURCE_DIR}/CMake/FLTKConfig.cmake.in" - "${FLTK_BINARY_DIR}/FLTKConfig.cmake" @ONLY IMMEDIATE) -CONFIGURE_FILE("${FLTK_SOURCE_DIR}/fltk-config.in" - "${FLTK_BINARY_DIR}/fltk-config" @ONLY IMMEDIATE) +# generate uninstall target +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/CMake/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + @ONLY + ) +add_custom_target(uninstall + "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + ) -# For installed tree usage -SET(FLTK_FLUID_COMMAND "${CMAKE_INSTALL_PREFIX}/bin/fluid") -SET(FLTK_LIBRARY_DEPENDS_FILE ${CMAKE_INSTALL_PREFIX}/lib/FLTK-${FLTK_VERSION}/FLTKLibraryDepends.cmake) -SET(FLTK_EXECUTABLE_DIRS "${CMAKE_INSTALL_PREFIX}/bin") -SET(FLTK_LIBRARY_DIRS "${CMAKE_INSTALL_PREFIX}/lib") -SET(FLTK_USE_FILE "${CMAKE_INSTALL_PREFIX}/lib/FLTK-${FLTK_VERSION}/FLTKUse.cmake") -SET(FLTK_INCLUDE_DIRS "${CMAKE_INSTALL_PREFIX}/") -SET(FLTK_BUILD_SETTINGS_FILE ${CMAKE_INSTALL_PREFIX}/lib/FLTK-${FLTK_VERSION}/FLTKBuildSettings.cmake) -SET(prefix "${CMAKE_INSTALL_PREFIX}") -SET(exec_prefix "${prefix}") -SET(exec_prefix_set "no") -SET(bindir "${prefix}/bin") -SET(includedir "${prefix}") -SET(libdir "${prefix}/lib") -SET(srcdir ".") +####################################################################### +# build examples - these have to be after fluid is built/imported +####################################################################### +if(OPTION_BUILD_EXAMPLES) + add_subdirectory(test) +endif(OPTION_BUILD_EXAMPLES) -CONFIGURE_FILE("${FLTK_SOURCE_DIR}/CMake/FLTKConfig.cmake.in" - "${FLTK_BINARY_DIR}/CMake/FLTKConfig.cmake" @ONLY IMMEDIATE) -CONFIGURE_FILE("${FLTK_SOURCE_DIR}/fltk-config.in" - "${FLTK_BINARY_DIR}/CMake/fltk-config" @ONLY IMMEDIATE) +####################################################################### +# installation +####################################################################### + +install(DIRECTORY ${FLTK_BINARY_DIR}/FL + DESTINATION ${PREFIX_INCLUDE} USE_SOURCE_PERMISSIONS + ) + +install(DIRECTORY ${FLTK_BINARY_DIR}/Fl + DESTINATION ${PREFIX_INCLUDE} USE_SOURCE_PERMISSIONS + ) + +install(PROGRAMS ${FLTK_BINARY_DIR}/fltk-config + DESTINATION ${PREFIX_BIN} + OPTIONAL + ) + +install(EXPORT fltk-install + DESTINATION ${PREFIX_CONFIG} + FILE FLTKLibraries.cmake + ) + +install(FILES ${EXECUTABLE_OUTPUT_PATH}/FLTKConfig.cmake + DESTINATION ${PREFIX_CONFIG} + ) + +install(FILES ${EXECUTABLE_OUTPUT_PATH}/UseFLTK.cmake + DESTINATION ${PREFIX_CONFIG} + ) + +if(CMAKE_HOST_UNIX) + macro(INSTALL_MAN FILE LEVEL) + install(FILES + ${FLTK_SOURCE_DIR}/documentation/src/${FILE}.man + DESTINATION ${PREFIX_MAN}/man${LEVEL} + RENAME ${FILE}.${LEVEL} + ) + endmacro(INSTALL_MAN FILE LEVEL) + + INSTALL_MAN(fluid 1) + INSTALL_MAN(fltk-config 1) + INSTALL_MAN(fltk 3) + INSTALL_MAN(blocks 6) + INSTALL_MAN(checkers 6) + INSTALL_MAN(sudoku 6) + +endif(CMAKE_HOST_UNIX) -INSTALL_FILES(/include/FL FILES ${FLTK_HEADER_FILES}) -INSTALL_FILES(/lib/FLTK-${FLTK_VERSION} FILES "${FLTK_SOURCE_DIR}/CMake/FLTKUse.cmake") -INSTALL_FILES(/lib/FLTK-${FLTK_VERSION} FILES "${FLTK_BINARY_DIR}/FLTKBuildSettings.cmake") -INSTALL_FILES(/lib/FLTK-${FLTK_VERSION} FILES "${FLTK_BINARY_DIR}/FLTKLibraryDepends.cmake") -INSTALL_FILES(/lib/FLTK-${FLTK_VERSION} FILES "${FLTK_BINARY_DIR}/CMake/FLTKConfig.cmake") diff --git a/plugins/zynaddsubfx/fltk/COPYING b/plugins/zynaddsubfx/fltk/COPYING index 0dd0e80d3..954207522 100644 --- a/plugins/zynaddsubfx/fltk/COPYING +++ b/plugins/zynaddsubfx/fltk/COPYING @@ -10,9 +10,11 @@ exceptions: a specific platform do not constitute a modified or derivative work. - The authors do request that such modifications be - contributed to the FLTK project - send all - contributions to "fltk-bugs@fltk.org". + The authors do request that such modifications be + contributed to the FLTK project - send all contributions + through the "Software Trouble Report" on the following page: + + http://www.fltk.org/str.php 2. Widgets that are subclassed from FLTK widgets do not constitute a derivative work. diff --git a/plugins/zynaddsubfx/fltk/CREDITS b/plugins/zynaddsubfx/fltk/CREDITS index 7cebe2a4d..0dee8118a 100644 --- a/plugins/zynaddsubfx/fltk/CREDITS +++ b/plugins/zynaddsubfx/fltk/CREDITS @@ -3,8 +3,10 @@ CREDITS - Fast Light Tool Kit (FLTK) Version 1.3.0 This file lists the people responsible for the toolkit you are now using. If you've looking for your name in lights - but we've forgotten you here, please send an email to - "fltk-bugs@fltk.org" and we'll update this file accordingly. + but we've forgotten you here, please use the report on the + following page, and we'll update this file accordingly: + + http://www.fltk.org/str.php CORE DEVELOPERS @@ -12,7 +14,7 @@ CORE DEVELOPERS The following people do the day-to-day development of FLTK: Fabien Costantini (fabien67@users.sf.net) - Craig P. Earls + Craig P. Earls Curtis Edwards (trilec@users.sourceforge.net) Gustavo Hime (hime@users.sourceforge.net) Talbot Hughes @@ -21,7 +23,7 @@ CORE DEVELOPERS James Dean Palmer (jamespalmer@users.sourceforge.net) Vincent Penne (vincentp@users.sourceforge.net) Bill Spitzak (spitzak@users.sourceforge.net) - Michael Sweet (easysw@users.sourceforge.net) + Michael Sweet (easysw@users.sourceforge.net) Carl Thompson (clip@users.sourceforge.net) Nafees Bin Zafar (nafees@users.sourceforge.net) @@ -39,6 +41,7 @@ OTHER CONTRIBUTORS Yuri Fedorchenko George Garvey Duncan Gibson + Manolo Gouy Mikael Hultgren Stuart Levy Howard Lightstone @@ -47,9 +50,11 @@ OTHER CONTRIBUTORS Alexander Rabi James Roth Albrecht Schlosser - Andrea Suatoni + Andrea Suatoni + Michael Surette Paul Sydney Aaron Ucko Emanuele Vicentini + Josef Vitu Jim Wilson Ken Yarnall diff --git a/plugins/zynaddsubfx/fltk/FL/Enumerations.H b/plugins/zynaddsubfx/fltk/FL/Enumerations.H index ba92ec2b0..53c32e0a2 100644 --- a/plugins/zynaddsubfx/fltk/FL/Enumerations.H +++ b/plugins/zynaddsubfx/fltk/FL/Enumerations.H @@ -1,5 +1,5 @@ // -// "$Id: Enumerations.H 6902 2009-09-27 11:06:56Z matt $" +// "$Id: Enumerations.H 7476 2010-04-09 22:18:05Z matt $" // // Enumerations for the Fast Light Tool Kit (FLTK). // @@ -618,6 +618,27 @@ extern Fl_Labeltype FL_EXPORT fl_define_FL_EMBOSSED_LABEL(); * inside the widget. * * Flags can be or'd to achieve a combination of alignments. + * + * Outside alignments: + * \code + * TOP_LEFT TOP TOP_RIGHT + * LEFT_TOP+---------------------------------+RIGHT_TOP + * | | + * LEFT| |RIGHT + * | | + * LEFT_BOTTOM+---------------------------------+RIGHT_BOTTOM + * BOTTOM_RIGHT BOTTOM BOTTOM_LEFT + * + * Inside alignments: + * \code + * +---------------------------------+ + * |TOP_LEFT TOP TOP_RIGHT| + * | | + * |LEFT RIGHT| + * | | + * |BOTTOM_RIGHT BOTTOM BOTTOM_LEFT| + * +---------------------------------+ + * \endcode * \see #FL_ALIGN_CENTER, etc. */ typedef unsigned Fl_Align; @@ -637,24 +658,33 @@ const Fl_Align FL_ALIGN_RIGHT = (Fl_Align)8; /** Draw the label inside of the widget. */ const Fl_Align FL_ALIGN_INSIDE = (Fl_Align)16; /** If the label contains an image, draw the text on top of the image. */ -const Fl_Align FL_ALIGN_TEXT_OVER_IMAGE = (Fl_Align)32; +const Fl_Align FL_ALIGN_TEXT_OVER_IMAGE = (Fl_Align)0x0020; /** If the label contains an image, draw the text below the image. */ -const Fl_Align FL_ALIGN_IMAGE_OVER_TEXT = (Fl_Align)0; +const Fl_Align FL_ALIGN_IMAGE_OVER_TEXT = (Fl_Align)0x0000; /** All parts of the label that are lager than the widget will not be drawn . */ const Fl_Align FL_ALIGN_CLIP = (Fl_Align)64; /** Wrap text that does not fit the width of the widget. */ const Fl_Align FL_ALIGN_WRAP = (Fl_Align)128; + /** If the label contains an image, draw the text to the right of the image. */ +const Fl_Align FL_ALIGN_IMAGE_NEXT_TO_TEXT = (Fl_Align)0x0100; + /** If the label contains an image, draw the text to the left of the image. */ +const Fl_Align FL_ALIGN_TEXT_NEXT_TO_IMAGE = (Fl_Align)0x0120; +/** If the label contains an image, draw the image or deimage in the backgroup. */ +const Fl_Align FL_ALIGN_IMAGE_BACKDROP = (Fl_Align)0x0200; const Fl_Align FL_ALIGN_TOP_LEFT = FL_ALIGN_TOP | FL_ALIGN_LEFT; const Fl_Align FL_ALIGN_TOP_RIGHT = FL_ALIGN_TOP | FL_ALIGN_RIGHT; const Fl_Align FL_ALIGN_BOTTOM_LEFT = FL_ALIGN_BOTTOM | FL_ALIGN_LEFT; const Fl_Align FL_ALIGN_BOTTOM_RIGHT = FL_ALIGN_BOTTOM | FL_ALIGN_RIGHT; -const Fl_Align FL_ALIGN_LEFT_TOP = FL_ALIGN_TOP_LEFT; -const Fl_Align FL_ALIGN_RIGHT_TOP = FL_ALIGN_TOP_RIGHT; -const Fl_Align FL_ALIGN_LEFT_BOTTOM = FL_ALIGN_BOTTOM_LEFT; -const Fl_Align FL_ALIGN_RIGHT_BOTTOM = FL_ALIGN_BOTTOM_RIGHT; +const Fl_Align FL_ALIGN_LEFT_TOP = 0x0007; // magic value +const Fl_Align FL_ALIGN_RIGHT_TOP = 0x000b; // magic value +const Fl_Align FL_ALIGN_LEFT_BOTTOM = 0x000d; // magic value +const Fl_Align FL_ALIGN_RIGHT_BOTTOM = 0x000e; // magic value const Fl_Align FL_ALIGN_NOWRAP = (Fl_Align)0; // for back compatability +const Fl_Align FL_ALIGN_POSITION_MASK = 0x000f; // left, right, top, bottom +const Fl_Align FL_ALIGN_IMAGE_MASK = 0x0320; // l/r, t/b, backdrop /*@}*/ + /** \name Font Numbers */ /*@{*/ /** A font number is an index into the internal font table. @@ -886,5 +916,5 @@ enum Fl_Damage { #endif // -// End of "$Id: Enumerations.H 6902 2009-09-27 11:06:56Z matt $". +// End of "$Id: Enumerations.H 7476 2010-04-09 22:18:05Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl.H b/plugins/zynaddsubfx/fltk/FL/Fl.H index 700f51936..6fd660a85 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl.H @@ -1,5 +1,5 @@ // -// "$Id: Fl.H 6903 2009-09-27 11:09:03Z matt $" +// "$Id: Fl.H 7334 2010-03-25 14:37:46Z AlbrechtS $" // // Main header file for the Fast Light Tool Kit (FLTK). // @@ -52,20 +52,59 @@ class Fl_Window; class Fl_Image; struct Fl_Label; + +/** \defgroup callback_functions Callback function typedefs + \brief Typedefs for callback or handler functions passed as function parameters. + + FLTK uses callback functions as parameters for some function calls, e.g. to + set up global event handlers (Fl::add_handler()), to add a timeout handler + (Fl::add_timeout()), and many more. + + The typedefs defined in this group describe the function parameters used to set + up or clear the callback functions and should also be referenced to define the + callback function to handle such events in the user's code. + + \see Fl::add_handler(), Fl::add_timeout(), Fl::repeat_timeout(), + Fl::remove_timeout() and others + @{ */ + /** signature of some label drawing functions passed as parameters */ -typedef void (Fl_Label_Draw_F)(const Fl_Label*, int,int,int,int, Fl_Align); +typedef void (Fl_Label_Draw_F)(const Fl_Label *label, int x, int y, int w, int h, Fl_Align align); /** signature of some label measurement functions passed as parameters */ -typedef void (Fl_Label_Measure_F)(const Fl_Label*, int&, int&); +typedef void (Fl_Label_Measure_F)(const Fl_Label *label, int &width, int &height); /** signature of some box drawing functions passed as parameters */ -typedef void (Fl_Box_Draw_F)(int,int,int,int, Fl_Color); +typedef void (Fl_Box_Draw_F)(int x, int y, int w, int h, Fl_Color color); /** signature of some timeout callback functions passed as parameters */ -typedef void (*Fl_Timeout_Handler)(void*); +typedef void (*Fl_Timeout_Handler)(void *data); /** signature of some wakeup callback functions passed as parameters */ -typedef void (*Fl_Awake_Handler)(void*); +typedef void (*Fl_Awake_Handler)(void *data); + +/** signature of add_idle callback functions passed as parameters */ +typedef void (*Fl_Idle_Handler)(void *data); + +/** signature of set_idle callback functions passed as parameters */ +typedef void (*Fl_Old_Idle_Handler)(); + +/** signature of add_fd functions passed as parameters */ +typedef void (*Fl_FD_Handler)(int fd, void *data); + +/** signature of add_handler functions passed as parameters */ +typedef int (*Fl_Event_Handler)(int event); + +/** signature of set_abort functions passed as parameters */ +typedef void (*Fl_Abort_Handler)(const char *format,...); + +/** signature of set_atclose functions passed as parameters */ +typedef void (*Fl_Atclose_Handler)(Fl_Window *window, void *data); + +/** signature of args functions passed as parameters */ +typedef int (*Fl_Args_Handler)(int argc, char **argv, int &i); + +/** @} */ /* group callback_functions */ /** The Fl is the FLTK global (static) containing @@ -138,7 +177,7 @@ public: // argument parsers: static int arg(int, char**, int&); - static int args(int, char**, int&, int (*)(int,char**,int&) = 0); + static int args(int, char**, int&, Fl_Args_Handler ah = 0); static void args(int, char**); /** Usage string displayed if Fl::args() detects an invalid argument. @@ -232,7 +271,7 @@ public: } \endcode */ - static void repeat_timeout(double t, Fl_Timeout_Handler,void* = 0); // platform dependent + static void repeat_timeout(double t, Fl_Timeout_Handler, void* = 0); // platform dependent static int has_timeout(Fl_Timeout_Handler, void* = 0); static void remove_timeout(Fl_Timeout_Handler, void* = 0); static void add_check(Fl_Timeout_Handler, void* = 0); @@ -257,17 +296,17 @@ public: devices, pipes, sockets, etc.). Due to limitations in Microsoft Windows, WIN32 applications can only monitor sockets. */ - static void add_fd(int fd, int when, void (*cb)(int,void*),void* =0); // platform dependent - /** See void add_fd(int fd, int when, void (*cb)(int,void*),void* =0) */ - static void add_fd(int fd, void (*cb)(int, void*), void* = 0); // platform dependent + static void add_fd(int fd, int when, Fl_FD_Handler cb, void* = 0); // platform dependent + /** See void add_fd(int fd, int when, Fl_FD_Handler cb, void* = 0) */ + static void add_fd(int fd, Fl_FD_Handler cb, void* = 0); // platform dependent /** Removes a file descriptor handler. */ static void remove_fd(int, int when); // platform dependent /** Removes a file descriptor handler. */ static void remove_fd(int); // platform dependent - static void add_idle(void (*cb)(void*), void* data = 0); - static int has_idle(void (*cb)(void*), void* data = 0); - static void remove_idle(void (*cb)(void*), void* data = 0); + static void add_idle(Fl_Idle_Handler cb, void* data = 0); + static int has_idle(Fl_Idle_Handler cb, void* data = 0); + static void remove_idle(Fl_Idle_Handler cb, void* data = 0); /** If true then flush() will do something. */ static int damage() {return damage_;} static void redraw(); @@ -603,8 +642,8 @@ public: /** Gets the current Fl::focus() widget. \sa Fl::focus(Fl_Widget*) */ static Fl_Widget* focus() {return focus_;} static void focus(Fl_Widget*); - static void add_handler(int (*h)(int)); - static void remove_handler(int (*h)(int)); + static void add_handler(Fl_Event_Handler h); + static void remove_handler(Fl_Event_Handler h); /** @} */ /** \defgroup fl_clipboard Selection & Clipboard functions @@ -764,13 +803,13 @@ public: /** \addtogroup fl_windows @{ */ /** For back compatibility, sets the void Fl::fatal handler callback */ - static void set_abort(void (*f)(const char*,...)) {fatal = f;} + static void set_abort(Fl_Abort_Handler f) {fatal = f;} static void (*atclose)(Fl_Window*,void*); static void default_atclose(Fl_Window*,void*); /** For back compatibility, sets the Fl::atclose handler callback. You can now simply change the callback for the window instead. \see Fl_Window::callback(Fl_Callback*) */ - static void set_atclose(void (*f)(Fl_Window*,void*)) {atclose = f;} + static void set_atclose(Fl_Atclose_Handler f) {atclose = f;} /** @} */ /** \addtogroup fl_events @@ -779,6 +818,8 @@ public: static int event_shift() {return e_state&FL_SHIFT;} /** Returns non-zero if the Control key is pressed. */ static int event_ctrl() {return e_state&FL_CTRL;} + /** Returns non-zero if the FL_COMMAND key is pressed, either FL_CTRL or on OSX FL_META. */ + static int event_command() {return e_state&FL_COMMAND;} /** Returns non-zero if the Alt key is pressed. */ static int event_alt() {return e_state&FL_ALT;} /** @@ -812,7 +853,7 @@ public: \deprecated This method is obsolete - use the add_idle() method instead. */ - static void set_idle(void (*cb)()) {idle = cb;} + static void set_idle(Fl_Old_Idle_Handler cb) {idle = cb;} /** See Fl_Window* grab() */ static void grab(Fl_Window&win) {grab(&win);} /** Releases the current grabbed window, equals grab(0). @@ -1042,5 +1083,5 @@ public: #endif // !Fl_H // -// End of "$Id: Fl.H 6903 2009-09-27 11:09:03Z matt $". +// End of "$Id: Fl.H 7334 2010-03-25 14:37:46Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Bitmap.H b/plugins/zynaddsubfx/fltk/FL/Fl_Bitmap.H index 9fec48d76..aeaee42b7 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Bitmap.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Bitmap.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Bitmap.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Bitmap.H 7617 2010-05-27 17:20:18Z manolo $" // // Bitmap header file for the Fast Light Tool Kit (FLTK). // @@ -40,25 +40,34 @@ struct Fl_Menu_Item; (bitmap) images. Images are drawn using the current color. */ class FL_EXPORT Fl_Bitmap : public Fl_Image { - public: + friend class Fl_Quartz_Graphics_Driver; + friend class Fl_GDI_Graphics_Driver; + friend class Fl_Xlib_Graphics_Driver; +public: /** pointer to raw bitmap data */ const uchar *array; /** Non-zero if array points to bitmap data allocated internally */ int alloc_array; + + private: + #if defined(__APPLE__) || defined(WIN32) /** for internal use */ - void *id; + void *id_; #else /** for internal use */ - unsigned id; + unsigned id_; #endif // __APPLE__ || WIN32 + + public: + /** The constructors create a new bitmap from the specified bitmap data */ Fl_Bitmap(const uchar *bits, int W, int H) : - Fl_Image(W,H,0), array(bits), alloc_array(0), id(0) {data((const char **)&array, 1);} + Fl_Image(W,H,0), array(bits), alloc_array(0), id_(0) {data((const char **)&array, 1);} /** The constructors create a new bitmap from the specified bitmap data */ Fl_Bitmap(const char *bits, int W, int H) : - Fl_Image(W,H,0), array((const uchar *)bits), alloc_array(0), id(0) {data((const char **)&array, 1);} + Fl_Image(W,H,0), array((const uchar *)bits), alloc_array(0), id_(0) {data((const char **)&array, 1);} virtual ~Fl_Bitmap(); virtual Fl_Image *copy(int W, int H); Fl_Image *copy() { return copy(w(), h()); } @@ -72,5 +81,5 @@ class FL_EXPORT Fl_Bitmap : public Fl_Image { #endif // -// End of "$Id: Fl_Bitmap.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: Fl_Bitmap.H 7617 2010-05-27 17:20:18Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Button.H b/plugins/zynaddsubfx/fltk/FL/Fl_Button.H index 73d6e4b0d..23547be05 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Button.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Button.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Button.H 6878 2009-09-17 22:12:24Z matt $" +// "$Id: Fl_Button.H 7499 2010-04-14 08:07:53Z manolo $" // // Button header file for the Fast Light Tool Kit (FLTK). // @@ -44,9 +44,7 @@ are set to zero.*/ #define FL_HIDDEN_BUTTON 3 ///< for Forms compatibility -#ifndef FL_DOXYGEN extern FL_EXPORT Fl_Shortcut fl_old_shortcut(const char*); -#endif /** \class Fl_Button @@ -172,5 +170,5 @@ public: #endif // -// End of "$Id: Fl_Button.H 6878 2009-09-17 22:12:24Z matt $". +// End of "$Id: Fl_Button.H 7499 2010-04-14 08:07:53Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Counter.H b/plugins/zynaddsubfx/fltk/FL/Fl_Counter.H index 24930779a..e6f1fad0d 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Counter.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Counter.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Counter.H 6902 2009-09-27 11:06:56Z matt $" +// "$Id: Fl_Counter.H 6939 2009-11-17 14:45:36Z matt $" // // Counter header file for the Fast Light Tool Kit (FLTK). // @@ -98,7 +98,7 @@ public: /** Returns the increment for normal step buttons. */ - double step() {return Fl_Valuator::step();} + double step() const {return Fl_Valuator::step();} /** Gets the text font */ Fl_Font textfont() const {return textfont_;} @@ -120,5 +120,5 @@ public: #endif // -// End of "$Id: Fl_Counter.H 6902 2009-09-27 11:06:56Z matt $". +// End of "$Id: Fl_Counter.H 6939 2009-11-17 14:45:36Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Device.H b/plugins/zynaddsubfx/fltk/FL/Fl_Device.H new file mode 100644 index 000000000..2cb9e66d1 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Device.H @@ -0,0 +1,386 @@ +// +// "$Id: Fl_Device.H 7666 2010-07-04 17:19:38Z AlbrechtS $" +// +// Definition of classes Fl_Device, Fl_Graphics_Driver, Fl_Surface_Device, Fl_Display_Device +// for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +/** \file Fl_Device.H + \brief declaration of classes Fl_Device, Fl_Graphics_Driver, Fl_Surface_Device, Fl_Display_Device. +*/ + +#ifndef Fl_Device_H +#define Fl_Device_H + +#include +#include +#include +#include +#include +#include +#ifdef WIN32 +#include +#elif defined(__APPLE__) +#else +#include +#endif + +class Fl_Graphics_Driver; +class Fl_Display_Device; +class Fl_Surface_Device; +/** \brief Points to the driver that currently receives all graphics requests */ +FL_EXPORT extern Fl_Graphics_Driver *fl_graphics_driver; +/** \brief Points to the surface that currently receives all graphics requests */ +FL_EXPORT extern Fl_Surface_Device *fl_surface; +/** \brief Points to the platform's display */ +FL_EXPORT extern Fl_Display_Device *fl_display_device; + +/** + signature of image generation callback function. + \param[in] data user data passed to function + \param[in] x,y,w position and width of scan line in image + \param[out] buf buffer for generated image data. You must copy \p w + pixels from scanline \p y, starting at pixel \p x + to this buffer. + */ +typedef void (*Fl_Draw_Image_Cb)(void* data,int x,int y,int w,uchar* buf); + +/** + \brief All graphical output devices and all graphics systems. + */ +class Fl_Device { +protected: + /** \brief The device type */ + const char *type_; + /** \brief A string that identifies each subclass of Fl_Device. + * + Function type() applied to a device of this class returns this string. + */ + static const char *device_type; +public: + /** + @brief An RTTI emulation of device classes. + * + The type of an instance of an Fl_Device subclass can be checked with code such as: + \code + if ( instance->type() == Fl_Printer::device_type ) { ... } + \endcode + */ + inline const char *type() {return type_;}; +}; + +/** + \brief A virtual class subclassed for each graphics driver FLTK uses. + * + The protected virtual methods of this class are those that a graphics driver should implement to + support all of FLTK drawing functions. +
The preferred FLTK API for drawing operations is the function collection of the + \ref fl_drawings and \ref fl_attributes modules. +
Alternatively, methods of the Fl_Graphics_Driver class can be called + using the global variable Fl_Graphics_Driver * \ref fl_graphics_driver that points at all time to + the single driver (an instance of an Fl_Graphics_Driver subclass) that's currently receiving graphics + requests. For example: + \code fl_graphics_driver->rect(x, y, w, h); \endcode +
Each protected method of the Fl_Graphics_Driver class has the same effect as the + function of the \ref fl_drawings and \ref fl_attributes modules which bears the same name + prefixed with fl_ and has the same parameter list. + */ +class Fl_Graphics_Driver : public Fl_Device { +protected: +/* ** \brief red color for background and/or mixing if device does not support masking or alpha * + uchar bg_r_; + ** \brief green color for background and/or mixing if device does not support masking or alpha * + uchar bg_g_; + ** \brief blue color for background and/or mixing if device does not support masking or alpha * + uchar bg_b_; */ + friend class Fl_Pixmap; + friend class Fl_Bitmap; + friend class Fl_RGB_Image; + friend class Fl_PostScript_Graphics_Driver; + friend void fl_rect(int x, int y, int w, int h); + friend void fl_rectf(int x, int y, int w, int h); + friend void fl_line_style(int style, int width, char* dashes); + friend void fl_xyline(int x, int y, int x1); + friend void fl_xyline(int x, int y, int x1, int y2); + friend void fl_xyline(int x, int y, int x1, int y2, int x3); + friend void fl_yxline(int x, int y, int y1); + friend void fl_yxline(int x, int y, int y1, int x2); + friend void fl_yxline(int x, int y, int y1, int x2, int y3); + friend void fl_line(int x, int y, int x1, int y1); + friend void fl_line(int x, int y, int x1, int y1, int x2, int y2); + friend void fl_draw(const char *str, int n, int x, int y); +#ifdef __APPLE__ + friend void fl_draw(const char *str, int n, float x, float y); +#endif + friend void fl_draw(int angle, const char *str, int n, int x, int y); + friend void fl_rtl_draw(const char *str, int n, int x, int y); + friend void fl_font(Fl_Font face, Fl_Fontsize size); + friend void fl_color(Fl_Color c); + friend void fl_color(uchar r, uchar g, uchar b); + friend void fl_point(int x, int y); + friend void fl_loop(int x0, int y0, int x1, int y1, int x2, int y2); + friend void fl_loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3); + friend void fl_polygon(int x0, int y0, int x1, int y1, int x2, int y2); + friend void fl_polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3); + friend void fl_begin_points(); + friend void fl_begin_line(); + friend void fl_begin_loop(); + friend void fl_begin_polygon(); + friend void fl_vertex(double x, double y); + friend void fl_curve(double X0, double Y0, double X1, double Y1, double X2, double Y2, double X3, double Y3); + friend void fl_circle(double x, double y, double r); + friend void fl_arc(double x, double y, double r, double start, double end); + friend void fl_arc(int x, int y, int w, int h, double a1, double a2); + friend void fl_pie(int x, int y, int w, int h, double a1, double a2); + friend void fl_end_points(); + friend void fl_end_line(); + friend void fl_end_loop(); + friend void fl_end_polygon(); + friend void fl_transformed_vertex(double xf, double yf); + friend void fl_push_clip(int x, int y, int w, int h); + friend int fl_clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H); + friend int fl_not_clipped(int x, int y, int w, int h); + friend void fl_push_no_clip(); + friend void fl_pop_clip(); + friend void fl_begin_complex_polygon(); + friend void fl_gap(); + friend void fl_end_complex_polygon(); + friend void fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int D, int L); + friend void fl_draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D, int L); + friend void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D); + friend FL_EXPORT void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D); + + /** \brief The constructor. */ + Fl_Graphics_Driver() {}; + /** \brief see fl_rect(int x, int y, int w, int h). */ + virtual void rect(int x, int y, int w, int h); + /** \brief see fl_rectf(int x, int y, int w, int h). */ + virtual void rectf(int x, int y, int w, int h); + /** \brief see fl_line_style(int style, int width, char* dashes). */ + virtual void line_style(int style, int width=0, char* dashes=0); + /** \brief see fl_xyline(int x, int y, int x1). */ + virtual void xyline(int x, int y, int x1); + /** \brief see fl_xyline(int x, int y, int x1, int y2). */ + virtual void xyline(int x, int y, int x1, int y2); + /** \brief see fl_xyline(int x, int y, int x1, int y2, int x3). */ + virtual void xyline(int x, int y, int x1, int y2, int x3); + /** \brief see fl_yxline(int x, int y, int y1). */ + virtual void yxline(int x, int y, int y1); + /** \brief see fl_yxline(int x, int y, int y1, int x2). */ + virtual void yxline(int x, int y, int y1, int x2); + /** \brief see fl_yxline(int x, int y, int y1, int x2, int y3). */ + virtual void yxline(int x, int y, int y1, int x2, int y3); + /** \brief see fl_line(int x, int y, int x1, int y1). */ + virtual void line(int x, int y, int x1, int y1); + /** \brief see fl_line(int x, int y, int x1, int y1, int x2, int y2). */ + virtual void line(int x, int y, int x1, int y1, int x2, int y2); + /** \brief see fl_draw(const char *str, int n, int x, int y). */ + virtual void draw(const char *str, int n, int x, int y); + /** \brief see fl_draw(int angle, const char *str, int n, int x, int y). */ + virtual void draw(int angle, const char *str, int n, int x, int y); + /** \brief see fl_rtl_draw(const char *str, int n, int x, int y). */ + virtual void rtl_draw(const char *str, int n, int x, int y); + /** \brief see fl_font(Fl_Font face, Fl_Fontsize size). */ + virtual void font(Fl_Font face, Fl_Fontsize size); + /** \brief see fl_color(Fl_Color c). */ + virtual void color(Fl_Color c); + /** \brief see fl_color(uchar r, uchar g, uchar b). */ + virtual void color(uchar r, uchar g, uchar b); + /** \brief see fl_point(int x, int y). */ + virtual void point(int x, int y); + /** \brief see fl_loop(int x0, int y0, int x1, int y1, int x2, int y2). */ + virtual void loop(int x0, int y0, int x1, int y1, int x2, int y2); + /** \brief see fl_loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3). */ + virtual void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3); + /** \brief see fl_polygon(int x0, int y0, int x1, int y1, int x2, int y2). */ + virtual void polygon(int x0, int y0, int x1, int y1, int x2, int y2); + /** \brief see fl_polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3). */ + virtual void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3); + /** \brief see fl_begin_points(). */ + virtual void begin_points(); + /** \brief see fl_begin_line(). */ + virtual void begin_line(); + /** \brief see fl_begin_loop(). */ + virtual void begin_loop(); + /** \brief see fl_begin_polygon(). */ + virtual void begin_polygon(); + /** \brief see fl_vertex(double x, double y). */ + virtual void vertex(double x, double y); + /** \brief see fl_curve(double X0, double Y0, double X1, double Y1, double X2, double Y2, double X3, double Y3). */ + virtual void curve(double X0, double Y0, double X1, double Y1, double X2, double Y2, double X3, double Y3); + /** \brief see fl_circle(double x, double y, double r). */ + virtual void circle(double x, double y, double r); + /** \brief see fl_arc(double x, double y, double r, double start, double end). */ + virtual void arc(double x, double y, double r, double start, double end); + /** \brief see fl_arc(int x, int y, int w, int h, double a1, double a2). */ + virtual void arc(int x, int y, int w, int h, double a1, double a2); + /** \brief see fl_pie(int x, int y, int w, int h, double a1, double a2). */ + virtual void pie(int x, int y, int w, int h, double a1, double a2); + /** \brief see fl_end_points(). */ + virtual void end_points(); + /** \brief see fl_end_line(). */ + virtual void end_line(); + /** \brief see fl_end_loop(). */ + virtual void end_loop(); + /** \brief see fl_end_polygon(). */ + virtual void end_polygon(); + /** \brief see fl_begin_complex_polygon(). */ + virtual void begin_complex_polygon(); + /** \brief see fl_gap(). */ + virtual void gap(); + /** \brief see fl_end_complex_polygon(). */ + virtual void end_complex_polygon(); + /** \brief see fl_transformed_vertex(double xf, double yf). */ + virtual void transformed_vertex(double xf, double yf); + /** \brief see fl_push_clip(int x, int y, int w, int h). */ + virtual void push_clip(int x, int y, int w, int h); + /** \brief see fl_clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H). */ + virtual int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H); + /** \brief see fl_not_clipped(int x, int y, int w, int h). */ + virtual int not_clipped(int x, int y, int w, int h); + /** \brief see fl_push_no_clip(). */ + virtual void push_no_clip(); + /** \brief see fl_pop_clip(). */ + virtual void pop_clip(); + // Images + /** \brief see fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int D, int L). */ + virtual void draw_image(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0); + /** \brief see fl_draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D, int L). */ + virtual void draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0); + /** \brief see fl_draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D). */ + virtual void draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3); + /** \brief see fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D). */ + virtual void draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1); + // Image classes + /** \brief Draws an Fl_RGB_Image object to the device. + * + Specifies a bounding box for the image, with the origin (upper left-hand corner) of + the image offset by the cx and cy arguments. + */ + virtual void draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy) {}; + /** \brief Draws an Fl_Pixmap object to the device. + * + Specifies a bounding box for the image, with the origin (upper left-hand corner) of + the image offset by the cx and cy arguments. + */ + virtual void draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy) {}; + /** \brief Draws an Fl_Bitmap object to the device. + * + Specifies a bounding box for the image, with the origin (upper left-hand corner) of + the image offset by the cx and cy arguments. + */ + virtual void draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {}; + +public: + static const char *device_type; + /** \brief The destructor */ + virtual ~Fl_Graphics_Driver() {}; +}; + +#if defined(__APPLE__) || defined(FL_DOXYGEN) +/** + \brief The Mac OS X-specific graphics class. + * + This class is implemented only on the Mac OS X platform. + */ +class Fl_Quartz_Graphics_Driver : public Fl_Graphics_Driver { +public: + Fl_Quartz_Graphics_Driver() { type_ = device_type; }; + static const char *device_type; + void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy); + void draw(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy); + void draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy); +}; +#endif +#if defined(WIN32) || defined(FL_DOXYGEN) +/** + \brief The MSWindows-specific graphics class. + * + This class is implemented only on the MSWindows platform. + */ +class Fl_GDI_Graphics_Driver : public Fl_Graphics_Driver { +public: + Fl_GDI_Graphics_Driver() { type_ = device_type; }; + static const char *device_type; + void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy); + void draw(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy); + void draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy); +}; +#endif +#if !(defined(__APPLE__) || defined(WIN32)) +/** + \brief The Xlib-specific graphics class. + * + This class is implemented only on the Xlib platform. + */ +class Fl_Xlib_Graphics_Driver : public Fl_Graphics_Driver { +public: + Fl_Xlib_Graphics_Driver() { type_ = device_type; }; + static const char *device_type; + void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy); + void draw(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy); + void draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy); +}; +#endif + +/** + \brief A surface that's susceptible to receive graphical output. + */ +class Fl_Surface_Device : public Fl_Device { + /** \brief The graphics driver in use by this surface. */ + Fl_Graphics_Driver *_driver; +protected: + /** \brief Constructor that sets the graphics driver to use for the created surface. */ + Fl_Surface_Device(Fl_Graphics_Driver *graphics_driver) {_driver = graphics_driver; }; +public: + static const char *device_type; + virtual void set_current(void); + /** \brief Sets the graphics driver of this drawing surface. */ + inline void driver(Fl_Graphics_Driver *graphics_driver) {_driver = graphics_driver;}; + /** \brief Returns the graphics driver of this drawing surface. */ + inline Fl_Graphics_Driver *driver() {return _driver; }; + /** \brief the surface that currently receives graphics output */ + static Fl_Surface_Device *surface() {return fl_surface; }; + /** \brief The destructor. */ + virtual ~Fl_Surface_Device() {} +}; + +/** + \brief A display to which the computer can draw. + */ +class Fl_Display_Device : public Fl_Surface_Device { +public: + static const char *device_type; + /** \brief A constructor that sets the graphics driver used by the display */ + Fl_Display_Device(Fl_Graphics_Driver *graphics_driver) : Fl_Surface_Device( graphics_driver) { type_ = device_type; }; + /** + @brief Returns the platform's display device. + */ + static Fl_Display_Device *display_device() { return fl_display_device; }; +}; + +#endif // Fl_Device_H + +// +// End of "$Id: Fl_Device.H 7666 2010-07-04 17:19:38Z AlbrechtS $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_File_Chooser.H b/plugins/zynaddsubfx/fltk/FL/Fl_File_Chooser.H index 95145a106..92471beec 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_File_Chooser.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_File_Chooser.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_File_Chooser.H 6678 2009-03-13 23:36:09Z AlbrechtS $" +// "$Id: Fl_File_Chooser.H 7007 2010-01-14 23:08:06Z greg.ercolano $" // // Fl_File_Chooser dialog for the Fast Light Tool Kit (FLTK). // @@ -222,6 +222,7 @@ private: Fl_Widget* ext_group; public: Fl_Widget* add_extra(Fl_Widget* gr); + Fl_File_Browser *browser(void) {return fileList; }; }; FL_EXPORT char *fl_dir_chooser(const char *message,const char *fname,int relative=0); FL_EXPORT char *fl_file_chooser(const char *message,const char *pat,const char *fname,int relative=0); @@ -230,5 +231,5 @@ FL_EXPORT void fl_file_chooser_ok_label(const char*l); #endif // -// End of "$Id: Fl_File_Chooser.H 6678 2009-03-13 23:36:09Z AlbrechtS $". +// End of "$Id: Fl_File_Chooser.H 7007 2010-01-14 23:08:06Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Group.H b/plugins/zynaddsubfx/fltk/FL/Fl_Group.H index 5ba61ad25..2c6e6f946 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Group.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Group.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Group.H 6907 2009-09-28 14:34:52Z matt $" +// "$Id: Fl_Group.H 7280 2010-03-16 22:51:31Z matt $" // // Group header file for the Fast Light Tool Kit (FLTK). // @@ -176,6 +176,14 @@ public: */ unsigned int clip_children() { return (flags() & CLIP_CHILDREN) != 0; } + /** Returns an Fl_Group pointer if this widget is an Fl_Group. + + \retval NULL if this widget is not derived from Fl_Group. + \note This method is provided to avoid dynamic_cast. + \todo More documentation ... + */ + virtual Fl_Group* as_group() { return this; } + // back compatibility functions: /** @@ -222,5 +230,5 @@ public: #endif // -// End of "$Id: Fl_Group.H 6907 2009-09-28 14:34:52Z matt $". +// End of "$Id: Fl_Group.H 7280 2010-03-16 22:51:31Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Help_View.H b/plugins/zynaddsubfx/fltk/FL/Fl_Help_View.H index eedb150fd..f30dc6b44 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Help_View.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Help_View.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Help_View.H 6743 2009-04-07 17:33:22Z AlbrechtS $" +// "$Id: Fl_Help_View.H 7139 2010-02-23 15:55:22Z greg.ercolano $" // // Help Viewer widget definitions. // @@ -147,6 +147,66 @@ struct Fl_Help_Target The Fl_Help_View widget displays HTML text. Most HTML 2.0 elements are supported, as well as a primitive implementation of tables. GIF, JPEG, and PNG images are displayed inline. + + Supported HTML tags: + - A: HREF/NAME + - B + - BODY: BGCOLOR/TEXT/LINK + - BR + - CENTER + - CODE + - DD + - DL + - DT + - EM + - FONT: COLOR/SIZE/FACE=(helvetica/arial/sans/times/serif/symbol/courier) + - H1/H2/H3/H4/H5/H6 + - HEAD + - HR + - I + - IMG: SRC/WIDTH/HEIGHT/ALT + - KBD + - LI + - OL + - P + - PRE + - STRONG + - TABLE: TH/TD/TR/BORDER/BGCOLOR/COLSPAN/ALIGN=CENTER|RIGHT|LEFT + - TITLE + - TT + - U + - UL + - VAR + + Supported color names: + - black,red,green,yellow,blue,magenta,fuchsia,cyan,aqua,white,gray,grey,lime,maroon,navy,olive,purple,silver,teal. + + Supported urls: + - Internal: file: + - External: http: ftp: https: ipp: mailto: news: + + Quoted char names: + - Aacute aacute Acirc acirc acute AElig aelig Agrave agrave amp Aring aring Atilde atilde Auml auml + - brvbar bull + - Ccedil ccedil cedil cent copy curren + - deg divide + - Eacute eacute Ecirc ecirc Egrave egrave ETH eth Euml euml euro + - frac12 frac14 frac34 + - gt + - Iacute iacute Icirc icirc iexcl Igrave igrave iquest Iuml iuml + - laquo lt + - macr micro middot + - nbsp not Ntilde ntilde + - Oacute oacute Ocirc ocirc Ograve ograve ordf ordm Oslash oslash Otilde otilde Ouml ouml + - para premil plusmn pound + - quot + - raquo reg + - sect shy sup1 sup2 sup3 szlig + - THORN thorn times trade + - Uacute uacute Ucirc ucirc Ugrave ugrave uml Uuml uuml + - Yacute yacute + - yen Yuml yuml + */ class FL_EXPORT Fl_Help_View : public Fl_Group // Help viewer widget { @@ -334,5 +394,5 @@ public: #endif // !Fl_Help_View_H // -// End of "$Id: Fl_Help_View.H 6743 2009-04-07 17:33:22Z AlbrechtS $". +// End of "$Id: Fl_Help_View.H 7139 2010-02-23 15:55:22Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Image.H b/plugins/zynaddsubfx/fltk/FL/Fl_Image.H index 7d0aa9495..278d70d7d 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Image.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Image.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Image.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Image.H 7617 2010-05-27 17:20:18Z manolo $" // // Image header file for the Fast Light Tool Kit (FLTK). // @@ -188,21 +188,29 @@ class FL_EXPORT Fl_Image { <FL/Fl_RGB_Image.H> should be included. */ class FL_EXPORT Fl_RGB_Image : public Fl_Image { - public: + friend class Fl_Quartz_Graphics_Driver; + friend class Fl_GDI_Graphics_Driver; + friend class Fl_Xlib_Graphics_Driver; +public: const uchar *array; int alloc_array; // Non-zero if array was allocated + private: + #if defined(__APPLE__) || defined(WIN32) - void *id; // for internal use - void *mask; // for internal use (mask bitmap) + void *id_; // for internal use + void *mask_; // for internal use (mask bitmap) #else - unsigned id; // for internal use - unsigned mask; // for internal use (mask bitmap) + unsigned id_; // for internal use + unsigned mask_; // for internal use (mask bitmap) #endif // __APPLE__ || WIN32 + + public: + /** The constructor creates a new image from the specified data. */ Fl_RGB_Image(const uchar *bits, int W, int H, int D=3, int LD=0) : - Fl_Image(W,H,D), array(bits), alloc_array(0), id(0), mask(0) {data((const char **)&array, 1); ld(LD);} + Fl_Image(W,H,D), array(bits), alloc_array(0), id_(0), mask_(0) {data((const char **)&array, 1); ld(LD);} virtual ~Fl_RGB_Image(); virtual Fl_Image *copy(int W, int H); Fl_Image *copy() { return copy(w(), h()); } @@ -218,5 +226,5 @@ class FL_EXPORT Fl_RGB_Image : public Fl_Image { #endif // !Fl_Image_H // -// End of "$Id: Fl_Image.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: Fl_Image.H 7617 2010-05-27 17:20:18Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Input_.H b/plugins/zynaddsubfx/fltk/FL/Fl_Input_.H index 26dab7d1a..dc14ab17f 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Input_.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Input_.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Input_.H 6902 2009-09-27 11:06:56Z matt $" +// "$Id: Fl_Input_.H 7672 2010-07-10 09:44:45Z matt $" // // Input base class header file for the Fast Light Tool Kit (FLTK). // @@ -151,7 +151,7 @@ class FL_EXPORT Fl_Input_ : public Fl_Widget { /** \internal Horizontal cursor position in pixels while movin up or down. */ static double up_down_pos; - /** \internal Flag to remeber last cursor move. */ + /** \internal Flag to remember last cursor move. */ static int was_up_down; /* Convert a given text segment into the text that will be rendered on screen. */ @@ -451,5 +451,5 @@ public: #endif // -// End of "$Id: Fl_Input_.H 6902 2009-09-27 11:06:56Z matt $". +// End of "$Id: Fl_Input_.H 7672 2010-07-10 09:44:45Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Input_Choice.H b/plugins/zynaddsubfx/fltk/FL/Fl_Input_Choice.H index 26345a44e..b0fbe1f27 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Input_Choice.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Input_Choice.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Input_Choice.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Input_Choice.H 7115 2010-02-20 17:40:07Z AlbrechtS $" // // An input/chooser widget. // ______________ ____ @@ -76,6 +76,7 @@ class Fl_Input_Choice : public Fl_Group { static void menu_cb(Fl_Widget*, void *data) { Fl_Input_Choice *o=(Fl_Input_Choice *)data; + Fl_Widget_Tracker wp(o); const Fl_Menu_Item *item = o->menubutton()->mvalue(); if (item && item->flags & (FL_SUBMENU|FL_SUBMENU_POINTER)) return; // ignore submenus if (!strcmp(o->inp_->value(), o->menu_->text())) @@ -92,6 +93,8 @@ class Fl_Input_Choice : public Fl_Group { if (o->when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE)) o->do_callback(); } + + if (wp.deleted()) return; if (o->callback() != default_callback) { @@ -102,6 +105,7 @@ class Fl_Input_Choice : public Fl_Group { static void inp_cb(Fl_Widget*, void *data) { Fl_Input_Choice *o=(Fl_Input_Choice *)data; + Fl_Widget_Tracker wp(o); if (o->inp_->changed()) { o->Fl_Widget::set_changed(); if (o->when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE)) @@ -111,6 +115,8 @@ class Fl_Input_Choice : public Fl_Group { if (o->when() & FL_WHEN_NOT_CHANGED) o->do_callback(); } + + if (wp.deleted()) return; if (o->callback() != default_callback) o->Fl_Widget::clear_changed(); @@ -212,5 +218,5 @@ public: #endif // !Fl_Input_Choice_H // -// End of "$Id: Fl_Input_Choice.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: Fl_Input_Choice.H 7115 2010-02-20 17:40:07Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Menu_.H b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_.H index 89ced65f6..9f4319ef2 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Menu_.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Menu_.H 6902 2009-09-27 11:06:56Z matt $" +// "$Id: Fl_Menu_.H 7517 2010-04-16 17:55:45Z greg.ercolano $" // // Menu base class header file for the Fast Light Tool Kit (FLTK). // @@ -52,7 +52,7 @@ class FL_EXPORT Fl_Menu_ : public Fl_Widget { protected: - uchar alloc; + uchar alloc; // flag indicates if menu_ is a dynamic copy (=1) or not (=0) uchar down_box_; Fl_Font textfont_; Fl_Fontsize textsize_; @@ -65,6 +65,10 @@ public: int item_pathname(char *name, int namelen, const Fl_Menu_Item *finditem=0) const; const Fl_Menu_Item* picked(const Fl_Menu_Item*); const Fl_Menu_Item* find_item(const char *name); + const Fl_Menu_Item* find_item(Fl_Callback*); + int find_index(const char *name) const; + int find_index(const Fl_Menu_Item *item) const; + int find_index(Fl_Callback *cb) const; const Fl_Menu_Item* test_shortcut() {return picked(menu()->test_shortcut());} void global(); @@ -76,14 +80,21 @@ public: const Fl_Menu_Item *menu() const {return menu_;} void menu(const Fl_Menu_Item *m); void copy(const Fl_Menu_Item *m, void* user_data = 0); + int insert(int index, const char*, int shortcut, Fl_Callback*, void* = 0, int = 0); int add(const char*, int shortcut, Fl_Callback*, void* = 0, int = 0); - /** See int Fl_Menu_::add(const char* label, int shortcut, Fl_Callback*, void *user_data=0, int flags=0)*/ + /** See int Fl_Menu_::add(const char* label, int shortcut, Fl_Callback*, void *user_data=0, int flags=0) */ int add(const char* a, const char* b, Fl_Callback* c, void* d = 0, int e = 0) { - return add(a,fl_old_shortcut(b),c,d,e);} + return add(a,fl_old_shortcut(b),c,d,e); + } + /** See int Fl_Menu_::insert(const char* label, int shortcut, Fl_Callback*, void *user_data=0, int flags=0) */ + int insert(int index, const char* a, const char* b, Fl_Callback* c, void* d = 0, int e = 0) { + return insert(index,a,fl_old_shortcut(b),c,d,e); + } int add(const char *); int size() const ; void size(int W, int H) { Fl_Widget::size(W, H); } void clear(); + int clear_submenu(int index); void replace(int,const char *); void remove(int); /** Changes the shortcut of item i to n. */ @@ -142,5 +153,5 @@ public: #endif // -// End of "$Id: Fl_Menu_.H 6902 2009-09-27 11:06:56Z matt $". +// End of "$Id: Fl_Menu_.H 7517 2010-04-16 17:55:45Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Item.H b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Item.H index 2e1426933..25b46732e 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Item.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Item.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Menu_Item.H 6902 2009-09-27 11:06:56Z matt $" +// "$Id: Fl_Menu_Item.H 7517 2010-04-16 17:55:45Z greg.ercolano $" // // Menu item header file for the Fast Light Tool Kit (FLTK). // @@ -386,6 +386,7 @@ struct FL_EXPORT Fl_Menu_Item { /** back compatibility only \deprecated. */ void uncheck() {flags &= ~FL_MENU_VALUE;} + int insert(int,const char*,int,Fl_Callback*,void* =0, int =0); int add(const char*, int shortcut, Fl_Callback*, void* =0, int = 0); /** See int add(const char*, int shortcut, Fl_Callback*, void*, int) */ @@ -414,5 +415,5 @@ enum { // back-compatibility enum: #endif // -// End of "$Id: Fl_Menu_Item.H 6902 2009-09-27 11:06:56Z matt $". +// End of "$Id: Fl_Menu_Item.H 7517 2010-04-16 17:55:45Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Native_File_Chooser.H b/plugins/zynaddsubfx/fltk/FL/Fl_Native_File_Chooser.H new file mode 100644 index 000000000..dac6807a7 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Native_File_Chooser.H @@ -0,0 +1,51 @@ +// +// "$Id: Fl_Native_File_Chooser.H 7003 2010-01-14 20:47:59Z greg.ercolano $" +// +// FLTK native OS file chooser widget +// +// Copyright 1998-2009 by Bill Spitzak and others. +// Copyright 2004 Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef FL_NATIVE_FILE_CHOOSER_H +#define FL_NATIVE_FILE_CHOOSER_H + +// Use Windows' chooser +#ifdef WIN32 +#include +#endif + +// Use Apple's chooser +#ifdef __APPLE__ +#include +#endif + +// All else falls back to FLTK's own chooser +#if ! defined(__APPLE__) && !defined(WIN32) +#include +#endif + +#endif /*FL_NATIVE_FILE_CHOOSER_H*/ + +// +// End of "$Id: Fl_Native_File_Chooser.H 7003 2010-01-14 20:47:59Z greg.ercolano $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Native_File_Chooser_FLTK.H b/plugins/zynaddsubfx/fltk/FL/Fl_Native_File_Chooser_FLTK.H new file mode 100644 index 000000000..8f1ae263e --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Native_File_Chooser_FLTK.H @@ -0,0 +1,142 @@ +// +// "$Id: Fl_Native_File_Chooser_FLTK.H 7007 2010-01-14 23:08:06Z greg.ercolano $" +// +// FLTK native OS file chooser widget +// +// Copyright 1998-2009 by Bill Spitzak and others. +// Copyright 2005 by Nathan Vander Wilt. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Native_File_Chooser widget. */ + +#include +#include // _POSIX_NAME_MAX + +/** + This class lets an FLTK application easily and consistently access + the operating system's native file chooser. Some operating systems + have very complex and specific file choosers that many users want + access to specifically, instead of FLTK's default file chooser(s). +

+ In cases where there is no native file browser, FLTK's own file browser + is used instead. +

+ \code + // Create and post the local native file chooser + #include + [..] + Fl_Native_File_Chooser fnfc; + fnfc.title("Pick a file"); + fnfc.type(Fl_Native_File_Chooser::BROWSE_FILE); + fnfc.filter("Text\t*.txt\n" + "C Files\t*.{cxx,h,c}"); + fnfc.directory("/var/tmp"); + // Show native chooser + switch ( fnfc.show() ) { + case -1: printf("ERROR: %s\n", fnfc.errmsg()); break; // ERROR + case 1: printf("CANCEL\n"); break; // CANCEL + default: printf("PICKED: %s\n", fnfc.filename()); break; // FILE CHOSEN + } + \endcode +

+ Platform Specific Caveats +

+ - Under X windows, it's best if you call Fl_File_Icon::load_system_icons() + at the start of main(), to enable the nicer looking file browser widgets. + - Some operating systems support certain OS specific options; see + Fl_Native_File_Chooser::options() for a list. +*/ +class Fl_Native_File_Chooser { +public: + enum Type { + BROWSE_FILE = 0, ///< browse files (lets user choose one file) + BROWSE_DIRECTORY, ///< browse directories (lets user choose one directory) + BROWSE_MULTI_FILE, ///< browse files (lets user choose multiple files) + BROWSE_MULTI_DIRECTORY, ///< browse directories (lets user choose multiple directories) + BROWSE_SAVE_FILE, ///< browse to save a file + BROWSE_SAVE_DIRECTORY ///< browse to save a directory + }; + enum Option { + NO_OPTIONS = 0x0000, ///< no options enabled + SAVEAS_CONFIRM = 0x0001, ///< Show native 'Save As' overwrite confirm dialog (if supported) + NEW_FOLDER = 0x0002, ///< Show 'New Folder' icon (if supported) + PREVIEW = 0x0004, ///< enable preview mode + }; +private: + int _btype; // kind-of browser to show() + int _options; // general options + int _nfilters; + char *_filter; // user supplied filter + char *_parsedfilt; // parsed filter + int _filtvalue; // selected filter + char *_preset_file; + char *_prevvalue; // Returned filename + char *_directory; + char *_errmsg; // error message + char *_old_dir; + Fl_File_Chooser *_file_chooser; + + // added by MG + Fl_File_Browser *my_fileList; + Fl_Check_Button *show_hidden; + int prev_filtervalue; + static void show_hidden_cb(Fl_Check_Button *o, void *data); + static void remove_hidden_files(Fl_File_Browser *my_fileList); + + // Private methods + void errmsg(const char *msg); + int type_fl_file(int); + void parse_filter(); + void keeplocation(); + int exist_dialog(); + +public: + Fl_Native_File_Chooser(int val=BROWSE_FILE); + ~Fl_Native_File_Chooser(); + + // Public methods + void type(int); + int type() const; + void options(int); + int options() const; + int count() const; + const char *filename() const; + const char *filename(int i) const; + void directory(const char *val); + const char *directory() const; + void title(const char *); + const char* title() const; + const char *filter() const; + void filter(const char *); + int filters() const; + void filter_value(int i); + int filter_value() const; + void preset_file(const char*); + const char* preset_file() const; + const char *errmsg() const; + int show(); +}; + +// +// End of "$Id: Fl_Native_File_Chooser_FLTK.H 7007 2010-01-14 23:08:06Z greg.ercolano $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Native_File_Chooser_MAC.H b/plugins/zynaddsubfx/fltk/FL/Fl_Native_File_Chooser_MAC.H new file mode 100644 index 000000000..d9668cfc6 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Native_File_Chooser_MAC.H @@ -0,0 +1,122 @@ +// +// "$Id: Fl_Native_File_Chooser_MAC.H 7354 2010-03-29 11:07:29Z matt $" +// +// FLTK native OS file chooser widget +// +// Copyright 1998-2009 by Bill Spitzak and others. +// Copyright 2004 Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef FL_DOXYGEN // PREVENT DOXYGEN'S USE OF THIS FILE + +// OSX-SPECIFIC NATIVE BROWSER +#include +#include + +#undef check // necessary for use of Fl::check() + +#include +#define MAXFILTERS 80 + +class Fl_Native_File_Chooser { +public: + enum Type { + BROWSE_FILE = 0, + BROWSE_DIRECTORY, + BROWSE_MULTI_FILE, + BROWSE_MULTI_DIRECTORY, + BROWSE_SAVE_FILE, + BROWSE_SAVE_DIRECTORY + }; + enum Option { + NO_OPTIONS = 0x0000, // no options enabled + SAVEAS_CONFIRM = 0x0001, // Show native 'Save As' overwrite confirm dialog (if supported) + NEW_FOLDER = 0x0002, // Show 'New Folder' icon (if supported) + PREVIEW = 0x0004, // enable preview mode + }; +private: + int _btype; // kind-of browser to show() + int _options; // general options + void *_panel; + char **_pathnames; // array of pathnames + int _tpathnames; // total pathnames + char *_directory; // default pathname to use + char *_title; // title for window + char *_preset_file; // the 'save as' filename + + char *_filter; // user-side search filter, eg: + // C Files\t*.[ch]\nText Files\t*.txt" + + char *_filt_names; // filter names (tab delimited) + // eg. "C Files\tText Files" + + char *_filt_patt[MAXFILTERS]; + // array of filter patterns, eg: + // _filt_patt[0]="*.{cxx,h}" + // _filt_patt[1]="*.txt" + + int _filt_total; // parse_filter() # of filters loaded + int _filt_value; // index of the selected filter + char *_errmsg; // error message + + // Private methods + void errmsg(const char *msg); + void clear_pathnames(); + void set_single_pathname(const char *s); + int get_saveas_basename(void); + void clear_filters(); + void add_filter(const char *, const char *); + void parse_filter(const char *from); + int post(); + +public: + Fl_Native_File_Chooser(int val = BROWSE_FILE); + ~Fl_Native_File_Chooser(); + + // Public methods + void type(int); + int type() const; + void options(int); + int options() const; + int count() const; + const char *filename() const; + const char *filename(int i) const; + void directory(const char *); + const char *directory() const; + void title(const char *); + const char *title() const; + const char *filter() const; + void filter(const char *); + void filter_value(int i) { _filt_value = i; } + int filter_value() { return(_filt_value); } + int filters() { return(_filt_total); } + void preset_file(const char *); + const char *preset_file(); + const char *errmsg() const; + int show(); +}; + +#endif /*!FL_DOXYGEN*/ + +// +// End of "$Id: Fl_Native_File_Chooser_MAC.H 7354 2010-03-29 11:07:29Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Native_File_Chooser_WIN32.H b/plugins/zynaddsubfx/fltk/FL/Fl_Native_File_Chooser_WIN32.H new file mode 100644 index 000000000..d6aa53a69 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Native_File_Chooser_WIN32.H @@ -0,0 +1,120 @@ +// +// "$Id: Fl_Native_File_Chooser_WIN32.H 7003 2010-01-14 20:47:59Z greg.ercolano $" +// +// FLTK native OS file chooser widget +// +// Copyright 1998-2005 by Bill Spitzak and others. +// Copyright 2004 by Greg Ercolano. +// April 2005 - API changes, improved filter processing by Nathan Vander Wilt +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +#ifndef FL_DOXYGEN // PREVENT DOXYGEN'S USE OF THIS FILE + +// #define _WIN32_WINNT 0x0501 // needed for OPENFILENAME's 'FlagsEx' +#include +#include // malloc +#include +#include // OPENFILENAME, GetOpenFileName() +#include // BROWSEINFO, SHBrowseForFolder() + +class Fl_Native_File_Chooser { +public: + enum Type { + BROWSE_FILE = 0, + BROWSE_DIRECTORY, + BROWSE_MULTI_FILE, + BROWSE_MULTI_DIRECTORY, + BROWSE_SAVE_FILE, + BROWSE_SAVE_DIRECTORY + }; + enum Option { + NO_OPTIONS = 0x0000, // no options enabled + SAVEAS_CONFIRM = 0x0001, // Show native 'Save As' overwrite confirm dialog (if supported) + NEW_FOLDER = 0x0002, // Show 'New Folder' icon (if supported) + PREVIEW = 0x0004, // enable preview mode + }; +private: + int _btype; // kind-of browser to show() + int _options; // general options + OPENFILENAMEW _ofn; // GetOpenFileName() & GetSaveFileName() struct + BROWSEINFO _binf; // SHBrowseForFolder() struct + char **_pathnames; // array of pathnames + int _tpathnames; // total pathnames + char *_directory; // default pathname to use + char *_title; // title for window + char *_filter; // user-side search filter + char *_parsedfilt; // filter parsed for Windows dialog + int _nfilters; // number of filters parse_filter counted + char *_preset_file; // the file to preselect + char *_errmsg; // error message + + // Private methods + void errmsg(const char *msg); + + void clear_pathnames(); + void set_single_pathname(const char *s); + void add_pathname(const char *s); + + void FreePIDL(ITEMIDLIST *pidl); + void ClearOFN(); + void ClearBINF(); + void Win2Unix(char *s); + void Unix2Win(char *s); + int showfile(); + static int CALLBACK Dir_CB(HWND win, UINT msg, LPARAM param, LPARAM data); + int showdir(); + + void parse_filter(const char *); + void clear_filters(); + void add_filter(const char *, const char *); + +public: + Fl_Native_File_Chooser(int val = BROWSE_FILE); + ~Fl_Native_File_Chooser(); + + // Public methods + void type(int val); + int type() const; + void options(int); + int options() const; + int count() const; + const char *filename() const; + const char *filename(int i) const; + void directory(const char *val); + const char *directory() const; + void title(const char *val); + const char *title() const; + const char *filter() const; + void filter(const char *val); + int filters() const { return _nfilters; } + void filter_value(int i); + int filter_value() const; + void preset_file(const char *); + const char *preset_file() const; + const char *errmsg() const; + int show(); +}; +#endif /*!FL_DOXYGEN*/ + +// +// End of "$Id: Fl_Native_File_Chooser_WIN32.H 7003 2010-01-14 20:47:59Z greg.ercolano $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Paged_Device.H b/plugins/zynaddsubfx/fltk/FL/Fl_Paged_Device.H new file mode 100644 index 000000000..345a4bab9 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Paged_Device.H @@ -0,0 +1,92 @@ +// +// "$Id: Fl_Paged_Device.H 7622 2010-05-27 17:50:51Z manolo $" +// +// Printing support for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** \file Fl_Paged_Device.H + \brief declaration of class Fl_Paged_Device. + */ + +#ifndef Fl_Paged_Device_H +#define Fl_Paged_Device_H + +#include + +/** + \brief Represents page-structured drawing surfaces. + * + This class has no public constructor: don't instantiate it; use Fl_Printer + or Fl_PostScript_File_Device instead. + */ +class Fl_Paged_Device : public Fl_Surface_Device { +private: +#ifdef __APPLE__ + struct chain_elt { + Fl_Image *image; + const uchar *data; + struct chain_elt *next; + }; + void add_image(Fl_Image *image, const uchar *data); // adds an image to the page image list +#endif + void traverse(Fl_Widget *widget); // finds subwindows of widget and prints them +protected: + /** \brief horizontal offset to the origin of graphics coordinates */ + int x_offset; + /** \brief vertical offset to the origin of graphics coordinates */ + int y_offset; + /** \brief chained list of Fl_Image's used in this page */ + struct chain_elt *image_list_; +#ifdef __APPLE__ + /** \brief deletes the page image list */ + void delete_image_list(); +#endif + /** \brief The constructor */ + Fl_Paged_Device() : Fl_Surface_Device(NULL) {type_ = device_type;}; + /** \brief The destructor */ + virtual ~Fl_Paged_Device() {}; +public: + static const char *device_type; + virtual int start_job(int pagecount, int *frompage = NULL, int *topage = NULL); + virtual int start_page(void); + virtual int printable_rect(int *w, int *h); + virtual void margins(int *left, int *top, int *right, int *bottom); + virtual void origin(int x, int y); + void origin(int *x, int *y); + virtual void scale(float scale_x, float scale_y); + virtual void rotate(float angle); + virtual void translate(int x, int y); + virtual void untranslate(void); + void print_widget(Fl_Widget* widget, int delta_x = 0, int delta_y = 0); + void print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x = 0, int delta_y = 0); + virtual int end_page (void); + virtual void end_job (void); +}; + +#endif // Fl_Paged_Device_H + +// +// End of "$Id: Fl_Paged_Device.H 7622 2010-05-27 17:50:51Z manolo $" +// + diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Pixmap.H b/plugins/zynaddsubfx/fltk/FL/Fl_Pixmap.H index 264fb38a5..273ed20d8 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Pixmap.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Pixmap.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Pixmap.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Pixmap.H 7617 2010-05-27 17:20:18Z manolo $" // // Pixmap header file for the Fast Light Tool Kit (FLTK). // @@ -45,6 +45,9 @@ struct Fl_Menu_Item; (pixmap) images, including transparency. */ class FL_EXPORT Fl_Pixmap : public Fl_Image { + friend class Fl_Quartz_Graphics_Driver; + friend class Fl_GDI_Graphics_Driver; + friend class Fl_Xlib_Graphics_Driver; void copy_data(); void delete_data(); void set_data(const char * const *p); @@ -56,22 +59,27 @@ class FL_EXPORT Fl_Pixmap : public Fl_Image { public: int alloc_data; // Non-zero if data was allocated + + private: + #if defined(__APPLE__) || defined(WIN32) - void *id; // for internal use - void *mask; // for internal use (mask bitmap) + void *id_; // for internal use + void *mask_; // for internal use (mask bitmap) #else - unsigned id; // for internal use - unsigned mask; // for internal use (mask bitmap) + unsigned id_; // for internal use + unsigned mask_; // for internal use (mask bitmap) #endif // __APPLE__ || WIN32 + public: + /** The constructors create a new pixmap from the specified XPM data. */ - explicit Fl_Pixmap(char * const * D) : Fl_Image(-1,0,1), alloc_data(0), id(0), mask(0) {set_data((const char*const*)D); measure();} + explicit Fl_Pixmap(char * const * D) : Fl_Image(-1,0,1), alloc_data(0), id_(0), mask_(0) {set_data((const char*const*)D); measure();} /** The constructors create a new pixmap from the specified XPM data. */ - explicit Fl_Pixmap(uchar* const * D) : Fl_Image(-1,0,1), alloc_data(0), id(0), mask(0) {set_data((const char*const*)D); measure();} + explicit Fl_Pixmap(uchar* const * D) : Fl_Image(-1,0,1), alloc_data(0), id_(0), mask_(0) {set_data((const char*const*)D); measure();} /** The constructors create a new pixmap from the specified XPM data. */ - explicit Fl_Pixmap(const char * const * D) : Fl_Image(-1,0,1), alloc_data(0), id(0), mask(0) {set_data((const char*const*)D); measure();} + explicit Fl_Pixmap(const char * const * D) : Fl_Image(-1,0,1), alloc_data(0), id_(0), mask_(0) {set_data((const char*const*)D); measure();} /** The constructors create a new pixmap from the specified XPM data. */ - explicit Fl_Pixmap(const uchar* const * D) : Fl_Image(-1,0,1), alloc_data(0), id(0), mask(0) {set_data((const char*const*)D); measure();} + explicit Fl_Pixmap(const uchar* const * D) : Fl_Image(-1,0,1), alloc_data(0), id_(0), mask_(0) {set_data((const char*const*)D); measure();} virtual ~Fl_Pixmap(); virtual Fl_Image *copy(int W, int H); Fl_Image *copy() { return copy(w(), h()); } @@ -87,5 +95,5 @@ class FL_EXPORT Fl_Pixmap : public Fl_Image { #endif // -// End of "$Id: Fl_Pixmap.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: Fl_Pixmap.H 7617 2010-05-27 17:20:18Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Plugin.H b/plugins/zynaddsubfx/fltk/FL/Fl_Plugin.H new file mode 100644 index 000000000..231a802cc --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Plugin.H @@ -0,0 +1,106 @@ +// +// "$Id: Fl_Plugin.H 6995 2010-01-12 08:48:55Z matt $" +// +// A Plugin system for FLTK, implemented in Fl_Preferences.cxx. +// +// Copyright 2002-2010 by Matthias Melcher. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* \file + Fl_Plugin class . */ + +#ifndef Fl_Plugin_H +# define Fl_Plugin_H + +# include "Fl_Preferences.H" + + +/** + \brief Fl_Plugin allows link-time and run-time integration of binary modules. + + Fl_Plugin and Fl_Plugin_Manager provide a small and simple solution for + linking C++ classes at run-time, or optionally linking modules at compile + time without the need to change the main application. + + Fl_Plugin_Manager uses static initialisation to create the plugin interface + early during startup. Plugins are stored in a temporary database, organized + in classes. + + Plugins should derive a new class from Fl_Plugin as a base: + \code + class My_Plugin : public Fl_Plugin { + public: + My_Plugin() : Fl_Plugin("effects", "blur") { } + void do_something(...); + }; + My_Plugin blur_plugin(); + \endcode + + Plugins can be put into modules and either linked befor distribution, or loaded + from dynamically linkable files. An Fl_Plugin_Manager is used to list and + access all currently loaded plugins. + \code + Fl_Plugin_Manager mgr("effects"); + int i, n = mgr.plugins(); + for (i=0; ido_something(); + } + \endcode + */ +class FL_EXPORT Fl_Plugin +{ + Fl_Preferences::ID id; +public: + Fl_Plugin(const char *klass, const char *name); + virtual ~Fl_Plugin(); +}; + + +/** + \brief Fl_Plugin_Manager manages link-time and run-time plugin binaries. + \see Fl_Plugin + */ +class FL_EXPORT Fl_Plugin_Manager : public Fl_Preferences +{ +public: + Fl_Plugin_Manager(const char *klass); + ~Fl_Plugin_Manager(); + + /** \brief Return the number of plugins in the klass. + */ + int plugins() { return groups(); } + Fl_Plugin *plugin(int index); + Fl_Plugin *plugin(const char *name); + Fl_Preferences::ID addPlugin(const char *name, Fl_Plugin *plugin); + + static void removePlugin(Fl_Preferences::ID id); + static int load(const char *filename); + static int loadAll(const char *filepath, const char *pattern=0); +}; + + +#endif // !Fl_Preferences_H + +// +// End of "$Id: Fl_Preferences.H 6995 2010-01-12 08:48:55Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_PostScript.H b/plugins/zynaddsubfx/fltk/FL/Fl_PostScript.H new file mode 100644 index 000000000..9a998a6d6 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_PostScript.H @@ -0,0 +1,293 @@ +// +// "$Id: Fl_PostScript.H 7622 2010-05-27 17:50:51Z manolo $" +// +// Support for graphics output to PostScript file for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +/** \file Fl_PostScript.H + \brief declaration of classes Fl_PostScript_Graphics_Driver, Fl_PostScript_File_Device. + */ + + +#ifndef Fl_PostScript_H +#define Fl_PostScript_H + +#include +#include + +#define NO_PAGE_FORMATS 30 /* MSVC6 compilation fix */ + +/** + \brief PostScript graphical backend. + * + PostScript text output is presently implemented only for the latin character set. + FLTK's standard fonts are output using PostScript's standard fonts: Helvetica, Courier, + Times (and their bold, oblique, italic variants), Symbol, ZapfDingbats. + */ +class Fl_PostScript_Graphics_Driver : public Fl_Graphics_Driver { +public: + static const char *device_type; + /** + \brief Possible page formats. + */ + enum Page_Format { + A0 = 0, + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + B0, + B1, + B2, + B3, + B4, + B5, + B6, + B7, + B8, + B9, + B10, + C5E, + DLE, + EXECUTIVE, + FOLIO, + LEDGER, + LEGAL, + LETTER, + TABLOID, + ENVELOPE, + MEDIA = 0x1000 + }; + + /** + \brief Possible page layouts. + */ + enum Page_Layout {PORTRAIT = 0, LANDSCAPE = 0x100, REVERSED = 0x200, ORIENTATION = 0x300}; + +#ifndef FL_DOXYGEN +public: + enum SHAPE{NONE=0, LINE, LOOP, POLYGON, POINTS}; + +typedef struct page_format { + int width; + int height; + const char *name; +} page_format; + +class Clip { + public: + int x, y, w, h; + Clip *prev; + }; + Clip * clip_; + + int lang_level_; + int font_; + int size_; + Fl_Color color_; + int gap_; + int pages_; + + double width_; + double height_; + + int shape_; + int linewidth_;// need for clipping, lang level 1-2 + int linestyle_;// + int interpolate_; //interpolation of images + unsigned char cr_,cg_,cb_; + char linedash_[256];//should be enough + void concat(); // transform ror scalable dradings... + void reconcat(); //invert + void recover(); //recovers the state after grestore (such as line styles...) + void reset(); + + uchar * mask; + int mx; // width of mask; + int my; // mask lines + //Fl_Color bg_; + int (*close_cmd_)(FILE *); + int page_policy_; + int nPages; + int orientation_; + + float scale_x; + float scale_y; + float angle; + int left_margin; + int top_margin; + + FILE *output; + double pw_, ph_; + static const page_format page_formats[NO_PAGE_FORMATS]; + + uchar bg_r, bg_g, bg_b; + int start_postscript (int pagecount, enum Page_Format format, enum Page_Layout layout); + /* int alpha_mask(const uchar * data, int w, int h, int D, int LD=0); + */ + void draw(const char* s, int n, int x, int y) {transformed_draw(s,n,x,y); }; + void draw(int angle, const char *str, int n, int x, int y); + void transformed_draw(const char* s, int n, double x, double y); //precise text placing + void transformed_draw(const char* s, double x, double y); + int alpha_mask(const uchar * data, int w, int h, int D, int LD=0); + void draw_scaled_image(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D=3, int LD=0); + void draw_scaled_image_mono(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D=3, int LD=0); + void draw_scaled_image(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D); + void draw_scaled_image_mono(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D); + + enum Page_Format page_format_; + char *ps_filename_; + // implementation of drawing methods + void color(Fl_Color c); + //void bg_color(Fl_Color bg); + void color(uchar r, uchar g, uchar b); + Fl_Color color(){return color_;}; + + void push_clip(int x, int y, int w, int h); + int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H); + int not_clipped(int x, int y, int w, int h); + void push_no_clip(); + void pop_clip(); + + void line_style(int style, int width=0, char* dashes=0); + + void rect(int x, int y, int w, int h); + void rectf(int x, int y, int w, int h); + + void xyline(int x, int y, int x1); + void xyline(int x, int y, int x1, int y2); + void xyline(int x, int y, int x1, int y2, int x3); + + void yxline(int x, int y, int y1); + void yxline(int x, int y, int y1, int x2); + void yxline(int x, int y, int y1, int x2, int y3); + + void line(int x1, int y1, int x2, int y2); + void line(int x1, int y1, int x2, int y2, int x3, int y3); + + void loop(int x0, int y0, int x1, int y1, int x2, int y2); + void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3); + void polygon(int x0, int y0, int x1, int y1, int x2, int y2); + void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3); + void point(int x, int y); + + void begin_points(); + void begin_line(); + void begin_loop(); + void begin_polygon(); + void vertex(double x, double y); + void curve(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3); + void circle(double x, double y, double r); + void arc(double x, double y, double r, double start, double a); + void arc(int x, int y, int w, int h, double a1, double a2); + void pie(int x, int y, int w, int h, double a1, double a2); + void end_points(); + void end_line(); + void end_loop(); + void end_polygon(); + void begin_complex_polygon(){begin_polygon();}; + void gap(){gap_=1;}; + void end_complex_polygon(){end_polygon();}; + void transformed_vertex(double x, double y); + + void font(int face, int size); + int font(){return font_;}; + int size(){return size_;}; + double width(unsigned c); + double width(const char* s, int n); + int descent(); + int height(); + + void draw_image(const uchar* d, int x,int y,int w,int h, int delta=3, int ldelta=0){draw_scaled_image(d,x,y,w,h,w,h,delta,ldelta);}; + void draw_image_mono(const uchar* d, int x,int y,int w,int h, int delta=1, int ld=0){draw_scaled_image_mono(d,x,y,w,h,w,h,delta,ld);}; + void draw_image(Fl_Draw_Image_Cb call, void* data, int x,int y, int w, int h, int delta=3){draw_scaled_image(call,data, x, y, w, h, w, h, delta);}; + void draw_image_mono(Fl_Draw_Image_Cb call, void* data, int x,int y, int w, int h, int delta=1){draw_scaled_image_mono(call, data, x, y, w, h, w, h, delta);}; + + void draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy); + void draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy); + void draw(Fl_Bitmap * bitmap,int XP, int YP, int WP, int HP, int cx, int cy); + +public: + void page_policy(int p); + int page_policy(){return page_policy_;}; + void close_command( int (*cmd)(FILE *)){close_cmd_=cmd;}; + FILE * file() {return output;}; + //void orientation (int o); + //Fl_PostScript_Graphics_Driver(FILE *o, int lang_level, int pages = 0); // ps (also multi-page) constructor + //Fl_PostScript_Graphics_Driver(FILE *o, int lang_level, int x, int y, int w, int h); //eps constructor + void interpolate(int i){interpolate_=i;}; + int interpolate(){return interpolate_;} + + void page(double pw, double ph, int media = 0); + void page(int format); + + void place(double x, double y, double tx, double ty, double scale = 1); +#endif // FL_DOXYGEN + Fl_PostScript_Graphics_Driver(); + ~Fl_PostScript_Graphics_Driver(); +}; + +/** + \brief To send graphical output to a PostScript file. + */ +class Fl_PostScript_File_Device : public Fl_Paged_Device { +#ifdef __APPLE__ + CGContextRef gc; +#endif +protected: + Fl_PostScript_Graphics_Driver *driver(); +public: + static const char *device_type; + Fl_PostScript_File_Device(); + ~Fl_PostScript_File_Device(); + int start_job(int pagecount, enum Fl_PostScript_Graphics_Driver::Page_Format format = Fl_PostScript_Graphics_Driver::A4, + enum Fl_PostScript_Graphics_Driver::Page_Layout layout = Fl_PostScript_Graphics_Driver::PORTRAIT); + int start_job(FILE *ps_output, int pagecount, enum Fl_PostScript_Graphics_Driver::Page_Format format = Fl_PostScript_Graphics_Driver::A4, + enum Fl_PostScript_Graphics_Driver::Page_Layout layout = Fl_PostScript_Graphics_Driver::PORTRAIT); + int start_page (void); + int printable_rect(int *w, int *h); + void margins(int *left, int *top, int *right, int *bottom); + void origin(int x, int y); + void scale (float scale_x, float scale_y); + void rotate(float angle); + void translate(int x, int y); + void untranslate(void); + int end_page (void); + void end_job(void); +#ifdef __APPLE__ + void set_current() { fl_gc = gc; Fl_Paged_Device::set_current(); } +#endif + + static const char *file_chooser_title; +}; + +#endif // Fl_PostScript_H + +// +// End of "$Id: Fl_PostScript.H 7622 2010-05-27 17:50:51Z manolo $" +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Preferences.H b/plugins/zynaddsubfx/fltk/FL/Fl_Preferences.H index a05653d14..1c201814b 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Preferences.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Preferences.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Preferences.H 6770 2009-04-18 18:52:59Z matt $" +// "$Id: Fl_Preferences.H 7672 2010-07-10 09:44:45Z matt $" // // Preferences . // @@ -57,11 +57,11 @@ yet exist. Entries can be of any length. However, the size of each - preferences file should be kept under 100k for performance + preferences file should be kept small for performance reasons. One application can have multiple preferences files. Extensive binary data however should be stored in separate files: see getUserdataPath(). - + \note Starting with FLTK 1.3, preference databases are expected to be in utf8 encoding. Previous databases were stored in the current chracter set or code page which renders them incompatible @@ -79,22 +79,57 @@ public: SYSTEM=0, ///< Preferences are used system-wide USER ///< Preferences apply only to the current user }; + + /** + Every Fl_Preferences-Group has a uniqe ID. + + ID's can be retrieved from an Fl_Preferences-Group and can then be used + to create more Fl_Preference references to the same data set, as long as the + database remains open. + */ + typedef void *ID; + + static const char *newUUID(); Fl_Preferences( Root root, const char *vendor, const char *application ); Fl_Preferences( const char *path, const char *vendor, const char *application ); Fl_Preferences( Fl_Preferences &parent, const char *group ); - Fl_Preferences( Fl_Preferences*, const char *group ); + Fl_Preferences( Fl_Preferences *parent, const char *group ); + Fl_Preferences( Fl_Preferences &parent, int groupIndex ); + Fl_Preferences( Fl_Preferences *parent, int groupIndex ); + Fl_Preferences(const Fl_Preferences&); + Fl_Preferences( ID id ); ~Fl_Preferences(); + + /** Return an ID that can later be reused to open more references to this dataset. + */ + ID id() { return (ID)node; } + + /** Remove the group with this ID from a database. + */ + static char remove(ID id_) { return ((Node*)id_)->remove(); } + /** Return the name of this entry. + */ + const char *name() { return node->name(); } + + /** Return the the full path to this entry. + */ + const char *path() { return node->path(); } + int groups(); const char *group( int num_group ); char groupExists( const char *key ); char deleteGroup( const char *group ); + char deleteAllGroups(); int entries(); const char *entry( int index ); char entryExists( const char *key ); char deleteEntry( const char *entry ); + char deleteAllEntries(); + + char clear(); char set( const char *entry, int value ); char set( const char *entry, float value ); @@ -120,6 +155,8 @@ public: // char export( const char *filename, Type fileFormat ); // char import( const char *filename ); + + // char copyTo(class Fl_Tree*); // deprecated, use Fl_Tree::load(Fl_Preferences&) /** 'Name' provides a simple method to create numerical or more complex @@ -157,30 +194,54 @@ public: private: - // make the following functions unavailable - Fl_Preferences(); - Fl_Preferences(const Fl_Preferences&); + Fl_Preferences() : node(0), rootNode(0) { } Fl_Preferences &operator=(const Fl_Preferences&); static char nameBuffer[128]; + static char uuidBuffer[40]; + static Fl_Preferences *runtimePrefs; + class RootNode; + class FL_EXPORT Node // a node contains a list to all its entries { // and all means to manage the tree structure - Node *child_, *next_, *parent_; + Node *child_, *next_; + union { // these two are mutually exclusive + Node *parent_; // top_ bit clear + RootNode *root_; // top_ bit set + }; char *path_; - char dirty_; + Entry *entry_; + int nEntry_, NEntry_; + unsigned char dirty_:1; + unsigned char top_:1; + unsigned char indexed_:1; + // indexing routines + Node **index_; + int nIndex_, NIndex_; + void createIndex(); + void updateIndex(); + void deleteIndex(); + public: + static int lastEntrySet; public: Node( const char *path ); ~Node(); // node methods int write( FILE *f ); + const char *name(); + const char *path() { return path_; } Node *find( const char *path ); Node *search( const char *path, int offset=0 ); + Node *childNode( int ix ); Node *addChild( const char *path ); void setParent( Node *parent ); - Node *parent() { return parent_; } + Node *parent() { return top_?0L:parent_; } + void setRoot(RootNode *r) { root_ = r; top_ = 1; } + RootNode *findRoot(); char remove(); char dirty(); + void deleteAllChildren(); // entry methods int nChildren(); const char *child( int ix ); @@ -190,10 +251,9 @@ private: const char *get( const char *name ); int getEntry( const char *name ); char deleteEntry( const char *name ); - // public values - Entry *entry; - int nEntry, NEntry; - static int lastEntrySet; + void deleteAllEntries(); + int nEntry() { return nEntry_; } + Entry &entry(int i) { return entry_[i]; } }; friend class Node; @@ -205,6 +265,7 @@ private: public: RootNode( Fl_Preferences *, Root root, const char *vendor, const char *application ); RootNode( Fl_Preferences *, const char *path, const char *vendor, const char *application ); + RootNode( Fl_Preferences * ); ~RootNode(); int read(); int write(); @@ -212,14 +273,15 @@ private: }; friend class RootNode; +protected: + Node *node; RootNode *rootNode; - }; #endif // !Fl_Preferences_H // -// End of "$Id: Fl_Preferences.H 6770 2009-04-18 18:52:59Z matt $". +// End of "$Id: Fl_Preferences.H 7672 2010-07-10 09:44:45Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Printer.H b/plugins/zynaddsubfx/fltk/FL/Fl_Printer.H new file mode 100644 index 000000000..91450837a --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Printer.H @@ -0,0 +1,270 @@ +// +// "$Id: Fl_Printer.H 7662 2010-07-01 15:35:28Z manolo $" +// +// Printing support for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +/** \file Fl_Printer.H + \brief declaration of classes Fl_System_Printer, Fl_PostScript_Printer, Fl_Printer, Fl_Device_Plugin. + */ + +#ifndef Fl_Printer_H +#define Fl_Printer_H + +#include +#include +#include +#include +#include +#include +#if !(defined(__APPLE__) || defined(WIN32)) +#include +#endif + +#if defined(__APPLE__) || defined(WIN32) || defined(FL_DOXYGEN) +/** + \brief Print support under MSWindows and Mac OS X. +* + Use Fl_Printer instead that is cross-platform and has the same API. + Fl_Printer is typedef'ed to Fl_System_Printer under MSWindows and Mac OS X. + */ +class Fl_System_Printer : public Fl_Paged_Device { +private: + /** \brief the printer's graphics context, if there's one, NULL otherwise */ + void *gc; + void set_current(); +#ifdef __APPLE__ + float scale_x; + float scale_y; + float angle; // rotation angle in radians + PMPrintSession printSession; + PMPageFormat pageFormat; + PMPrintSettings printSettings; +#elif defined(WIN32) + int abortPrint; + PRINTDLG pd; + HDC hPr; + int prerr; + int left_margin; + int top_margin; + void absolute_printable_rect(int *x, int *y, int *w, int *h); +#endif +public: + static const char *device_type; + /** + @brief The constructor. + */ + Fl_System_Printer(void); + int start_job(int pagecount, int *frompage = NULL, int *topage = NULL); + int start_page (void); + int printable_rect(int *w, int *h); + void margins(int *left, int *top, int *right, int *bottom); + void origin(int x, int y); + void scale (float scale_x, float scale_y); + void rotate(float angle); + void translate(int x, int y); + void untranslate(void); + int end_page (void); + void end_job (void); + + /** + @brief The destructor. + */ + ~Fl_System_Printer(void); +#ifndef FL_DOXYGEN +public: + static const char *dialog_title; + static const char *dialog_printer; + static const char *dialog_range; + static const char *dialog_copies; + static const char *dialog_all; + static const char *dialog_pages; + static const char *dialog_from; + static const char *dialog_to; + static const char *dialog_properties; + static const char *dialog_copyNo; + static const char *dialog_print_button; + static const char *dialog_cancel_button; + static const char *dialog_print_to_file; + static const char *property_title; + static const char *property_pagesize; + static const char *property_mode; + static const char *property_use; + static const char *property_save; + static const char *property_cancel; +#endif // FL_DOXYGEN +}; // class Fl_System_Printer + +/** \brief OS-independant class name */ +typedef Fl_System_Printer Fl_Printer; +#endif + +#if !(defined(__APPLE__) || defined(WIN32)) +/** + \brief Print support under Unix/Linux. + * + Use Fl_Printer instead that is cross-platform and has the same API. + Fl_Printer is typedef'ed to Fl_PostScript_Printer under Unix/Linux. + */ +class Fl_PostScript_Printer : public Fl_PostScript_File_Device { +private: + void set_current(); +public: + static const char *device_type; + int start_job(int pages, int *firstpage = NULL, int *lastpage = NULL); + +#ifndef FL_DOXYGEN + static const char *dialog_title; + static const char *dialog_printer; + static const char *dialog_range; + static const char *dialog_copies; + static const char *dialog_all; + static const char *dialog_pages; + static const char *dialog_from; + static const char *dialog_to; + static const char *dialog_properties; + static const char *dialog_copyNo; + static const char *dialog_print_button; + static const char *dialog_cancel_button; + static const char *dialog_print_to_file; + static const char *property_title; + static const char *property_pagesize; + static const char *property_mode; + static const char *property_use; + static const char *property_save; + static const char *property_cancel; +#endif // FL_DOXYGEN +}; + +/** \brief OS-independant class name */ +typedef Fl_PostScript_Printer Fl_Printer; +#endif + +/** + * @brief OS-independent print support. + * + Fl_Printer allows to use all FLTK drawing, color, text, and clip functions, and to have them operate + on printed page(s). There are two main, non exclusive, ways to use it. +

  • Print any widget (standard, custom, Fl_Window, Fl_Gl_Window) as it appears + on screen, with optional translation, scaling and rotation. This is done by calling print_widget() + or print_window_part(). +
  • Use a series of FLTK graphics commands (e.g., font, text, lines, colors, clip) to + compose a page appropriately shaped for printing. +
+ In both cases, begin by start_job(), start_page(), printable_rect() and origin() calls + and finish by end_page() and end_job() calls. +

Platform specifics +
Fl_Printer is typedef'ed to Fl_PostScript_Printer under Unix/Linux + and to Fl_System_Printer otherwise. Both classes have the same API. +

    +
  • Unix/Linux platforms: + Class Fl_RGB_Image prints but loses its transparency if it has one. + PostScript text output is presently restricted to the Latin alphabet. + Use the static public attributes of this class to set the print dialog to other languages + than English. For example, the "Printer:" dialog item Fl_Printer::dialog_printer can be set to French with: + \code + Fl_Printer::dialog_printer = "Imprimante:"; + \endcode + before creation of the Fl_Printer object. + Use Fl_PostScript_File_Device::file_chooser_title to customize the title of the file chooser dialog that opens + when using the "Print To File" option of the print dialog. +
  • MSWindows platform: Transparent Fl_RGB_Image 's don't print with exact transparency on most printers. + Fl_RGB_Image 's don't rotate() well. + A workaround is to use the print_window_part() call. +
  • Mac OS X platform: all graphics requests print as on display. +
+ */ +#ifdef FL_DOXYGEN +// this class is NOT compiled. It's here for Doxygen documentation purpose only +class Fl_Printer : public Fl_System_Printer, Fl_PostScript_Printer { +public: + static const char *device_type; + /** @brief The constructor */ + Fl_Printer(void); + int start_job(int pagecount, int *frompage = NULL, int *topage = NULL); + int start_page(void); + int printable_rect(int *w, int *h); + void margins(int *left, int *top, int *right, int *bottom); + void origin(int x, int y); + void scale(float scale_x, float scale_y); + void rotate(float angle); + void translate(int x, int y); + void untranslate(void); + int end_page (void); + void end_job (void); + /** @brief The destructor */ + ~Fl_Printer(void); + + /** \name These attributes are effective under the Xlib platform only. + \{ + */ + static const char *dialog_title; + static const char *dialog_printer; + static const char *dialog_range; + static const char *dialog_copies; + static const char *dialog_all; + static const char *dialog_pages; + static const char *dialog_from; + static const char *dialog_to; + static const char *dialog_properties; + static const char *dialog_copyNo; + static const char *dialog_print_button; + static const char *dialog_cancel_button; + static const char *dialog_print_to_file; + static const char *property_title; + static const char *property_pagesize; + static const char *property_mode; + static const char *property_use; + static const char *property_save; + static const char *property_cancel; + /** \} */ +}; +#endif + +/** + This plugin socket allows the integration of new device drivers for special + window or screen types. It is currently used to provide an automated printing + service for OpenGL windows, if linked with fltk_gl. + */ +class Fl_Device_Plugin : public Fl_Plugin { +public: + /** \brief The constructor */ + Fl_Device_Plugin(const char *name) + : Fl_Plugin(klass(), name) { } + /** \brief Returns the class name */ + virtual const char *klass() { return "fltk:device"; } + /** \brief Returns the plugin name */ + virtual const char *name() = 0; + /** \brief Prints a widget + \param w the widget + \param x,y offsets where to print relatively to coordinates origin + \param height height of the current drawing area + */ + virtual int print(Fl_Widget* w, int x, int y, int height) { return 0; } +}; + +#endif // Fl_Printer_H + +// +// End of "$Id: Fl_Printer.H 7662 2010-07-01 15:35:28Z manolo $" +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_RGB_Image.H b/plugins/zynaddsubfx/fltk/FL/Fl_RGB_Image.H new file mode 100644 index 000000000..fd4a44fc7 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_RGB_Image.H @@ -0,0 +1,35 @@ +// +// "$Id: Fl_RGB_Image.H 6942 2009-11-18 12:22:51Z AlbrechtS $" +// +// RGB Image header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_RGB_Image_H +# define Fl_RGB_Image_H +# include "Fl_Image.H" +#endif // !Fl_RGB_Image_H + +// +// End of "$Id: Fl_RGB_Image.H 6942 2009-11-18 12:22:51Z AlbrechtS $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Scroll.H b/plugins/zynaddsubfx/fltk/FL/Fl_Scroll.H index a8bbdb480..f93b222c3 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Scroll.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Scroll.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Scroll.H 6828 2009-07-12 00:15:06Z greg.ercolano $" +// "$Id: Fl_Scroll.H 6951 2009-12-06 22:21:55Z matt $" // // Scroll header file for the Fast Light Tool Kit (FLTK). // @@ -39,19 +39,21 @@ larger than your window. If the child widgets are larger than the size of this object then scrollbars will appear so that you can scroll over to them: -

\image html Fl_Scroll.gif

+ \image html Fl_Scroll.gif \image latex Fl_Scroll.eps "Fl_Scroll" width=4cm -

If all of the child widgets are packed together into a solid + + If all of the child widgets are packed together into a solid rectangle then you want to set box() to FL_NO_BOX or one of the _FRAME types. This will result in the best output. - However, if the child widgets are a sparse arrangment you must set - box() to a real _BOX type. This can result in some + However, if the child widgets are a sparse arrangement you must + set box() to a real _BOX type. This can result in some blinking during redrawing, but that can be solved by using a - Fl_Double_Window.

+ Fl_Double_Window. By default you can scroll in both directions, and the scrollbars disappear if the data will fit in the area of the scroll. -

Use Fl_Scroll::type() to change this as follows : + + Use Fl_Scroll::type() to change this as follows :

  • 0 - No scrollbars
  • Fl_Scroll::HORIZONTAL - Only a horizontal scrollbar.
  • @@ -62,38 +64,38 @@
  • Fl_Scroll::BOTH_ALWAYS - Both always on.
-

Use scrollbar.align(int) ( see void Fl_Widget::align(Fl_Align) ) : - to change what side the scrollbars are drawn on.
If the - FL_ALIGN_LEFT bit is on, the vertical scrollbar is on the left. + Use scrollbar.align(int) ( see void Fl_Widget::align(Fl_Align) ) : + to change what side the scrollbars are drawn on. + + If the FL_ALIGN_LEFT bit is on, the vertical scrollbar is on the left. If the FL_ALIGN_TOP bit is on, the horizontal scrollbar is on the top. Note that only the alignment flags in scrollbar are considered. The flags in hscrollbar however are ignored. -

This widget can also be used to pan around a single child widget + This widget can also be used to pan around a single child widget "canvas". This child widget should be of your own class, with a draw() method that draws the contents. The scrolling is done by changing the x() and y() of the widget, so this child - must use the x() and y() to position it's drawing. + must use the x() and y() to position its drawing. To speed up drawing it should test fl_push_clip(). -

Another very useful child is a single - Fl_Pack, which is itself a group that packs it's children - together and changes size to surround them. Filling the Fl_Pack - with Fl_Tabs groups (and then putting + Another very useful child is a single Fl_Pack, which is itself a group + that packs its children together and changes size to surround them. + Filling the Fl_Pack with Fl_Tabs groups (and then putting normal widgets inside those) gives you a very powerful scrolling list - of individually-openable panels.

+ of individually-openable panels. -

Fluid lets you create these, but you can only lay out objects that + Fluid lets you create these, but you can only lay out objects that fit inside the Fl_Scroll without scrolling. Be sure to leave - space for the scrollbars, as Fluid won't show these either.

-

You cannot use Fl_Window as a child of this since the + space for the scrollbars, as Fluid won't show these either. + + You cannot use Fl_Window as a child of this since the clipping is not conveyed to it when drawn, and it will draw over the scrollbars and neighboring objects. */ class FL_EXPORT Fl_Scroll : public Fl_Group { int xposition_, yposition_; - int width_, height_; int oldx, oldy; int scrollbar_size_; static void hscrollbar_cb(Fl_Widget*, void*); @@ -193,5 +195,5 @@ public: #endif // -// End of "$Id: Fl_Scroll.H 6828 2009-07-12 00:15:06Z greg.ercolano $". +// End of "$Id: Fl_Scroll.H 6951 2009-12-06 22:21:55Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Shared_Image.H b/plugins/zynaddsubfx/fltk/FL/Fl_Shared_Image.H index 8566b6267..0e1b39b20 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Shared_Image.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Shared_Image.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Shared_Image.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Shared_Image.H 7505 2010-04-14 20:47:34Z manolo $" // // Shared image header file for the Fast Light Tool Kit (FLTK). // @@ -25,8 +25,8 @@ // http://www.fltk.org/str.php // -/* \file - Fl_Shared_Image class . */ +/** \file + Fl_Shared_Image class. */ #ifndef Fl_Shared_Image_H # define Fl_Shared_Image_H @@ -106,5 +106,5 @@ FL_EXPORT extern void fl_register_images(); #endif // !Fl_Shared_Image_H // -// End of "$Id: Fl_Shared_Image.H 6614 2009-01-01 16:11:32Z matt $" +// End of "$Id: Fl_Shared_Image.H 7505 2010-04-14 20:47:34Z manolo $" // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Sys_Menu_Bar.H b/plugins/zynaddsubfx/fltk/FL/Fl_Sys_Menu_Bar.H index 27cf7494c..68a26d16a 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Sys_Menu_Bar.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Sys_Menu_Bar.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Sys_Menu_Bar.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Sys_Menu_Bar.H 7518 2010-04-16 19:27:28Z manolo $" // // MacOS system menu bar header file for the Fast Light Tool Kit (FLTK). // @@ -29,28 +29,52 @@ #define Fl_Sys_Menu_Bar_H #include "Fl_Menu_Bar.H" +#include "x.H" -#ifdef __APPLE__ +#if defined(__APPLE__) || defined(FL_DOXYGEN) +/** + @brief A class to create, modify and delete menus that appear on Mac OS X in the menu bar at the top of the screen. + * + * On other than Mac OS X platforms, Fl_Sys_Menu_Bar is a synonym of class Fl_Menu_Bar. + */ class FL_EXPORT Fl_Sys_Menu_Bar : public Fl_Menu_Bar { protected: void draw(); public: + /** + @brief The constructor. + * + * On Mac OS X, all arguments are unused. On other platforms they are used as by Fl_Menu_Bar::Fl_Menu_Bar(). + */ Fl_Sys_Menu_Bar(int x,int y,int w,int h,const char *l=0) : Fl_Menu_Bar(x,y,w,h,l) { - deactivate(); // don't let the old area take events - } + deactivate(); // don't let the old area take events + fl_sys_menu_bar = this; + } void menu(const Fl_Menu_Item *m); + int add(const char* label, int shortcut, Fl_Callback*, void *user_data=0, int flags=0); + int insert(int index, const char* label, int shortcut, Fl_Callback *cb, void *user_data=0, int flags=0); + void remove(int n); + void replace(int rank, const char *name); + void clear(); + int clear_submenu(int index); +#if ! defined(FL_DOXYGEN) + enum menuOrItemOperation { itemAtIndex, setKeyEquivalent, setKeyEquivalentModifierMask, setState, initWithTitle, + numberOfItems, setSubmenu, setEnabled, addSeparatorItem, setTitle, removeItem, addNewItem, renameItem }; + // function doMenuOrItemOperation is in file Fl_cocoa.mm because it contains objective-c code + static void *doMenuOrItemOperation( menuOrItemOperation operation, ...); +#endif }; #else typedef Fl_Menu_Bar Fl_Sys_Menu_Bar; -#endif +#endif // defined(__APPLE__) || defined(FL_DOXYGEN) -#endif +#endif // Fl_Sys_Menu_Bar_H // -// End of "$Id: Fl_Sys_Menu_Bar.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: Fl_Sys_Menu_Bar.H 7518 2010-04-16 19:27:28Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Table.H b/plugins/zynaddsubfx/fltk/FL/Fl_Table.H new file mode 100644 index 000000000..3be069dc4 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Table.H @@ -0,0 +1,1067 @@ +// +// "$Id: Fl_Table.H 7612 2010-05-19 07:22:37Z greg.ercolano $" +// +// Fl_Table -- A table widget +// +// Copyright 2002 by Greg Ercolano. +// Copyright (c) 2004 O'ksi'D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "erco at seriss dot com". +// +// TODO: +// o Auto scroll during dragged selection +// o Keyboard navigation (up/down/left/right arrow) +// + +#ifndef _FL_TABLE_H +#define _FL_TABLE_H + +#include +#include // memcpy +#ifdef WIN32 +#include // WINDOWS: malloc/realloc +#else /*WIN32*/ +#include // UNIX: malloc/realloc +#endif /*WIN32*/ + +#include +#include +#include +#include +#include + +/** + A table of widgets or other content. + + This is the base class for table widgets. + + To be useful it must be subclassed and several virtual functions defined. + Normally applications use widgets derived from this widget, and do not use this + widget directly; this widget is usually too low level to be used directly by + applications. + + This widget does \em not handle the data in the table. The draw_cell() + method must be overridden by a subclass to manage drawing the contents of + the cells. + + This widget can be used in several ways: + + - As a custom widget; see test/testtablerow.cxx. Very optimal for even + extremely large tables. + - As a table made up of a single FLTK widget instanced all over the table; + see test/singleinput.cxx. Very optimal for even extremely large tables; + - As a regular container of FLTK widgets, one widget per cell. + See test/widgettable.cxx. \em Not recommended for large tables. + + When acting as part of a custom widget, events on the cells and/or headings + generate callbacks when they are clicked by the user. You control when events + are generated based on the setting for Fl_Table::when(). + + When acting as a container for FLTK widgets, the FLTK widgets maintain + themselves. Although the draw_cell() method must be overridden, its contents + can be very simple. See the draw_cell() code in test/widgettable.cxx. + + The following variables are available to classes deriving from Fl_Table: + + \image html table-dimensions.gif + + + + + + + + + + + + +
x()/y()/w()/h()Fl_Table widget's outer dimension. The outer edge of the border of the + Fl_Table. (Red in the diagram above)
wix/wiy/wiw/wihFl_Table widget's inner dimension. The inner edge of the border of the + Fl_Table. eg. if the Fl_Table's box() is FL_NO_BOX, these values are the same + as x()/y()/w()/h(). (Yellow in the diagram above)
tox/toy/tow/tohThe table's outer dimension. The outer edge of the border around the cells, + but inside the row/col headings and scrollbars. (Green in the diagram above) +
tix/tiy/tiw/tihThe table's inner dimension. The inner edge of the border around the cells, + but inside the row/col headings and scrollbars. AKA the table's clip region. + eg. if the table_box() is FL_NO_BOX, these values are the same as + tox/toyy/tow/toh. (Blue in the diagram above) +
+ + CORE DEVELOPERS + + - Greg Ercolano : 12/16/2002 - initial implementation 12/16/02. Fl_Table, Fl_Table_Row, docs. + - Jean-Marc Lienher : 02/22/2004 - added keyboard nav + mouse selection, and ported Fl_Table into fltk-utf8-1.1.4 + + OTHER CONTRIBUTORS + + - Inspired by the Feb 2000 version of FLVW's Flvw_Table widget. Mucho thanks to those folks. + - Mister Satan : 04/07/2003 - MinGW porting mods, and singleinput.cxx; a cool Fl_Input oriented spreadsheet example + - Marek Paliwoda : 01/08/2003 - Porting mods for Borland + - Ori Berger : 03/16/2006 - Optimizations for >500k rows/cols + + LICENSE + + Greg added the following license to the original distribution of Fl_Table. He + kindly gave his permission to integrate Fl_Table and Fl_Table_row into FLTK, + allowing FLTK license to apply while his widgets are part of the library. + + If used on its own, this is the license that applies: + + Fl_Table License + December 16, 2002 + + The Fl_Table library and included programs are provided under the terms + of the GNU Library General Public License (LGPL) with the following + exceptions: + + 1. Modifications to the Fl_Table configure script, config + header file, and makefiles by themselves to support + a specific platform do not constitute a modified or + derivative work. + + The authors do request that such modifications be + contributed to the Fl_Table project - send all + contributions to "erco at seriss dot com". + + 2. Widgets that are subclassed from Fl_Table widgets do not + constitute a derivative work. + + 3. Static linking of applications and widgets to the + Fl_Table library does not constitute a derivative work + and does not require the author to provide source + code for the application or widget, use the shared + Fl_Table libraries, or link their applications or + widgets against a user-supplied version of Fl_Table. + + If you link the application or widget to a modified + version of Fl_Table, then the changes to Fl_Table must be + provided under the terms of the LGPL in sections + 1, 2, and 4. + + 4. You do not have to provide a copy of the Fl_Table license + with programs that are linked to the Fl_Table library, nor + do you have to identify the Fl_Table license in your + program or documentation as required by section 6 + of the LGPL. + + However, programs must still identify their use of Fl_Table. + The following example statement can be included in user + documentation to satisfy this requirement: + + [program/widget] is based in part on the work of + the Fl_Table project http://seriss.com/people/erco/fltk/Fl_Table/ + + + */ +class Fl_Table : public Fl_Group { +public: + enum TableContext { + CONTEXT_NONE = 0, + CONTEXT_STARTPAGE = 0x01, // before a page is redrawn + CONTEXT_ENDPAGE = 0x02, // after a page is redrawn + CONTEXT_ROW_HEADER = 0x04, // in the row header + CONTEXT_COL_HEADER = 0x08, // in the col header + CONTEXT_CELL = 0x10, // in one of the cells + CONTEXT_TABLE = 0x20, // in the table + CONTEXT_RC_RESIZE = 0x40 // column or row being resized + }; + +private: + int _rows, _cols; // total rows/cols + int _row_header_w; // width of row header + int _col_header_h; // height of column header + int _row_position; // last row_position set (not necessarily == toprow!) + int _col_position; // last col_position set (not necessarily == leftcol!) + + char _row_header; // row header enabled? + char _col_header; // col header enabled? + char _row_resize; // row resizing enabled? + char _col_resize; // col resizing enabled? + int _row_resize_min; // row minimum resizing height (default=1) + int _col_resize_min; // col minimum resizing width (default=1) + + // OPTIMIZATION: partial row/column redraw variables + int _redraw_toprow; + int _redraw_botrow; + int _redraw_leftcol; + int _redraw_rightcol; + Fl_Color _row_header_color; + Fl_Color _col_header_color; + + int _auto_drag; + int _selecting; + + // An STL-ish vector without templates + class IntVector { + int *arr; + unsigned int _size; + void init() { + arr = NULL; + _size = 0; + } + void copy(int *newarr, unsigned int newsize) { + size(newsize); + memcpy(arr, newarr, newsize * sizeof(int)); + } + public: + IntVector() { init(); } // CTOR + ~IntVector() { if ( arr ) free(arr); arr = NULL; } // DTOR + IntVector(IntVector&o) { init(); copy(o.arr, o._size); } // COPY CTOR + IntVector& operator=(IntVector&o) { // ASSIGN + init(); + copy(o.arr, o._size); + return(*this); + } + int operator[](int x) const { return(arr[x]); } + int& operator[](int x) { return(arr[x]); } + unsigned int size() { return(_size); } + void size(unsigned int count) { + if ( count != _size ) { + arr = (int*)realloc(arr, count * sizeof(int)); + _size = count; + } + } + int pop_back() { int tmp = arr[_size-1]; _size--; return(tmp); } + void push_back(int val) { unsigned int x = _size; size(_size+1); arr[x] = val; } + int back() { return(arr[_size-1]); } + }; + + IntVector _colwidths; // column widths in pixels + IntVector _rowheights; // row heights in pixels + + Fl_Cursor _last_cursor; // last mouse cursor before changed to 'resize' cursor + + // EVENT CALLBACK DATA + TableContext _callback_context; // event context + int _callback_row, _callback_col; // event row/col + + // handle() state variables. + // Put here instead of local statics in handle(), so more + // than one Fl_Table can exist without crosstalk between them. + // + int _resizing_col; // column being dragged + int _resizing_row; // row being dragged + int _dragging_x; // starting x position for horiz drag + int _dragging_y; // starting y position for vert drag + int _last_row; // last row we FL_PUSH'ed + + // Redraw single cell + void _redraw_cell(TableContext context, int R, int C); + + void _start_auto_drag(); + void _stop_auto_drag(); + void _auto_drag_cb(); + static void _auto_drag_cb2(void *d); + +protected: + enum ResizeFlag { + RESIZE_NONE = 0, + RESIZE_COL_LEFT = 1, + RESIZE_COL_RIGHT = 2, + RESIZE_ROW_ABOVE = 3, + RESIZE_ROW_BELOW = 4 + }; + + int table_w, table_h; // table's virtual size (in pixels) + int toprow, botrow, leftcol, rightcol; // four corners of viewable table + + // selection + int current_row, current_col; + int select_row, select_col; + + // OPTIMIZATION: Precomputed scroll positions for the toprow/leftcol + int toprow_scrollpos; + int leftcol_scrollpos; + + // Dimensions + int tix, tiy, tiw, tih; // data table inner dimension xywh + int tox, toy, tow, toh; // data table outer dimension xywh + int wix, wiy, wiw, wih; // widget inner dimension xywh + + Fl_Scroll *table; // container for child fltk widgets (if any) + Fl_Scrollbar *vscrollbar; // vertical scrollbar + Fl_Scrollbar *hscrollbar; // horizontal scrollbar + + // Fltk + int handle(int e); // fltk handle() override + + // Class maintenance + void recalc_dimensions(); + void table_resized(); // table resized; recalc + void table_scrolled(); // table scrolled; recalc + void get_bounds(TableContext context, // return x/y/w/h bounds for context + int &X, int &Y, int &W, int &H); + void change_cursor(Fl_Cursor newcursor); // change mouse cursor to some other shape + TableContext cursor2rowcol(int &R, int &C, ResizeFlag &resizeflag); + // find r/c given current x/y event + int find_cell(TableContext context, // find cell's x/y/w/h given r/c + int R, int C, int &X, int &Y, int &W, int &H); + int row_col_clamp(TableContext context, int &R, int &C); + // clamp r/c to known universe + + /** + Subclass should override this method to handle drawing the cells. + + This method will be called whenever the table is redrawn, once per cell. + + Only cells that are completely (or partially) visible will be told to draw. + + \p context will be one of the following: + + + + + + + + + + + + + + + + + + + + + +
\p Fl_Table::CONTEXT_STARTPAGE When table, or parts of the table, are about to be redrawn. + Use to initialize static data, such as font selections. + r/c will be zero, x/y/w/h will be the dimensions of the + table's entire data area. + (Useful for locking a database before accessing; see + also visible_cells())
\p Fl_Table::CONTEXT_ENDPAGEWhen table has completed being redrawn. + r/c will be zero, x/y/w/h dimensions of table's data area. + (Useful for unlocking a database after accessing)
\p Fl_Table::CONTEXT_ROW_HEADERWhenever a row header cell needs to be drawn.
\p Fl_Table::CONTEXT_COL_HEADERWhenever a column header cell needs to be drawn.
\p Fl_Table::CONTEXT_CELLWhenever a data cell in the table needs to be drawn.
\p Fl_Table::CONTEXT_RC_RESIZEWhenever table or row/column is resized or scrolled, + either interactively or via col_width() or row_height(). + + Useful for fltk containers that need to resize or move + the child fltk widgets.
+ + \p row and \p col will be set to the row and column number + the user clicked on. In the case of row headers, \p col will be \a 0. + In the case of column headers, \p row will be \a 0. + + x/y/w/h will be the position and dimensions of where the cell + should be drawn. + + In the case of custom widgets, a minimal draw_cell() override might + look like the following. With custom widgets it is up to the caller to handle + drawing everything within the dimensions of the cell, including handling the + selection color. Note all clipping must be handled as well; this allows drawing + outside the dimensions of the cell if so desired for 'custom effects'. + + \code + // This is called whenever Fl_Table wants you to draw a cell + void MyTable::draw_cell(TableContext context, int R=0, int C=0, int X=0, int Y=0, int W=0, int H=0) + { + static char s[40]; + sprintf(s, "%d/%d", R, C); // text for each cell + switch ( context ) + { + case CONTEXT_STARTPAGE: // Fl_Table telling us its starting to draw page + fl_font(FL_HELVETICA, 16); + return; + + case CONTEXT_ROW_HEADER: // Fl_Table telling us it's draw row/col headers + case CONTEXT_COL_HEADER: + fl_push_clip(X, Y, W, H); + { + fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, color()); + fl_color(FL_BLACK); + fl_draw(s, X, Y, W, H, FL_ALIGN_CENTER); + } + fl_pop_clip(); + return; + + case CONTEXT_CELL: // Fl_Table telling us to draw cells + fl_push_clip(X, Y, W, H); + { + // BG COLOR + fl_color( row_selected(R) ? selection_color() : FL_WHITE); + fl_rectf(X, Y, W, H); + + // TEXT + fl_color(FL_BLACK); + fl_draw(s, X, Y, W, H, FL_ALIGN_CENTER); + + // BORDER + fl_color(FL_LIGHT2); + fl_rect(X, Y, W, H); + } + fl_pop_clip(); + return; + + default: + return; + } + //NOTREACHED + } + \endcode + */ + virtual void draw_cell(TableContext context, int R=0, int C=0, + int X=0, int Y=0, int W=0, int H=0) + { } // overridden by deriving class + + long row_scroll_position(int row); // find scroll position of row (in pixels) + long col_scroll_position(int col); // find scroll position of col (in pixels) + + int is_fltk_container() { // does table contain fltk widgets? + return( Fl_Group::children() > 3 ); // (ie. more than box and 2 scrollbars?) + } + + static void scroll_cb(Fl_Widget*,void*); // h/v scrollbar callback + + void damage_zone(int r1, int c1, int r2, int c2, int r3 = 0, int c3 = 0); + + void redraw_range(int toprow, int botrow, int leftcol, int rightcol) { + if ( _redraw_toprow == -1 ) { + // Initialize redraw range + _redraw_toprow = toprow; + _redraw_botrow = botrow; + _redraw_leftcol = leftcol; + _redraw_rightcol = rightcol; + } else { + // Extend redraw range + if ( toprow < _redraw_toprow ) _redraw_toprow = toprow; + if ( botrow > _redraw_botrow ) _redraw_botrow = botrow; + if ( leftcol < _redraw_leftcol ) _redraw_leftcol = leftcol; + if ( rightcol > _redraw_rightcol ) _redraw_rightcol = rightcol; + } + + // Indicate partial redraw needed of some cells + damage(FL_DAMAGE_CHILD); + } + +public: + /** + The constructor for the Fl_Table. + This creates an empty table with no rows or columns, + with headers and row/column resize behavior disabled. + */ + Fl_Table(int X, int Y, int W, int H, const char *l=0); + + /** + The destructor for the Fl_Table. + Destroys the table and its associated widgets. + */ + ~Fl_Table(); + + /** + Clears the table to zero rows, zero columns. + Same as rows(0); cols(0); + \see rows(int), cols(int) + */ + virtual void clear() { rows(0); cols(0); } + + // topline() + // middleline() + // bottomline() + + /** + Sets the kind of box drawn around the data table, + the default being FL_NO_BOX. Changing this value will cause the table + to redraw. + */ + inline void table_box(Fl_Boxtype val) { + table->box(val); + table_resized(); + } + + /** + Returns the current box type used for the data table. + */ + inline Fl_Boxtype table_box( void ) { + return(table->box()); + } + + /** + Sets the number of rows in the table, and the table is redrawn. + */ + virtual void rows(int val); // set/get number of rows + + /** + Returns the number of rows in the table. + */ + inline int rows() { + return(_rows); + } + + /** + Set the number of columns in the table and redraw. + */ + virtual void cols(int val); // set/get number of columns + + /** + Get the number of columns in the table. + */ + inline int cols() { + return(_cols); + } + + /** + Returns the range of row and column numbers for all visible + and partially visible cells in the table. + + These values can be used e.g. by your draw_cell() routine during + CONTEXT_STARTPAGE to figure out what cells are about to be redrawn + for the purposes of locking the data from a database before it's drawn. + + \code + leftcol rightcol + : : + toprow .. .-------------------. + | | + | V I S I B L E | + | | + | T A B L E | + | | + botrow .. '-------------------` + \endcode + + e.g. in a table where the visible rows are 5-20, and the + visible columns are 100-120, then those variables would be: + + - toprow = 5 + - botrow = 20 + - leftcol = 100 + - rightcol = 120 + */ + inline void visible_cells(int& r1, int& r2, int& c1, int& c2) { + r1 = toprow; + r2 = botrow; + c1 = leftcol; + c2 = rightcol; + } + + /** + Returns 1 if someone is interactively resizing a row or column. + You can currently call this only from within your callback(). + */ + int is_interactive_resize() { + return(_resizing_row != -1 || _resizing_col != -1); + } + + /** + Returns the current value of this flag. + */ + inline int row_resize() { + return(_row_resize); + } + + /** + Allows/disallows row resizing by the user. + 1=allow interactive resizing, 0=disallow interactive resizing. + Since interactive resizing is done via the row headers, + row_header() must also be enabled to allow resizing. + */ + void row_resize(int flag) { // enable row resizing + _row_resize = flag; + } + + /** + Returns the current value of this flag. + */ + inline int col_resize() { + return(_col_resize); + } + /** + Allows/disallows column resizing by the user. + 1=allow interactive resizing, 0=disallow interactive resizing. + Since interactive resizing is done via the column headers, + \p col_header() must also be enabled to allow resizing. + */ + void col_resize(int flag) { // enable col resizing + _col_resize = flag; + } + + /** + Sets the current column minimum resize value. + This is used to prevent the user from interactively resizing + any column to be smaller than 'pixels'. Must be a value >=1. + */ + inline int col_resize_min() { // column minimum resizing width + return(_col_resize_min); + } + + /** + Returns the current column minimum resize value. + */ + void col_resize_min(int val) { + _col_resize_min = ( val < 1 ) ? 1 : val; + } + + /** + Returns the current row minimum resize value. + */ + inline int row_resize_min() { // column minimum resizing width + return(_row_resize_min); + } + + /** + Sets the current row minimum resize value. + This is used to prevent the user from interactively resizing + any row to be smaller than 'pixels'. Must be a value >=1. + */ + void row_resize_min(int val) { + _row_resize_min = ( val < 1 ) ? 1 : val; + } + + /** + Returns the value of this flag. + */ + inline int row_header() { // set/get row header enable flag + return(_row_header); + } + + /** + Enables/disables showing the row headers. 1=enabled, 0=disabled. + If changed, the table is redrawn. + */ + void row_header(int flag) { + _row_header = flag; + table_resized(); + redraw(); + } + + /** + Returns if column headers are enabled or not. + */ + inline int col_header() { // set/get col header enable flag + return(_col_header); + } + + /** + Enable or disable column headers. + If changed, the table is redrawn. + */ + void col_header(int flag) { + _col_header = flag; + table_resized(); + redraw(); + } + + /** + Sets the height in pixels for column headers and redraws the table. + */ + inline void col_header_height(int height) { // set/get col header height + _col_header_h = height; + table_resized(); + redraw(); + } + + /** + Gets the column header height. + */ + inline int col_header_height() { + return(_col_header_h); + } + + /** + Sets the row header width to n and causes the screen to redraw. + */ + inline void row_header_width(int width) { // set/get row header width + _row_header_w = width; + table_resized(); + redraw(); + } + + /** + Returns the current row header width (in pixels). + */ + inline int row_header_width() { + return(_row_header_w); + } + + /** + Sets the row header color and causes the screen to redraw. + */ + inline void row_header_color(Fl_Color val) { // set/get row header color + _row_header_color = val; + redraw(); + } + + /** + Returns the current row header color. + */ + inline Fl_Color row_header_color() { + return(_row_header_color); + } + + /** + Sets the color for column headers and redraws the table. + */ + inline void col_header_color(Fl_Color val) { // set/get col header color + _col_header_color = val; + redraw(); + } + + /** + Gets the color for column headers. + */ + inline Fl_Color col_header_color() { + return(_col_header_color); + } + + /** + Sets the height of the specified row in pixels, + and the table is redrawn. + callback() will be invoked with CONTEXT_RC_RESIZE + if the row's height was actually changed, and when() is FL_WHEN_CHANGED. + */ + void row_height(int row, int height); // set/get row height + + /** + Returns the current height of the specified row as a value in pixels. + */ + inline int row_height(int row) { + return((row<0 || row>=(int)_rowheights.size()) ? 0 : _rowheights[row]); + } + + /** + Sets the width of the specified column in pixels, and the table is redrawn. + callback() will be invoked with CONTEXT_RC_RESIZE + if the column's width was actually changed, and when() is FL_WHEN_CHANGED. + */ + void col_width(int col, int width); // set/get a column's width + + /** + Returns the current width of the specified column in pixels. + */ + inline int col_width(int col) { + return((col<0 || col>=(int)_colwidths.size()) ? 0 : _colwidths[col]); + } + + /** + Convenience method to set the height of all rows to the + same value, in pixels. The screen is redrawn. + */ + void row_height_all(int height) { // set all row/col heights + for ( int r=0; rinit_sizes(); + table->redraw(); + } + void add(Fl_Widget& w) { + table->add(w); + } + void add(Fl_Widget* w) { + table->add(w); + } + void insert(Fl_Widget& w, int n) { + table->insert(w,n); + } + void insert(Fl_Widget& w, Fl_Widget* w2) { + table->insert(w,w2); + } + void remove(Fl_Widget& w) { + table->remove(w); + } + void begin() { + table->begin(); + } + void end() { + table->end(); + // HACK: Avoid showing Fl_Scroll; seems to erase screen + // causing unnecessary flicker, even if its box() is FL_NO_BOX. + // + if ( table->children() > 2 ) { + table->show(); + } else { + table->hide(); + } + Fl_Group::current(Fl_Group::parent()); + } + Fl_Widget * const *array() { + return(table->array()); + } + + /** + Returns the child widget by an index. + + When using the Fl_Table as a container for FLTK widgets, this method returns + the widget pointer from the internal array of widgets in the container. + + Typically used in loops, eg: + \code + for ( int i=0; ichild(n)); + } + + /** + Returns the number of children in the table. + + When using the Fl_Table as a container for FLTK widgets, this method returns + how many child widgets the table has. + + \see child(int) + */ + int children() const { + return(table->children()-2); // -2: skip Fl_Scroll's h/v scrollbar widgets + } + int find(const Fl_Widget *w) const { + return(table->find(w)); + } + int find(const Fl_Widget &w) const { + return(table->find(w)); + } + // CALLBACKS + + /** + * Returns the current row the event occurred on. + * + * This function should only be used from within the user's callback function + */ + int callback_row() { + return(_callback_row); + } + + /** + * Returns the current column the event occurred on. + * + * This function should only be used from within the user's callback function + */ + int callback_col() { + return(_callback_col); + } + + /** + * Returns the current 'table context'. + * + * This function should only be used from within the user's callback function + */ + TableContext callback_context() { + return(_callback_context); + } + + void do_callback(TableContext context, int row, int col) { + _callback_context = context; + _callback_row = row; + _callback_col = col; + Fl_Widget::do_callback(); + } + +#if DOXYGEN + /** + The Fl_Widget::when() function is used to set a group of flags, determining + when the widget callback is called: + + + + + + + + + +
\p FL_WHEN_CHANGED + callback() will be called when rows or columns are resized (interactively or + via col_width() or row_height()), passing CONTEXT_RC_RESIZE via + callback_context(). +
\p FL_WHEN_RELEASE + callback() will be called during FL_RELEASE events, such as when someone + releases a mouse button somewhere on the table. +
+ + The callback() routine is sent a TableContext that indicates the context the + event occurred in, such as in a cell, in a header, or elsewhere on the table. + When an event occurs in a cell or header, callback_row() and + callback_col() can be used to determine the row and column. The callback can + also look at the regular fltk event values (ie. Fl::event() and Fl::button()) + to determine what kind of event is occurring. + */ + void when(Fl_When flags); +#endif + +#if DOXYGEN + /** + Callbacks will be called depending on the setting of Fl_Widget::when(). + + Callback functions should use the following functions to determine the + context/row/column: + + * Fl_Table::callback_row() returns current row + * Fl_Table::callback_col() returns current column + * Fl_Table::callback_context() returns current table context + + callback_row() and callback_col() will be set to the row and column number the + event occurred on. If someone clicked on a row header, \p col will be \a 0. + If someone clicked on a column header, \p row will be \a 0. + + callback_context() will return one of the following: + + + + + + + + + + + + + + +
Fl_Table::CONTEXT_ROW_HEADERSomeone clicked on a row header. Excludes resizing.
Fl_Table::CONTEXT_COL_HEADERSomeone clicked on a column header. Excludes resizing.
Fl_Table::CONTEXT_CELL + Someone clicked on a cell. + + To receive callbacks for FL_RELEASE events, you must set + when(FL_WHEN_RELEASE). +
Fl_Table::CONTEXT_RC_RESIZE + Someone is resizing rows/columns either interactively, + or via the col_width() or row_height() API. + + Use is_interactive_resize() + to determine interactive resizing. + + If resizing a column, R=0 and C=column being resized. + + If resizing a row, C=0 and R=row being resized. + + NOTE: To receive resize events, you must set when(FL_WHEN_CHANGED). +
+ + \code + class MyTable + { + [..] + private: + // Handle events that happen on the table + void event_callback2() + { + int R = callback_row(), // row where event occurred + C = callback_col(); // column where event occurred + TableContext context = callback_context(); // which part of table + fprintf(stderr, "callback: Row=%d Col=%d Context=%d Event=%d\n", + R, C, (int)context, (int)Fl::event()); + } + + // Actual static callback + static void event_callback(Fl_Widget*, void* data) + { + MyTable *o = (MyTable*)data; + o->event_callback2(); + } + + public: + MyTable() // Constructor + { + [..] + table.callback(&event_callback, (void*)this); // setup callback + table.when(FL_WHEN_CHANGED|FL_WHEN_RELEASE); // when to call it + } + }; + \endcode + */ + void callback(Fl_Widget*, void*); +#endif +}; + +#endif /*_FL_TABLE_H*/ + +// +// End of "$Id: Fl_Table.H 7612 2010-05-19 07:22:37Z greg.ercolano $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Table_Row.H b/plugins/zynaddsubfx/fltk/FL/Fl_Table_Row.H new file mode 100644 index 000000000..936eb47af --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Table_Row.H @@ -0,0 +1,213 @@ +// +// "$Id: Fl_Table_Row.H 6942 2009-11-18 12:22:51Z AlbrechtS $" +// + +#ifndef _FL_TABLE_ROW_H +#define _FL_TABLE_ROW_H + +// +// Fl_Table_Row -- A row oriented table widget +// +// A class specializing in a table of rows. +// Handles row-specific selection behavior. +// +// Copyright 2002 by Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "erco at seriss dot com". +// +// + +#include "Fl_Table.H" + +/** + A table with row selection capabilities. + + This class implements a simple table of rows and columns that specializes in + the selection of rows. This widget is similar in behavior to a "mail subject + browser", similar to that found in mozilla, netscape and outlook mail browsers. + + Most methods of importance will be found in the Fl_Table widget, such as + Fl_Table::rows() and Fl_Table::cols(). + + To be useful it must be subclassed and at minimum the draw_cell() + method must be overridden to provide the content of the cells. This widget + does \em not manage the cell's data content; it is up to the parent + class's draw_cell() method override to provide this. + + Events on the cells and/or headings generate callbacks when they are + clicked by the user. You control when events are generated based on + the values you supply for Fl_Table::when(). + */ +class Fl_Table_Row : public Fl_Table { +public: + enum TableRowSelectMode { + SELECT_NONE, // no selection allowed + SELECT_SINGLE, // single row selection + SELECT_MULTI // multiple row selection (default) + }; +private: + // An STL-ish vector without templates + class CharVector { + char *arr; + int _size; + void init() { + arr = NULL; + _size = 0; + } + void copy(char *newarr, int newsize) { + size(newsize); + memcpy(arr, newarr, newsize * sizeof(char)); + } + public: + CharVector() { // CTOR + init(); + } + ~CharVector() { // DTOR + if ( arr ) free(arr); + arr = NULL; + } + CharVector(CharVector&o) { // COPY CTOR + init(); + copy(o.arr, o._size); + } + CharVector& operator=(CharVector&o) { // ASSIGN + init(); + copy(o.arr, o._size); + return(*this); + } + char operator[](int x) const { + return(arr[x]); + } + char& operator[](int x) { + return(arr[x]); + } + int size() { + return(_size); + } + void size(int count) { + if ( count != _size ) { + arr = (char*)realloc(arr, count * sizeof(char)); + _size = count; + } + } + char pop_back() { + char tmp = arr[_size-1]; + _size--; + return(tmp); + } + void push_back(char val) { + int x = _size; + size(_size+1); + arr[x] = val; + } + char back() { + return(arr[_size-1]); + } + }; + CharVector _rowselect; // selection flag for each row + + // handle() state variables. + // Put here instead of local statics in handle(), so more + // than one instance can exist without crosstalk between. + // + int _dragging_select; // dragging out a selection? + int _last_row; + int _last_y; // last event's Y position + int _last_push_x; // last PUSH event's X position + int _last_push_y; // last PUSH event's Y position + + TableRowSelectMode _selectmode; + +protected: + int handle(int event); + int find_cell(TableContext context, // find cell's x/y/w/h given r/c + int R, int C, int &X, int &Y, int &W, int &H) { + return(Fl_Table::find_cell(context, R, C, X, Y, W, H)); + } + +public: + /** + The constructor for the Fl_Table_Row. + This creates an empty table with no rows or columns, + with headers and row/column resize behavior disabled. + */ + Fl_Table_Row(int X, int Y, int W, int H, const char *l=0) : Fl_Table(X,Y,W,H,l) { + _dragging_select = 0; + _last_row = -1; + _last_y = -1; + _last_push_x = -1; + _last_push_y = -1; + _selectmode = SELECT_MULTI; + } + + /** + The destructor for the Fl_Table_Row. + Destroys the table and its associated widgets. + */ + ~Fl_Table_Row() { } + + void rows(int val); // set number of rows + int rows() { // get number of rows + return(Fl_Table::rows()); + } + + /** + Sets the table selection mode. + + - \p Fl_Table_Row::SELECT_NONE - No selection allowed + - \p Fl_Table_Row::SELECT_SINGLE - Only single rows can be selected + - \p Fl_Table_Row::SELECT_MULTI - Multiple rows can be selected + */ + void type(TableRowSelectMode val); // set selection mode + + TableRowSelectMode type() const { // get selection mode + return(_selectmode); + } + + /** + Checks to see if 'row' is selected. Returns 1 if selected, 0 if not. You can + change the selection of a row by clicking on it, or by using + select_row(row, flag) + */ + int row_selected(int row); // is row selected? (0=no, 1=yes, -1=range err) + + /** + Changes the selection state for 'row', depending on the value + of 'flag'. 0=deselected, 1=select, 2=toggle existing state. + */ + int select_row(int row, int flag=1); // select state for row: flag:0=off, 1=on, 2=toggle + // returns: 0=no change, 1=changed, -1=range err + + /** + This convenience function changes the selection state + for \em all rows based on 'flag'. 0=deselect, 1=select, 2=toggle existing state. + */ + void select_all_rows(int flag=1); // all rows to a known state + + void clear() { + rows(0); // implies clearing selection + cols(0); + Fl_Table::clear(); // clear the table + } +}; + +#endif /*_FL_TABLE_ROW_H*/ + +// +// End of "$Id: Fl_Table_Row.H 6942 2009-11-18 12:22:51Z AlbrechtS $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Text_Buffer.H b/plugins/zynaddsubfx/fltk/FL/Fl_Text_Buffer.H index a4d85139c..84fae40a5 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Text_Buffer.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Text_Buffer.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Text_Buffer.H 6822 2009-07-04 00:24:26Z fabien $" +// "$Id: Fl_Text_Buffer.H 7527 2010-04-18 14:33:33Z engelsman $" // // Header file for Fl_Text_Buffer class. // @@ -28,293 +28,952 @@ // /* \file - Fl_Text_Buffer, Fl_Text_Selection widget . */ + Fl_Text_Buffer, Fl_Text_Selection widget . */ #ifndef FL_TEXT_BUFFER_H #define FL_TEXT_BUFFER_H +/* + Suggested UTF-8 terminology for this file: + + ?? "length" is the number of characters in a string + ?? "size" is the number of bytes + ?? "index" is the position in a string in number of characters + ?? "offset" is the position in a strin in bytes (and must be kept on a charater boundary) + (there seems to be no standard in Uncode documents, howevere "length" is commonly + referencing the number of bytes. Maybe "bytes" and "glyphs" would be the most + obvious way to describe sizes?) + + "character size" is the size of a UTF-8 character in bytes + "character width" is the width of a Unicode character in pixels + + "column" was orginally defined as a character offset from the left margin. It was + identical to the byte offset. In UTF-8, we have neither a byte offset nor + truly fixed width fonts. Column could be a pixel value multiplied with + an average character width (which is a bearable approximation). + */ + + /* Maximum length in characters of a tab or control character expansion - of a single buffer character */ + of a single buffer character */ #define FL_TEXT_MAX_EXP_CHAR_LEN 20 #include "Fl_Export.H" -/** \class Fl_Text_Selection - This is an internal class for Fl_Text_Buffer to manage text selections. - - \todo members must be documented + +/** + \class Fl_Text_Selection + \brief This is an internal class for Fl_Text_Buffer to manage text selections. + This class works correctly with utf-8 strings assuming that the parameters + for all calls are on character boundaries. */ class FL_EXPORT Fl_Text_Selection { friend class Fl_Text_Buffer; - - public: - void set(int start, int end); - void set_rectangular(int start, int end, int rectStart, int rectEnd); - void update(int pos, int nDeleted, int nInserted); - char rectangular() const { return mRectangular; } - int start() const { return mStart; } - int end() const { return mEnd; } - int rect_start() const { return mRectStart; } - int rect_end() const { return mRectEnd; } - /** - Returns a non-zero number if any text has been selected, or 0 - if no text is selected. - */ - char selected() const { return mSelected; } - void selected(char b) { mSelected = b; } - int includes(int pos, int lineStartPos, int dispIndex) const; - int position(int* start, int* end) const; - int position(int* start, int* end, int* isRect, int* rectStart, int* rectEnd) const; - - - protected: - char mSelected; - char mRectangular; - int mStart; - int mEnd; - int mRectStart; - int mRectEnd; + +public: + + /** + \brief Set the selection range. + \param start byte offset to first selected character + \param end byte offset pointing after last selected character + */ + void set(int start, int end); + + /** + \brief Set a regtangular selection range. + \param start byte offset to first selected character + \param end byte offset pointing after last selected character + \param rectStart first selected column + \param rectEnd last selected column +1 + */ + void set_rectangular(int start, int end, int rectStart, int rectEnd); + + /** + \brief Updates a selection afer text was modified. + Updates an individual selection for changes in the corresponding text + \param pos byte offset into text buffer at which the change occured + \param nDeleted number of bytes deleted from the buffer + \param nInserted number of bytes inserted into the buffer + */ + void update(int pos, int nDeleted, int nInserted); + + /** + \brief Returns true if the selection is rectangular. + \return flag + */ + char rectangular() const { return mRectangular; } + + /** + \brief Return the byte offset to the first selected character. + \return byte offset + */ + int start() const { return mStart; } + + /** + \brief Return the byte ofsset to the character after the last selected character. + \return byte offset + */ + int end() const { return mEnd; } + + /** + \brief Return the first column of the rectangular selection. + \return first column of rectangular selection + */ + int rect_start() const { return mRectStart; } + + /** + \brief Return the last column of the rectangular selection + 1. + \return last column of rectangular selection +1 + */ + int rect_end() const { return mRectEnd; } + + /** + \brief Returns true if any text is selected. + \return a non-zero number if any text has been selected, or 0 + if no text is selected. + */ + char selected() const { return mSelected; } + + /** + \brief Modify the 'selected' flag. + \param b new flag + */ + void selected(char b) { mSelected = b; } + + /** + Return true if position \p pos with indentation \p dispIndex is in + the Fl_Text_Selection. + */ + int includes(int pos, int lineStartPos, int dispIndex) const; + + /** + \brief Return the positions of this selection. + \param start retrun byte offset to first selected character + \param end retrun byte offset pointing after last selected character + \return true if selected + */ + int position(int* start, int* end) const; + + /** + \brief Return the positions of this rectangular selection. + \param start return byte offset to first selected character + \param end return byte offset pointing after last selected character + \param isRect return if the selection is rectangular + \param rectStart return first selected column + \param rectEnd return last selected column +1 + \return true if selected + */ + int position(int* start, int* end, int* isRect, int* rectStart, int* rectEnd) const; + +protected: + + char mSelected; ///< this flag is set if any text is selected + char mRectangular; ///< this flag is set if the selection is rectangular + int mStart; ///< byte offset to the first selected character + int mEnd; ///< byte offset to the character after the last selected character + int mRectStart; ///< first selected column (see "column") + int mRectEnd; ///< last selected column +1 (see "column") }; typedef void (*Fl_Text_Modify_Cb)(int pos, int nInserted, int nDeleted, int nRestyled, const char* deletedText, void* cbArg); + typedef void (*Fl_Text_Predelete_Cb)(int pos, int nDeleted, void* cbArg); + /** - The Fl_Text_Buffer class is used by the Fl_Text_Display - and Fl_Text_Editor to manage complex text data and is based upon the - excellent NEdit text editor engine - see http://www.nedit.org/. -*/ -/** - The Fl_Text_Buffer class is used by the - Fl_Text_Display - and - Fl_Text_Editor - to manage complex text data and is based upon the - excellent NEdit text editor engine - see - http://www.nedit.org/. -*/ + \brief This class manages unicode displayed in one or more Fl_Text_Display widgets. + + The Fl_Text_Buffer class is used by the Fl_Text_Display + and Fl_Text_Editor to manage complex text data and is based upon the + excellent NEdit text editor engine - see http://www.nedit.org/. + \todo unicode check + */ class FL_EXPORT Fl_Text_Buffer { - public: - Fl_Text_Buffer(int requestedSize = 0, int preferredGapSize = 1024); - ~Fl_Text_Buffer(); +public: - /** Returns the number of characters in the buffer. */ - int length() const { return mLength; } - char* text() const; - void text(const char* text); - char* text_range(int start, int end) const; - char character(int pos) const; - char* text_in_rectangle(int start, int end, int rectStart, int rectEnd) const; - void insert(int pos, const char* text); - /** Appends the text string to the end of the buffer. */ - void append(const char* t) { insert(length(), t); } - void remove(int start, int end); - void replace(int start, int end, const char *text); - void copy(Fl_Text_Buffer* fromBuf, int fromStart, int fromEnd, int toPos); - int undo(int *cp=0); - void canUndo(char flag=1); - int insertfile(const char *file, int pos, int buflen = 128*1024); - /** - Appends the named file to the end of the buffer. Returns 0 on - success, non-zero on error (strerror() contains reason). 1 indicates - open for read failed (no data loaded). 2 indicates error occurred - while reading data (data was partially loaded). - */ - int appendfile(const char *file, int buflen = 128*1024) - { return insertfile(file, length(), buflen); } - /** Loads a text file into the buffer */ - int loadfile(const char *file, int buflen = 128*1024) - { select(0, length()); remove_selection(); return appendfile(file, buflen); } - int outputfile(const char *file, int start, int end, int buflen = 128*1024); - /** Saves a text file from the current buffer */ - int savefile(const char *file, int buflen = 128*1024) - { return outputfile(file, 0, length(), buflen); } - - void insert_column(int column, int startPos, const char* text, - int* charsInserted, int* charsDeleted); - - void replace_rectangular(int start, int end, int rectStart, int rectEnd, - const char* text); - - void overlay_rectangular(int startPos, int rectStart, int rectEnd, - const char* text, int* charsInserted, - int* charsDeleted); - - void remove_rectangular(int start, int end, int rectStart, int rectEnd); - void clear_rectangular(int start, int end, int rectStart, int rectEnd); - /** Gets the tab width. */ - int tab_distance() const { return mTabDist; } - void tab_distance(int tabDist); - void select(int start, int end); - /** Returns a non 0 value if text has been selected, 0 otherwise */ - int selected() const { return mPrimary.selected(); } - void unselect(); - void select_rectangular(int start, int end, int rectStart, int rectEnd); - int selection_position(int* start, int* end); - - int selection_position(int* start, int* end, int* isRect, int* rectStart, - int* rectEnd); - - char* selection_text(); - void remove_selection(); - void replace_selection(const char* text); - void secondary_select(int start, int end); - /** Returns a non 0 value if text has been selected in the secondary - text selection, 0 otherwise */ - int secondary_selected() { return mSecondary.selected(); } - /** Clears any selection in the secondary text selection object. */ - void secondary_unselect(); - - void secondary_select_rectangular(int start, int end, int rectStart, - int rectEnd); - - int secondary_selection_position(int* start, int* end); - int secondary_selection_position(int* start, int* end, int* isRect, - int* rectStart, int* rectEnd); - - char* secondary_selection_text(); - void remove_secondary_selection(); - void replace_secondary_selection(const char* text); - void highlight(int start, int end); - /** - Returns the highlighted text. When you are done with the - text, free it using the free() function. - */ - int highlight() { return mHighlight.selected(); } - void unhighlight(); - void highlight_rectangular(int start, int end, int rectStart, int rectEnd); - - int highlight_position(int* start, int* end); - int highlight_position(int* start, int* end, int* isRect, int* rectStart, - int* rectEnd); - - char* highlight_text(); - void add_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void* cbArg); - void remove_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void* cbArg); - - /** - Calls all modify callbacks that have been registered using - the add_modify_callback() - method. - */ - void call_modify_callbacks() { call_modify_callbacks(0, 0, 0, 0, 0); } - - void add_predelete_callback(Fl_Text_Predelete_Cb bufPredelCB, void* cbArg); - void remove_predelete_callback(Fl_Text_Predelete_Cb predelCB, void* cbArg); - - /** - Calls the stored pre-delete callback procedure(s) for this buffer to update - the changed area(s) on the screen and any other listeners. + /** + Create an empty text buffer of a pre-determined size. + \param requestedSize use this to avoid unnecessary re-allocation + if you know exactly how much the buffer will need to hold + \param preferredGapSize Initial size for the buffer gap (empty space + in the buffer where text might be inserted + if the user is typing sequential chars) */ - void call_predelete_callbacks() { call_predelete_callbacks(0, 0); } + Fl_Text_Buffer(int requestedSize = 0, int preferredGapSize = 1024); + + /** + Frees a text buffer + */ + ~Fl_Text_Buffer(); + + /** + \brief Returns the number of bytes in the buffer. + \return size of text in bytes + */ + int length() const { return mLength; } + + /** + \brief Get a copy of the entire contents of the text buffer. + Memory is allocated to contain the returned string, which the caller + must free. + \return newly allocated text buffer - must be free'd + */ + char* text() const; + + /** + Replaces the entire contents of the text buffer + \todo unicode check + */ + void text(const char* text); + + /** + \brief Get a copy of a part of the text buffer. + Return a copy of the text between \p start and \p end character positions + from text buffer \p buf. Positions start at 0, and the range does not + include the character pointed to by \p end. + When you are done with the text, free it using the free() function. + \param start byte offset to first character + \param end byte offset after last character in range + \return newly allocated text buffer - must be free'd + */ + char* text_range(int start, int end) const; + + /** + Returns the character at the specified position pos in the buffer. + Positions start at 0 + \param pos byte offset into buffer + \return Unicode UCS-4 encoded character + */ + unsigned int character(int pos) const; + + /** + Convert a byte offset in buffer into a memory address. + */ + const char *address(int pos) const + { return (pos < mGapStart) ? mBuf+pos : mBuf+pos+mGapEnd-mGapStart; } - char* line_text(int pos) const; - int line_start(int pos) const; - int line_end(int pos) const; - int word_start(int pos) const; - int word_end(int pos) const; - int expand_character(int pos, int indent, char *outStr) const; + /** + Convert a byte offset in buffer into a memory address. + */ + char *address(int pos) + { return (pos < mGapStart) ? mBuf+pos : mBuf+pos+mGapEnd-mGapStart; } + + /** + Returns the text from the given rectangle. When you are done + with the text, free it using the free() function. + \todo unicode check + */ + char* text_in_rectangle(int start, int end, int rectStart, int rectEnd) const; + + /** + Inserts null-terminated string \p text at position \p pos. + \param pos insertion position as byte offset (must be utf-8 character aligned) + \param text utf-8 encoded and nul terminated text + */ + void insert(int pos, const char* text); + + /** + Appends the text string to the end of the buffer. + \todo unicode check + */ + void append(const char* t) { insert(length(), t); } + + /** + Deletes a range of characters in the buffer. + \param start byte offset to first character to be removed + \param end byte offset to charcatre after last character to be removed + */ + void remove(int start, int end); + + /** + Deletes the characters between \p start and \p end, and inserts the null-terminated string \p text in their place in the buffer. + \param start byte offset to first character to be removed and new insert position + \param end byte offset to charcatre after last character to be removed + \param text utf-8 encoded and nul terminated text + */ + void replace(int start, int end, const char *text); + + /** + Copies text from one buffer to this one; fromBuf may + be the same as this. + \todo unicode check + */ + void copy(Fl_Text_Buffer* fromBuf, int fromStart, int fromEnd, int toPos); + + /** + Undo text modification according to the undo variables or insert text + from the undo buffer + \todo unicode check + */ + int undo(int *cp=0); + + /** + Lets the undo system know if we can undo changes + */ + void canUndo(char flag=1); + + /** + Inserts a file at the specified position. Returns 0 on success, + non-zero on error (strerror() contains reason). 1 indicates open + for read failed (no data loaded). 2 indicates error occurred + while reading data (data was partially loaded). + \todo unicode check + */ + int insertfile(const char *file, int pos, int buflen = 128*1024); + + /** + Appends the named file to the end of the buffer. Returns 0 on + success, non-zero on error (strerror() contains reason). 1 indicates + open for read failed (no data loaded). 2 indicates error occurred + while reading data (data was partially loaded). + \todo unicode check + */ + int appendfile(const char *file, int buflen = 128*1024) + { return insertfile(file, length(), buflen); } + + /** + Loads a text file into the buffer + \todo unicode check + */ + int loadfile(const char *file, int buflen = 128*1024) + { select(0, length()); remove_selection(); return appendfile(file, buflen); } + + /** + Writes the specified portions of the file to a file. Returns 0 on success, non-zero + on error (strerror() contains reason). 1 indicates open for write failed + (no data saved). 2 indicates error occurred while writing data + (data was partially saved). + \todo unicode check + */ + int outputfile(const char *file, int start, int end, int buflen = 128*1024); + + /** + Saves a text file from the current buffer + \todo unicode check + */ + int savefile(const char *file, int buflen = 128*1024) + { return outputfile(file, 0, length(), buflen); } + + /** + Insert \p s columnwise into buffer starting at displayed character + position \p column on the line beginning at \p startPos. Opens a rectangular + space the width and height of \p s, by moving all text to the right of + \p column right. If \p charsInserted and \p charsDeleted are not NULL, the + number of characters inserted and deleted in the operation (beginning + at \p startPos) are returned in these arguments. + \todo unicode check + */ + void insert_column(int column, int startPos, const char* text, + int* charsInserted, int* charsDeleted); + + /** + Replaces a rectangular area in the buffer, given by \p start, \p end, + \p rectStart, and \p rectEnd, with \p text. If \p text is vertically + longer than the rectangle, add extra lines to make room for it. + \todo unicode check + */ + void replace_rectangular(int start, int end, int rectStart, int rectEnd, + const char* text); + + /** + Overlay \p text between displayed character positions \p rectStart and + \p rectEnd on the line beginning at \p startPos. If \p charsInserted and + \p charsDeleted are not NULL, the number of characters inserted and deleted + in the operation (beginning at \p startPos) are returned in these arguments. + \todo unicode check + */ + void overlay_rectangular(int startPos, int rectStart, int rectEnd, + const char* text, int* charsInserted, + int* charsDeleted); + + /** + Removes a rectangular swath of characters between character positions start + and end and horizontal displayed-character offsets rectStart and rectEnd. + \todo unicode check + */ + void remove_rectangular(int start, int end, int rectStart, int rectEnd); + + /** + Clears text in the specified area. + It clears a rectangular "hole" out of the buffer between character positions + start and end and horizontal displayed-character offsets rectStart and + rectEnd. + \todo unicode check + */ + void clear_rectangular(int start, int end, int rectStart, int rectEnd); + + /** + Gets the tab width. + \todo unicode check + */ + int tab_distance() const { return mTabDist; } + + /** + Set the hardware tab distance (width) used by all displays for this buffer, + and used in computing offsets for rectangular selection operations. + \todo unicode check + */ + void tab_distance(int tabDist); + + /** + Selects a range of characters in the buffer. + \todo unicode check + */ + void select(int start, int end); + + /** + Returns a non 0 value if text has been selected, 0 otherwise + */ + int selected() const { return mPrimary.selected(); } + + /** + Cancels any previous selection on the primary text selection object + \todo unicode check + */ + void unselect(); + + /** + Achieves a rectangular selection on the primary text selection object + \todo unicode check + */ + void select_rectangular(int start, int end, int rectStart, int rectEnd); + + /** + Gets the selection position + \todo unicode check + */ + int selection_position(int* start, int* end); + + /** + Gets the selection position, and rectangular selection info + \todo unicode check + */ + int selection_position(int* start, int* end, int* isRect, int* rectStart, + int* rectEnd); + + /** + Returns the currently selected text. When you are done with + the text, free it using the free() function. + \todo unicode check + */ + char* selection_text(); - static int expand_character(char c, int indent, char* outStr, int tabDist, - char nullSubsChar); + /** + Removes the text in the primary selection. + \todo unicode check + */ + void remove_selection(); + + /** + Replaces the text in the primary selection. + \todo unicode check + */ + void replace_selection(const char* text); + + /** + Selects a range of characters in the secondary selection. + \todo unicode check + */ + void secondary_select(int start, int end); + + /** + Returns a non 0 value if text has been selected in the secondary + text selection, 0 otherwise + */ + int secondary_selected() { return mSecondary.selected(); } + + /** + Clears any selection in the secondary text selection object. + \todo unicode check + */ + void secondary_unselect(); + + /** + Achieves a rectangular selection on the secondary text selection object + \todo unicode check + */ + void secondary_select_rectangular(int start, int end, int rectStart, + int rectEnd); + + /** + Returns the current selection in the secondary text selection object. + \todo unicode check + */ + int secondary_selection_position(int* start, int* end); + + /** + Returns the current selection in the secondary text selection object. + \todo unicode check + */ + int secondary_selection_position(int* start, int* end, int* isRect, + int* rectStart, int* rectEnd); + + /** + Returns the text in the secondary selection. When you are + done with the text, free it using the free() function. + \todo unicode check + */ + char* secondary_selection_text(); + + /** + Removes the text from the buffer corresponding to the secondary text selection object. + \todo unicode check + */ + void remove_secondary_selection(); + + /** + Replaces the text from the buffer corresponding to the secondary + text selection object with the new string \p text. + \todo unicode check + */ + void replace_secondary_selection(const char* text); + + /** + Highlights the specified text within the buffer. + \todo unicode check + */ + void highlight(int start, int end); + + /** + Returns the highlighted text. When you are done with the + text, free it using the free() function. + */ + int highlight() { return mHighlight.selected(); } + + /** + Unhighlights text in the buffer. + \todo unicode check + */ + void unhighlight(); - static int character_width(char c, int indent, int tabDist, char nullSubsChar); - int count_displayed_characters(int lineStartPos, int targetPos) const; - int skip_displayed_characters(int lineStartPos, int nChars); - int count_lines(int startPos, int endPos) const; - int skip_lines(int startPos, int nLines); - int rewind_lines(int startPos, int nLines); - int findchar_forward(int startPos, char searchChar, int* foundPos) const; - int findchar_backward(int startPos, char searchChar, int* foundPos) const; - int findchars_forward(int startPos, const char* searchChars, int* foundPos) const; - int findchars_backward(int startPos, const char* searchChars, int* foundPos) const; + /** + Highlights a rectangular selection in the buffer + \todo unicode check + */ + void highlight_rectangular(int start, int end, int rectStart, int rectEnd); + + /** + Highlights the specified text between \p start and \p end within the buffer. + \todo unicode check + */ + int highlight_position(int* start, int* end); + + /** + Highlights the specified rectangle of text within the buffer. + \todo unicode check + */ + int highlight_position(int* start, int* end, int* isRect, int* rectStart, + int* rectEnd); + + /** + Returns the highlighted text. When you are done with the + text, free it using the free() function. + \todo unicode check + */ + char* highlight_text(); + + /** + Adds a callback function that is called whenever the text buffer is + modified. The callback function is declared as follows: + + \code + typedef void (*Fl_Text_Modify_Cb)(int pos, int nInserted, int nDeleted, + int nRestyled, const char* deletedText, + void* cbArg); + \endcode + \todo unicode check + */ + void add_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void* cbArg); + + /** + Removes a modify callback. + \todo unicode check + */ + void remove_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void* cbArg); + + /** + Calls all modify callbacks that have been registered using + the add_modify_callback() + method. + \todo unicode check + */ + void call_modify_callbacks() { call_modify_callbacks(0, 0, 0, 0, 0); } + + /** + Adds a callback routine to be called before text is deleted from the buffer. + \todo unicode check + */ + void add_predelete_callback(Fl_Text_Predelete_Cb bufPredelCB, void* cbArg); - int search_forward(int startPos, const char* searchString, int* foundPos, - int matchCase = 0) const; + /** + Removes a callback routine \p bufPreDeleteCB associated with argument \p cbArg + to be called before text is deleted from the buffer. + \todo unicode check + */ + void remove_predelete_callback(Fl_Text_Predelete_Cb predelCB, void* cbArg); + + /** + Calls the stored pre-delete callback procedure(s) for this buffer to update + the changed area(s) on the screen and any other listeners. + \todo unicode check + */ + void call_predelete_callbacks() { call_predelete_callbacks(0, 0); } + + /** + Returns the text from the entire line containing the specified + character position. When you are done with the text, free it + using the free() function. + \todo unicode check + */ + char* line_text(int pos) const; + + /** + Returns the position of the start of the line containing position \p pos. + \todo unicode check + */ + int line_start(int pos) const; + + /** + Finds and returns the position of the end of the line containing position \p pos + (which is either a pointer to the newline character ending the line, + or a pointer to one character beyond the end of the buffer) + \todo unicode check + */ + int line_end(int pos) const; - int search_backward(int startPos, const char* searchString, int* foundPos, - int matchCase = 0) const; + /** + Returns the position corresponding to the start of the word + \todo unicode check + */ + int word_start(int pos) const; - int substitute_null_characters(char* string, int length); - void unsubstitute_null_characters(char* string); - /** Returns the current nul substitution character. */ - char null_substitution_character() const { return mNullSubsChar; } - /** Returns the primary selection. */ - const Fl_Text_Selection* primary_selection() const { return &mPrimary; } - /** Returns the primary selection. */ - Fl_Text_Selection* primary_selection() { return &mPrimary; } - /** Returns the secondary selection. */ - const Fl_Text_Selection* secondary_selection() const { return &mSecondary; } - /** Returns the current highlight selection. */ - const Fl_Text_Selection* highlight_selection() const { return &mHighlight; } + /** + Returns the position corresponding to the end of the word. + \todo unicode check + */ + int word_end(int pos) const; + + /** + Expands the given character to a displayable format. Tabs and + other control characters are given special treatment. + Get a character from the text buffer expanded into its screen + representation (which may be several characters for a tab or a + control code). Returns the number of characters written to \p outStr. + \p indent is the number of characters from the start of the line + for figuring tabs. Output string is guranteed to be shorter or + equal in length to FL_TEXT_MAX_EXP_CHAR_LEN + \todo unicode check + */ + int expand_character(int pos, int indent, char *outStr) const; + + /** + Expand a single character \p c from the text buffer into it's displayable + screen representation (which may be several characters for a tab or a + control code). Returns the number of characters added to \p outStr. + \p indent is the number of characters from the start of the line + for figuring tabs of length \p tabDist. Output string is guaranteed + to be shorter or equal in length to FL_TEXT_MAX_EXP_CHAR_LEN + Tabs and other control characters are given special treatment. + \param src address of utf-8 text + \param indent + \param[out] outStr write substitution here + \param tabDist + \return number of byte in substitution + */ + static int expand_character(const char *src, int indent, char* outStr, int tabDist); + + /** + Return the length in displayed characters of character \p c expanded + for display (as discussed above in expand_character() ). + \param src address of utf-8 text + \param indent + \param tabDist + \return number of byte in substitution + */ + static int character_width(const char *src, int indent, int tabDist); + static int character_width(const char c, int indent, int tabDist); - protected: - void call_modify_callbacks(int pos, int nDeleted, int nInserted, - int nRestyled, const char* deletedText) const; - void call_predelete_callbacks(int pos, int nDeleted) const; + /** + Count the number of displayed characters between buffer position + \p lineStartPos and \p targetPos. (displayed characters are the characters + shown on the screen to represent characters in the buffer, where tabs and + control characters are expanded) + \todo unicode check + */ + int count_displayed_characters(int lineStartPos, int targetPos) const; - int insert_(int pos, const char* text); - void remove_(int start, int end); + /** + Count forward from buffer position \p startPos in displayed characters + (displayed characters are the characters shown on the screen to represent + characters in the buffer, where tabs and control characters are expanded) + \param lineStartPos byte offset into buffer + \param nChars number of bytes that are sent to the display + \return byte offset in input after all output bytes are sent + \todo unicode check + */ + int skip_displayed_characters(int lineStartPos, int nChars); + + /** + Counts the number of newlines between \p startPos and \p endPos in buffer. + The character at position \p endPos is not counted. + \todo unicode check + */ + int count_lines(int startPos, int endPos) const; - void remove_rectangular_(int start, int end, int rectStart, int rectEnd, - int* replaceLen, int* endPos); + /** + Finds the first character of the line \p nLines forward from \p startPos + in the buffer and returns its position + \todo unicode check + */ + int skip_lines(int startPos, int nLines); + + /** + Finds and returns the position of the first character of the line \p nLines backwards + from \p startPos (not counting the character pointed to by \p startpos if + that is a newline) in the buffer. \p nLines == 0 means find the beginning of the line + \todo unicode check + */ + int rewind_lines(int startPos, int nLines); - void insert_column_(int column, int startPos, const char* insText, - int* nDeleted, int* nInserted, int* endPos); + /** + Finds the next occurrence of the specified character. + Search forwards in buffer for character \p searchChar, starting + with the character \p startPos, and returning the result in \p foundPos + returns 1 if found, 0 if not. (The difference between this and + BufSearchForward is that it's optimized for single characters. The + overall performance of the text widget is dependent on its ability to + count lines quickly, hence searching for a single character: newline) + \todo unicode check + */ + int findchar_forward(int startPos, char searchChar, int* foundPos) const; + + /** + Search backwards in buffer \p buf for character \p searchChar, starting + with the character BEFORE \p startPos, returning the result in \p foundPos + returns 1 if found, 0 if not. (The difference between this and + BufSearchBackward is that it's optimized for single characters. The + overall performance of the text widget is dependent on its ability to + count lines quickly, hence searching for a single character: newline) + \todo unicode check + */ + int findchar_backward(int startPos, char searchChar, int* foundPos) const; + + /** + Finds the next occurrence of the specified characters. + Search forwards in buffer for characters in \p searchChars, starting + with the character \p startPos, and returning the result in \p foundPos + returns 1 if found, 0 if not. + \todo unicode check + */ + int findchars_forward(int startPos, const char* searchChars, int* foundPos) const; + + /** + Finds the previous occurrence of the specified characters. + Search backwards in buffer for characters in \p searchChars, starting + with the character BEFORE \p startPos, returning the result in \p foundPos + returns 1 if found, 0 if not. + \todo unicode check + */ + int findchars_backward(int startPos, const char* searchChars, int* foundPos) const; + + /** + Search forwards in buffer for string \p searchString, starting with the + character \p startPos, and returning the result in \p foundPos + returns 1 if found, 0 if not. + \todo unicode check + */ + int search_forward(int startPos, const char* searchString, int* foundPos, + int matchCase = 0) const; + + /** + Search backwards in buffer for string searchCharssearchString, starting with the + character BEFORE \p startPos, returning the result in \p foundPos + returns 1 if found, 0 if not. + \todo unicode check + */ + int search_backward(int startPos, const char* searchString, int* foundPos, + int matchCase = 0) const; + + /** + Returns the primary selection. + */ + const Fl_Text_Selection* primary_selection() const { return &mPrimary; } + + /** + Returns the primary selection. + */ + Fl_Text_Selection* primary_selection() { return &mPrimary; } + + /** + Returns the secondary selection. + */ + const Fl_Text_Selection* secondary_selection() const { return &mSecondary; } + + /** + Returns the current highlight selection. + */ + const Fl_Text_Selection* highlight_selection() const { return &mHighlight; } + +protected: - void overlay_rectangular_(int startPos, int rectStart, int rectEnd, - const char* insText, int* nDeleted, - int* nInserted, int* endPos); - - void redisplay_selection(Fl_Text_Selection* oldSelection, - Fl_Text_Selection* newSelection) const; - - void move_gap(int pos); - void reallocate_with_gap(int newGapStart, int newGapLen); - char* selection_text_(Fl_Text_Selection* sel) const; - void remove_selection_(Fl_Text_Selection* sel); - void replace_selection_(Fl_Text_Selection* sel, const char* text); - - void rectangular_selection_boundaries(int lineStartPos, int rectStart, - int rectEnd, int* selStart, - int* selEnd) const; - - void update_selections(int pos, int nDeleted, int nInserted); - - Fl_Text_Selection mPrimary; /**< highlighted areas */ - Fl_Text_Selection mSecondary; /**< highlighted areas */ - Fl_Text_Selection mHighlight; /**< highlighted areas */ - int mLength; /**< length of the text in the buffer (the length + /** + Calls the stored modify callback procedure(s) for this buffer to update the + changed area(s) on the screen and any other listeners. + \todo unicode check + */ + void call_modify_callbacks(int pos, int nDeleted, int nInserted, + int nRestyled, const char* deletedText) const; + + /** + Calls the stored pre-delete callback procedure(s) for this buffer to update + the changed area(s) on the screen and any other listeners. + \todo unicode check + */ + void call_predelete_callbacks(int pos, int nDeleted) const; + + /** + Internal (non-redisplaying) version of BufInsert. Returns the length of + text inserted (this is just strlen(\p text), however this calculation can be + expensive and the length will be required by any caller who will continue + on to call redisplay). \p pos must be contiguous with the existing text in + the buffer (i.e. not past the end). + \todo unicode check + */ + int insert_(int pos, const char* text); + + /** + Internal (non-redisplaying) version of BufRemove. Removes the contents + of the buffer between start and end (and moves the gap to the site of + the delete). + \todo unicode check + */ + void remove_(int start, int end); + + /** + Deletes a rectangle of text without calling the modify callbacks. Returns + the number of characters replacing those between \p start and \p end. Note that + in some pathological cases, deleting can actually increase the size of + the buffer because of tab expansions. \p endPos returns the buffer position + of the point in the last line where the text was removed (as a hint for + routines which need to position the cursor after a delete operation) + \todo unicode check + */ + void remove_rectangular_(int start, int end, int rectStart, int rectEnd, + int* replaceLen, int* endPos); + + /** + Inserts a column of text without calling the modify callbacks. Note that + in some pathological cases, inserting can actually decrease the size of + the buffer because of spaces being coalesced into tabs. \p nDeleted and + \p nInserted return the number of characters deleted and inserted beginning + at the start of the line containing \p startPos. \p endPos returns buffer + position of the lower left edge of the inserted column (as a hint for + routines which need to set a cursor position). + \todo unicode check + */ + void insert_column_(int column, int startPos, const char* insText, + int* nDeleted, int* nInserted, int* endPos); + + /** + Overlay a rectangular area of text without calling the modify callbacks. + \p nDeleted and \p nInserted return the number of characters deleted and + inserted beginning at the start of the line containing \p startPos. + \p endPos returns buffer position of the lower left edge of the inserted + column (as a hint for routines which need to set a cursor position). + \todo unicode check + */ + void overlay_rectangular_(int startPos, int rectStart, int rectEnd, + const char* insText, int* nDeleted, + int* nInserted, int* endPos); + + /** + Calls the stored redisplay procedure(s) for this buffer to update the + screen for a change in a selection. + \todo unicode check + */ + void redisplay_selection(Fl_Text_Selection* oldSelection, + Fl_Text_Selection* newSelection) const; + + /** + \todo unicode check + */ + void move_gap(int pos); + + /** + Reallocates the text storage in the buffer to have a gap starting at \p newGapStart + and a gap size of \p newGapLen, preserving the buffer's current contents. + \todo unicode check + */ + void reallocate_with_gap(int newGapStart, int newGapLen); + + char* selection_text_(Fl_Text_Selection* sel) const; + + /** + Removes the text from the buffer corresponding to \p sel. + \todo unicode check + */ + void remove_selection_(Fl_Text_Selection* sel); + + /** + Replaces the \p text in selection \p sel. + \todo unicode check + */ + void replace_selection_(Fl_Text_Selection* sel, const char* text); + + /** + Finds the first and last character position in a line within a rectangular + selection (for copying). Includes tabs which cross rectStart, but not + control characters which do so. Leaves off tabs which cross rectEnd. + + Technically, the calling routine should convert tab characters which + cross the right boundary of the selection to spaces which line up with + the edge of the selection. Unfortunately, the additional memory + management required in the parent routine to allow for the changes + in string size is not worth all the extra work just for a couple of + shifted characters, so if a tab protrudes, just lop it off and hope + that there are other characters in the selection to establish the right + margin for subsequent columnar pastes of this data. + \todo unicode check + */ + void rectangular_selection_boundaries(int lineStartPos, int rectStart, + int rectEnd, int* selStart, + int* selEnd) const; + + /** + Updates all of the selections in the buffer for changes in the buffer's text + \todo unicode check + */ + void update_selections(int pos, int nDeleted, int nInserted); + + Fl_Text_Selection mPrimary; /**< highlighted areas */ + Fl_Text_Selection mSecondary; /**< highlighted areas */ + Fl_Text_Selection mHighlight; /**< highlighted areas */ + int mLength; /**< length of the text in the buffer (the length of the buffer itself must be calculated: gapEnd - gapStart + length) */ - char* mBuf; /**< allocated memory where the text is stored */ - int mGapStart; /**< points to the first character of the gap */ - int mGapEnd; /**< points to the first char after the gap */ - // The hardware tab distance used by all displays for this buffer, - // and used in computing offsets for rectangular selection operations. - int mTabDist; /**< equiv. number of characters in a tab */ - int mUseTabs; /**< True if buffer routines are allowed to use + char* mBuf; /**< allocated memory where the text is stored */ + int mGapStart; /**< points to the first character of the gap */ + int mGapEnd; /**< points to the first char after the gap */ + // The hardware tab distance used by all displays for this buffer, + // and used in computing offsets for rectangular selection operations. + int mTabDist; /**< equiv. number of characters in a tab */ + int mUseTabs; /**< True if buffer routines are allowed to use tabs for padding in rectangular operations */ - int mNModifyProcs; /**< number of modify-redisplay procs attached */ - Fl_Text_Modify_Cb* /**< procedures to call when buffer is */ - mModifyProcs; /**< modified to redisplay contents */ - void** mCbArgs; /**< caller arguments for modifyProcs above */ - int mNPredeleteProcs; /**< number of pre-delete procs attached */ - Fl_Text_Predelete_Cb* /**< procedure to call before text is deleted */ - mPredeleteProcs; /**< from the buffer; at most one is supported. */ - void **mPredeleteCbArgs; /**< caller argument for pre-delete proc above */ - int mCursorPosHint; /**< hint for reasonable cursor position after + int mNModifyProcs; /**< number of modify-redisplay procs attached */ + Fl_Text_Modify_Cb* /**< procedures to call when buffer is */ + mModifyProcs; /**< modified to redisplay contents */ + void** mCbArgs; /**< caller arguments for modifyProcs above */ + int mNPredeleteProcs; /**< number of pre-delete procs attached */ + Fl_Text_Predelete_Cb* /**< procedure to call before text is deleted */ + mPredeleteProcs; /**< from the buffer; at most one is supported. */ + void **mPredeleteCbArgs; /**< caller argument for pre-delete proc above */ + int mCursorPosHint; /**< hint for reasonable cursor position after a buffer modification operation */ - char mNullSubsChar; /**< NEdit is based on C null-terminated strings, - so ascii-nul characters must be substituted - with something else. This is the else, but - of course, things get quite messy when you - use it */ - char mCanUndo; /**< if this buffer is used for attributes, it must - not do any undo calls */ - int mPreferredGapSize; /**< the default allocation for the text gap is 1024 + char mCanUndo; /**< if this buffer is used for attributes, it must + not do any undo calls */ + int mPreferredGapSize; /**< the default allocation for the text gap is 1024 bytes and should only be increased if frequent and large changes in buffer size are expected */ }; @@ -322,5 +981,5 @@ class FL_EXPORT Fl_Text_Buffer { #endif // -// End of "$Id: Fl_Text_Buffer.H 6822 2009-07-04 00:24:26Z fabien $". +// End of "$Id: Fl_Text_Buffer.H 7527 2010-04-18 14:33:33Z engelsman $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Text_Display.H b/plugins/zynaddsubfx/fltk/FL/Fl_Text_Display.H index 495737718..71bbd229d 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Text_Display.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Text_Display.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Text_Display.H 6902 2009-09-27 11:06:56Z matt $" +// "$Id: Fl_Text_Display.H 7527 2010-04-18 14:33:33Z engelsman $" // // Header file for Fl_Text_Display class. // @@ -251,7 +251,7 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group { bool countLastLineMissingNewLine = true) const; void find_line_end(int pos, bool start_pos_is_line_start, int *lineEnd, int *nextLineStart) const; - int measure_proportional_character(char c, int colNum, int pos) const; + int measure_proportional_character(const char *s, int colNum, int pos) const; int wrap_uses_character(int lineEndPos) const; int range_touches_selection(const Fl_Text_Selection *sel, int rangeStart, int rangeEnd) const; @@ -340,5 +340,5 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group { #endif // -// End of "$Id: Fl_Text_Display.H 6902 2009-09-27 11:06:56Z matt $". +// End of "$Id: Fl_Text_Display.H 7527 2010-04-18 14:33:33Z engelsman $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Tree.H b/plugins/zynaddsubfx/fltk/FL/Fl_Tree.H new file mode 100644 index 000000000..94e43f6fe --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Tree.H @@ -0,0 +1,699 @@ +// +// "$Id: Fl_Tree.H 7672 2010-07-10 09:44:45Z matt $" +// + +#ifndef FL_TREE_H +#define FL_TREE_H + +#include +#include +#include +#include + +#include +#include + +////////////////////// +// FL/Fl_Tree.H +////////////////////// +// +// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK +// Copyright (C) 2009 by Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +/// +/// \file +/// \brief This file contains the definitions of the Fl_Tree class +/// + +/// \class Fl_Tree +/// +/// \brief Tree widget. +/// +/// \code +/// Fl_Tree // Top level widget +/// |--- Fl_Tree_Item // Items in the tree +/// |--- Fl_Tree_Prefs // Preferences for the tree +/// |--- Fl_Tree_Connector (enum) // Connection modes +/// |--- Fl_Tree_Select (enum) // Selection modes +/// |--- Fl_Tree_Sort (enum) // Sort behavior +/// \endcode +/// +/// An expandable tree widget. +/// +/// Similar to Fl_Browser, Fl_Tree is browser of Fl_Tree_Item's, which can be +/// in a parented hierarchy. Subtrees can be expanded or closed. Items can be +/// added, deleted, inserted, sorted and re-ordered. +/// +/// The tree items may also contain other FLTK widgets, like buttons, input fields, +/// or even "custom" widgets. +/// +/// The callback() is invoked depending on the value of when(): +/// +/// - FL_WHEN_RELEASE -- callback invoked when left mouse button is released on an item +/// - FL_WHEN_CHANGED -- callback invoked when left mouse changes selection state +/// +/// The simple way to define a tree: +/// \code +/// #include +/// [..] +/// Fl_Tree tree(X,Y,W,H); +/// tree.begin(); +/// tree.add("Flintstones/Fred"); +/// tree.add("Flintstones/Wilma"); +/// tree.add("Flintstones/Pebbles"); +/// tree.add("Simpsons/Homer"); +/// tree.add("Simpsons/Marge"); +/// tree.add("Simpsons/Bart"); +/// tree.add("Simpsons/Lisa"); +/// tree.end(); +/// \endcode +/// +/// Items can be added with Fl_Tree::add(), +/// removed with Fl_Tree::remove(), +/// inserted with Fl_Tree::insert_above(), +/// selected/deselected with Fl_Tree::select() and Fl_Tree::deselect(). +/// Items can be swapped with Fl_Tree_Item::swap_children(), sorting control via +/// Fl_Tree::sortorder(). +/// +/// The tree can have different selection behaviors controlled by Fl_Tree::selectmode(). +/// +/// FLTK and custom FLTK widgets can be assigned to tree items via Fl_Tree_Item::widget(). +/// +/// Parent nodes can be open/closed with open() and close(), icons can be assigned +/// or redefined with some or all items via +/// Fl_Tree_Item::openicon(), +/// Fl_Tree_Item::closeicon(), +/// Fl_Tree_Item::usericon(). +/// +/// Various default preferences can be manipulated via Fl_Tree_Prefs, including +/// colors, margins, connection lines. +/// +/// \image html tree-elements.png +/// +/// \todo Needs handling of callbacks when items are procedurally select()ed +/// + +class Fl_Tree : public Fl_Group { + Fl_Tree_Item *_root; // can be null! + Fl_Tree_Item *_item_clicked; + Fl_Tree_Prefs _prefs; // all the tree's settings + Fl_Scrollbar *_vscroll; + +public: + /// Find the item that was clicked. + /// You probably want to use item_clicked() instead, which is fast. + /// + /// This method walks the entire tree looking for the first item that is + /// under the mouse (ie. at Fl::event_x()/Fl:event_y(). + /// + /// Use this method /only/ if you've subclassed Fl_Tree, and are receiving + /// events before Fl_Tree has been able to process and update item_clicked(). + /// + /// \returns the item clicked, or 0 if no item was under the current event. + /// + const Fl_Tree_Item *find_clicked() const { + if ( ! _root ) return(0); + return(_root->find_clicked(_prefs)); + } +protected: + /// Set the item that was last clicked. + /// Should only be used by subclasses needing to change this value. + /// Normally Fl_Tree manages this value. + /// + void item_clicked(Fl_Tree_Item* val) { + _item_clicked = val; + } + void do_callback_for_item(Fl_Tree_Item* item) { + Fl_Tree_Item *save = _item_clicked; // save previous 'item_clicked' + _item_clicked = item; // set item_clicked to this item while we do callback + do_callback((Fl_Widget*)this, user_data()); + _item_clicked = save; // restore item_clicked + } + +public: + Fl_Tree(int X, int Y, int W, int H, const char *L=0); + ~Fl_Tree(); + int handle(int e); + void draw(); + + /////////////////////// + // root methods + /////////////////////// + + /// Set the label for the root item. + /// + /// Makes an internally managed copy of 'new_label'. + /// + void root_label(const char *new_label) { + if ( ! _root ) return; + _root->label(new_label); + } + /// Returns the root item. + Fl_Tree_Item* root() { + return(_root); + } + + //////////////////////////////// + // Item creation/removal methods + //////////////////////////////// + Fl_Tree_Item *add(const char *path); + Fl_Tree_Item* add(Fl_Tree_Item *item, const char *name); + Fl_Tree_Item *insert_above(Fl_Tree_Item *above, const char *name); + Fl_Tree_Item* insert(Fl_Tree_Item *item, const char *name, int pos); + + /// Remove the specified \p item from the tree. + /// If it has children, all those are removed too. + /// \returns 0 if done, -1 if 'item' not found. + /// + int remove(Fl_Tree_Item *item) { + if ( !item ) return(0); + if ( item == _root ) { + clear(); + } else { + Fl_Tree_Item *parent = item->parent(); // find item's parent + if ( ! parent ) return(-1); + parent->remove_child(item); // remove child + children + } + return(0); + } + /// Clear all children from the tree. + /// The tree will be left completely empty. + /// + void clear() { + if ( ! _root ) return; + _root->clear_children(); + delete _root; _root = 0; + } + /// Clear all the children of a particular node in the tree specified by \p item. + void clear_children(Fl_Tree_Item *item) { + if ( item->has_children() ) { + item->clear_children(); + redraw(); // redraw only if there were children to clear + } + } + + //////////////////////// + // Item lookup methods + //////////////////////// + Fl_Tree_Item *find_item(const char *path); + const Fl_Tree_Item *find_item(const char *path) const; + + /// Return the item that was last clicked. + /// + /// Valid only from within an Fl_Tree::callback(). + /// + /// \returns the item clicked, or 0 if none. + /// 0 may also be used to indicate several items were clicked/changed. + /// + Fl_Tree_Item *item_clicked() { + return(_item_clicked); + } + /// Returns the first item in the tree. + /// + /// Use this to walk the tree in the forward direction, eg: + /// \code + /// for ( Fl_Tree_Item *item = tree->first(); item; item = item->next() ) { + /// printf("Item: %s\n", item->label()); + /// } + /// \endcode + /// + /// \returns first item in tree, or 0 if none (tree empty). + /// + Fl_Tree_Item *first() { + return(_root); // first item always root + } + /// Returns the last item in the tree. + /// + /// Use this to walk the tree in reverse, eg: + /// + /// \code + /// for ( Fl_Tree_Item *item = tree->last(); item; item = item->prev() ) { + /// printf("Item: %s\n", item->label()); + /// } + /// \endcode + /// + /// \returns last item in the tree, or 0 if none (tree empty). + /// + Fl_Tree_Item *last() { + if ( ! _root ) return(0); + Fl_Tree_Item *item = _root; + while ( item->has_children() ) { + item = item->child(item->children()-1); + } + return(item); + } + + ////////////////////////// + // Item open/close methods + ////////////////////////// + + /// Open the specified 'item'. + /// This causes the item's children (if any) to be shown. + /// Handles redrawing if anything was actually changed. + /// + void open(Fl_Tree_Item *item) { + if ( ! item->is_open() ) { + item->open(); + redraw(); + } + } + /// Opens the item specified by \p path (eg: "Parent/child/item"). + /// This causes the item's children (if any) to be shown. + /// Handles redrawing if anything was actually changed. + /// + /// \returns + /// - 0 : OK + /// - -1 : item was not found + /// + int open(const char *path) { + Fl_Tree_Item *item = find_item(path); + if ( item ) { + open(item); + return(0); + } + return(-1); + } + /// Closes the specified \p item. + /// Handles redrawing if anything was actually changed. + /// + void close(Fl_Tree_Item *item) { + if ( ! item->is_close() ) { + item->close(); + redraw(); + } + } + /// Closes the item specified by \p path, eg: "Parent/child/item". + /// + /// Handles redrawing if anything was actually changed. + /// + /// \returns + /// - 0 -- OK + /// - -1 -- item was not found + /// + int close(const char *path) { + Fl_Tree_Item *item = find_item(path); + if ( item ) { + close(item); + return(0); + } + return(-1); + } + /// See if \p item is open. + /// + /// Items that are 'open' are themselves not necessarily visible; + /// one of the item's parents might be closed. + /// + /// \returns + /// - 1 : item is open + /// - 0 : item is closed + /// + int is_open(Fl_Tree_Item *item) const { + return(item->is_open()?1:0); + } + /// See if item specified by \p path (eg: "Parent/child/item") is open. + /// + /// Items that are 'open' are themselves not necessarily visible; + /// one of the item's parents might be closed. + /// + /// \returns + /// - 1 : item is open + /// - 0 : item is closed + /// - -1 : item was not found + /// + int is_open(const char *path) const { + const Fl_Tree_Item *item = find_item(path); + if ( item ) return(item->is_open()?1:0); + return(-1); + } + /// See if the specified \p item is closed. + /// \returns + /// - 1 : item is open + /// - 0 : item is closed + /// + int is_close(Fl_Tree_Item *item) const { + return(item->is_close()); + } + /// See if item specified by \p path (eg: "Parent/child/item") is closed. + /// + /// \returns + /// - 1 : item is closed + /// - 0 : item is open + /// - -1 : item was not found + /// + int is_close(const char *path) const { + const Fl_Tree_Item *item = find_item(path); + if ( item ) return(item->is_close()?1:0); + return(-1); + } + + ///////////////////////// + // Item selection methods + ///////////////////////// + + /// Select the specified \p item. Use 'deselect()' to de-select it. + /// Handles redrawing if anything was actually changed. + /// + /// \p docallback is an optional paramemter that can either be 0 or 1. + /// - 0 - the callback() is not invoked (default) + /// - 1 - the callback() is invoked if the item changed state, + /// and the callback can use item_clicked() to determine the selected item. + /// + void select(Fl_Tree_Item *item, int docallback=0) { + if ( ! item->is_selected() ) { + item->select(); + if ( docallback == 1 ) do_callback_for_item(item); + redraw(); + } + } + /// Select the item specified by \p path (eg: "Parent/child/item"). + /// Handles redrawing if anything was actually changed. + /// + /// \p docallback is an optional paramemter that can either be 0 or 1. + /// - 0 - the callback() is not invoked (default) + /// - 1 - the callback() is invoked if the item changed state, + /// and the callback can use item_clicked() to determine the selected item. + /// + /// \returns + /// - 0 : OK + /// - -1 : item was not found + /// + int select(const char *path, int docallback=0) { + Fl_Tree_Item *item = find_item(path); + if ( item ) { + select(item); + if ( docallback == 1 ) do_callback_for_item(item); + return(0); + } + return(-1); + } + /// Toggle the select state of the specified \p item. + /// Handles redrawing. + /// + /// \p docallback is an optional paramemter that can either be 0 or 1. + /// - 0 - the callback() is not invoked (default) + /// - 1 - the callback() is invoked, + /// and the callback can use item_clicked() to determine the selected item. + /// + void select_toggle(Fl_Tree_Item *item, int docallback=0) { + item->select_toggle(); + if ( docallback == 1 ) do_callback_for_item(item); + redraw(); + } + /// De-select the specified \p item. + /// Handles redrawing if anything was actually changed. + /// + /// \p docallback is an optional paramemter that can either be 0 or 1. + /// - 0 - the callback() is not invoked (default) + /// - 1 - the callback() is invoked if the item changed state, + /// and the callback can use item_clicked() to determine the selected item. + /// + void deselect(Fl_Tree_Item *item, int docallback=0) { + if ( item->is_selected() ) { + item->deselect(); + if ( docallback == 1 ) do_callback_for_item(item); + redraw(); + } + } + /// De-select an item specified by \p path (eg: "Parent/child/item"). + /// Handles redrawing if anything was actually changed. + /// + /// \p docallback is an optional paramemter that can either be 0 or 1. + /// - 0 - the callback() is not invoked (default) + /// - 1 - the callback() is invoked if the item changed state, + /// and the callback can use item_clicked() to determine the selected item. + /// + /// \returns + /// - 0 : OK + /// - -1 : item was not found + /// + int deselect(const char *path, int docallback=0) { + Fl_Tree_Item *item = find_item(path); + if ( item ) { + deselect(item, docallback); + return(0); + } + return(-1); + } + + int deselect_all(Fl_Tree_Item *item=0, int docallback=0); + int select_only(Fl_Tree_Item *selitem, int docallback=0); + int select_all(Fl_Tree_Item *item=0, int docallback=0); + + /// See if the specified \p item is selected. + /// \return + /// - 1 : item selected + /// - 0 : item deselected + /// + int is_selected(Fl_Tree_Item *item) const { + return(item->is_selected()?1:0); + } + /// See if item specified by \p path (eg: "Parent/child/item") is selected. + /// + /// \returns + /// - 1 : item selected + /// - 0 : item deselected + /// - -1 : item was not found + /// + int is_selected(const char *path) { + Fl_Tree_Item *item = find_item(path); + if ( item ) return(is_selected(item)); + return(-1); + } + /// Print the tree as 'ascii art' to stdout. + /// Used mainly for debugging. + /// + void show_self() { + if ( ! _root ) return; + _root->show_self(); + } + + ///////////////////////////////// + // Item attribute related methods + ///////////////////////////////// + + /// Get the default label fontsize used for creating new items. + int labelsize() const { + return(_prefs.labelsize()); + } + /// Set the default label font size used for creating new items. + /// To change the font size on a per-item basis, use Fl_Tree_Item::labelsize(int) + /// + void labelsize(int val) { + _prefs.labelsize(val); + } + + /// Get the default font face used for item's labels when new items are created. + /// + /// Don't use this if you want to change an existing label() size; use + /// item->labelfont() instead. + /// + int labelfont() const { + return(_prefs.labelfont()); + } + /// Set the default font face used for item's labels when new items are created. + /// + /// Don't use this if you want to change an existing label() size; use + /// item->labelfont(int) instead. + /// + void labelfont(int val) { + _prefs.labelfont(val); + } + /// Get the amount of white space (in pixels) that should appear + /// between the widget's left border and the tree's contents. + /// + int marginleft() const { + return(_prefs.marginleft()); + } + /// Set the amount of white space (in pixels) that should appear + /// between the widget's left border and the left side of the tree's contents. + /// + void marginleft(int val) { + _prefs.marginleft(val); + redraw(); + } + /// Get the amount of white space (in pixels) that should appear + /// between the widget's top border and the top of the tree's contents. + /// + int margintop() const { + return(_prefs.margintop()); + } + /// Sets the amount of white space (in pixels) that should appear + /// between the widget's top border and the top of the tree's contents. + /// + void margintop(int val) { + _prefs.margintop(val); + redraw(); + } + /// Get the amount of white space (in pixels) that should appear + /// below an open child tree's contents. + /// + int openchild_marginbottom() const { + return(_prefs.openchild_marginbottom()); + } + /// Set the amount of white space (in pixels) that should appear + /// below an open child tree's contents. + /// + void openchild_marginbottom(int val) { + _prefs.openchild_marginbottom(val); + redraw(); + } + /// Gets the width of the horizontal connection lines (in pixels) + /// that appear to the left of each tree item's label. + /// + int connectorwidth() const { + return(_prefs.connectorwidth()); + } + /// Sets the width of the horizontal connection lines (in pixels) + /// that appear to the left of each tree item's label. + /// + void connectorwidth(int val) { + _prefs.connectorwidth(val); + redraw(); + } + /// Returns the Fl_Image being used as the default user icon for newly created items. + /// Returns zero if no icon has been set, which is the default. + /// + Fl_Image *usericon() const { + return(_prefs.usericon()); + } + /// Sets the Fl_Image to be used as the default user icon for all + /// newly created items. + /// + /// If you want to specify user icons on a per-item basis, + /// use Fl_Tree_Item::usericon() instead. + /// + /// \param[in] val -- The new image to be used, or + /// zero to disable user icons. + /// + void usericon(Fl_Image *val) { + _prefs.usericon(val); + redraw(); + } + /// Returns the icon to be used as the 'open' icon. + /// If none was set, the internal default is returned, + /// a simple '[+]' icon. + /// + Fl_Image *openicon() const { + return(_prefs.openicon()); + } + /// Sets the icon to be used as the 'open' icon. + /// This overrides the built in default '[+]' icon. + /// + /// \param[in] val -- The new image, or zero to use the default [+] icon. + /// + void openicon(Fl_Image *val) { + _prefs.openicon(val); + redraw(); + } + /// Returns the icon to be used as the 'close' icon. + /// If none was set, the internal default is returned, + /// a simple '[-]' icon. + /// + Fl_Image *closeicon() const { + return(_prefs.closeicon()); + } + /// Sets the icon to be used as the 'close' icon. + /// This overrides the built in default '[-]' icon. + /// + /// \param[in] val -- The new image, or zero to use the default [-] icon. + /// + void closeicon(Fl_Image *val) { + _prefs.closeicon(val); + redraw(); + } + /// Returns 1 if the collapse icon is enabled, 0 if not. + int showcollapse() const { + return(_prefs.showcollapse()); + } + /// Set if we should show the collapse icon or not. + /// If collapse icons are disabled, the user will not be able + /// to interactively collapse items in the tree, unless the application + /// provides some other means via open() and close(). + /// + /// \param[in] val 1: shows collapse icons (default),\n + /// 0: hides collapse icons. + /// + void showcollapse(int val) { + _prefs.showcollapse(val); + redraw(); + } + /// Returns 1 if the root item is to be shown, or 0 if not. + int showroot() const { + return(_prefs.showroot()); + } + /// Set if the root item should be shown or not. + /// \param[in] val 1 -- show the root item (default)\n + /// 0 -- hide the root item. + /// + void showroot(int val) { + _prefs.showroot(val); + redraw(); + } + /// Returns the line drawing style for inter-connecting items. + Fl_Tree_Connector connectorstyle() const { + return(_prefs.connectorstyle()); + } + /// Sets the line drawing style for inter-connecting items. + void connectorstyle(Fl_Tree_Connector val) { + _prefs.connectorstyle(val); + redraw(); + } + /// Set the default sort order used when items are added to the tree. + /// See Fl_Tree_Sort for possible values. + /// + Fl_Tree_Sort sortorder() const { + return(_prefs.sortorder()); + } + /// Gets the sort order used to add items to the tree. + void sortorder(Fl_Tree_Sort val) { + _prefs.sortorder(val); + // no redraw().. only affects new add()itions + } + /// Sets the style of box used to draw selected items. + /// This is an fltk Fl_Boxtype. + /// The default is influenced by FLTK's current Fl::scheme() + /// + Fl_Boxtype selectbox() const { + return(_prefs.selectbox()); + } + /// Gets the style of box used to draw selected items. + /// This is an fltk Fl_Boxtype. + /// The default is influenced by FLTK's current Fl::scheme() + /// + void selectbox(Fl_Boxtype val) { + _prefs.selectbox(val); + redraw(); + } + /// Gets the tree's current selection mode. + Fl_Tree_Select selectmode() const { + return(_prefs.selectmode()); + } + /// Sets the tree's selection mode. + void selectmode(Fl_Tree_Select val) { + _prefs.selectmode(val); + } + + void load(class Fl_Preferences&); +}; + +#endif /*FL_TREE_H*/ + +// +// End of "$Id: Fl_Tree.H 7672 2010-07-10 09:44:45Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Tree_Item.H b/plugins/zynaddsubfx/fltk/FL/Fl_Tree_Item.H new file mode 100644 index 000000000..6c46c5caa --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Tree_Item.H @@ -0,0 +1,321 @@ +// +// "$Id: Fl_Tree_Item.H 6957 2009-12-08 08:39:31Z greg.ercolano $" +// + +#ifndef FL_TREE_ITEM_H +#define FL_TREE_ITEM_H + +#include +#include +#include +#include + +#include +#include + +////////////////////// +// FL/Fl_Tree_Item.H +////////////////////// +// +// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK +// Copyright (C) 2009 by Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +/// +/// \file +/// \brief This file contains the definitions for Fl_Tree_Item +/// + +/// \brief Tree item +/// +/// This class is a single tree item, and manages all of the item's attributes. +/// Fl_Tree_Item is used by Fl_Tree, which is comprised of many instances of Fl_Tree_Item. +/// +/// Fl_Tree_Item is hierarchical; it dynamically manages an Fl_Tree_Item_Array of children +/// that are themselves instances of Fl_Tree_Item. Each item can have zero or more children. +/// When an item has children, close() and open() can be used to hide or show them. +/// +/// Items have their own attributes; font size, face, color. +/// Items maintain their own hierarchy of children. +/// +/// When you make changes to items, you'll need to tell the tree to redraw() +/// for the changes to show up. +/// +class Fl_Tree_Item { + const char *_label; // label (memory managed) + int _labelfont; // label's font face + int _labelsize; // label's font size + Fl_Color _labelfgcolor; // label's fg color + Fl_Color _labelbgcolor; // label's bg color + char _open; // item is open? + char _visible; // item is visible? + char _active; // item activated? + char _selected; // item selected? + int _xywh[4]; // xywh of this widget (if visible) + int _collapse_xywh[4]; // xywh of collapse icon (if any) + int _label_xywh[4]; // xywh of label + Fl_Widget *_widget; // item's label widget (optional) + Fl_Image *_usericon; // item's user-specific icon (optional) + Fl_Tree_Item_Array _children; // array of child items + Fl_Tree_Item *_parent; // parent item (=0 if root) + void *_userdata; // user data that can be associated with an item +protected: + void show_widgets(); + void hide_widgets(); + void draw_vertical_connector(int x, int y1, int y2, const Fl_Tree_Prefs &prefs); + void draw_horizontal_connector(int x1, int x2, int y, const Fl_Tree_Prefs &prefs); +public: + Fl_Tree_Item(const Fl_Tree_Prefs &prefs); // CTOR + ~Fl_Tree_Item(); // DTOR + Fl_Tree_Item(const Fl_Tree_Item *o); // COPY CTOR + void draw(int X, int &Y, int W, Fl_Widget *tree, const Fl_Tree_Prefs &prefs, int lastchild=1); + void show_self(const char *indent = "") const; + void label(const char *val); + const char *label() const; + + /// Set a user-data value for the item. + inline void user_data( void* data ) { _userdata = data; } + + /// Retrieve the user-data value that has been assigned to the item. + inline void* user_data() const { return _userdata; } + + /// Set item's label font face. + void labelfont(int val) { + _labelfont = val; + } + /// Get item's label font face. + int labelfont() const { + return(_labelfont); + } + /// Set item's label font size. + void labelsize(int val) { + _labelsize = val; + } + /// Get item's label font size. + int labelsize() const { + return(_labelsize); + } + /// Set item's label foreground text color. + void labelfgcolor(Fl_Color val) { + _labelfgcolor = val; + } + /// Set item's label text color. + void labelcolor(Fl_Color val) { + _labelfgcolor = val; + } + /// Return item's label text color. + Fl_Color labelcolor() const { + return(_labelfgcolor); + } + /// Return item's label foreground text color. + Fl_Color labelfgcolor() const { + return(_labelfgcolor); + } + /// Set item's label background color. + void labelbgcolor(Fl_Color val) { + _labelbgcolor = val; + } + /// Return item's background text color. + Fl_Color labelbgcolor() const { + return(_labelbgcolor); + } + /// Assign an FLTK widget to this item. + void widget(Fl_Widget *val) { + _widget = val; + } + /// Return FLTK widget assigned to this item. + Fl_Widget *widget() const { + return(_widget); + } + /// Return the number of children this item has. + int children() const { + return(_children.total()); + } + /// Return the child item for the given 'index'. + Fl_Tree_Item *child(int index) { + return(_children[index]); + } + /// Return the const child item for the given 'index'. + const Fl_Tree_Item *child(int t) const; + /// See if this item has children. + int has_children() const { + return(children()); + } + int find_child(const char *name); + int find_child(Fl_Tree_Item *item); + int remove_child(Fl_Tree_Item *item); + int remove_child(const char *new_label); + void clear_children(); + void swap_children(int ax, int bx); + int swap_children(Fl_Tree_Item *a, Fl_Tree_Item *b); + const Fl_Tree_Item *find_item(char **arr) const; + Fl_Tree_Item *find_item(char **arr); + ////////////////// + // Adding items + ////////////////// + Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs, const char *new_label); + Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs, char **arr); + Fl_Tree_Item *insert(const Fl_Tree_Prefs &prefs, const char *new_label, int pos=0); + Fl_Tree_Item *insert_above(const Fl_Tree_Prefs &prefs, const char *new_label); + int depth() const; + Fl_Tree_Item *prev(); + Fl_Tree_Item *next(); + + /// Return the parent for this item. + Fl_Tree_Item *parent() { + return(_parent); + } + /// Return the const parent for this item. + const Fl_Tree_Item *parent() const { + return(_parent); + } + /// Set the parent for this item. + /// Should only be used by Fl_Tree's internals. + /// + void parent(Fl_Tree_Item *val) { + _parent = val; + } + ////////////////// + // State + ////////////////// + void open(); + void close(); + /// See if the item is 'open'. + int is_open() const { + return(_open?1:0); + } + /// See if the item is 'closed'. + int is_close() const { + return(_open?0:1); + } + /// Toggle the item's open/closed state. + void open_toggle() { + _open?close():open(); + } + /// Change the item's selection state to the optionally specified 'val'. + /// If 'val' is not specified, the item will be selected. + /// + void select(int val=1) { + _selected = val; + } + /// Toggle the item's selection state. + void select_toggle() { + if ( is_selected() ) { + deselect(); // deselect if selected + } else { + select(); // select if deselected + } + } + /// Select self and all children + /// Returns count of how many items were in the 'deselected' state, + /// ie. how many items were "changed". + /// + int select_all() { + int count = 0; + if ( ! is_selected() ) { + select(); + ++count; + } + for ( int t=0; tselect_all(); + } + return(count); + } + /// Disable the item's selection state. + void deselect() { + _selected = 0; + } + /// Deselect self and all children + /// Returns count of how many items were in the 'selected' state, + /// ie. how many items were "changed". + /// + int deselect_all() { + int count = 0; + if ( is_selected() ) { + deselect(); + ++count; + } + for ( int t=0; tdeselect_all(); + } + return(count); + } + /// See if the item is selected. + char is_selected() const { + return(_selected); + } + /// Change the item's activation state to the optionally specified 'val'. + /// + /// When deactivated, the item will be 'grayed out'; the callback() + /// won't be invoked if the user clicks on the label. If the item + /// has a widget() associated with the item, its activation state + /// will be changed as well. + /// + /// If 'val' is not specified, the item will be activated. + /// + void activate(int val=1) { + _active = val; + if ( _widget && val != (int)_widget->active() ) { + if ( val ) { + _widget->activate(); + } else { + _widget->deactivate(); + } + _widget->redraw(); + } + } + /// Deactivate the item; the callback() won't be invoked when clicked. + /// Same as activate(0) + /// + void deactivate() { + activate(0); + } + /// See if the item is activated. + char is_activated() const { + return(_active); + } + /// See if the item is activated. + char is_active() const { + return(_active); + } + /// Set the user icon's image. '0' will disable. + void usericon(Fl_Image *val) { + _usericon = val; + } + /// Get the user icon. Returns '0' if disabled. + Fl_Image *usericon() const { + return(_usericon); + } + ////////////////// + // Events + ////////////////// + const Fl_Tree_Item *find_clicked(const Fl_Tree_Prefs &prefs) const; + Fl_Tree_Item *find_clicked(const Fl_Tree_Prefs &prefs); + int event_on_collapse_icon(const Fl_Tree_Prefs &prefs) const; + int event_on_label(const Fl_Tree_Prefs &prefs) const; + /// Is this item the root of the tree? + int is_root() const { + return(_parent==0?1:0); + } +}; + +#endif /*FL_TREE_ITEM_H*/ + +// +// End of "$Id: Fl_Tree_Item.H 6957 2009-12-08 08:39:31Z greg.ercolano $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Tree_Item_Array.H b/plugins/zynaddsubfx/fltk/FL/Fl_Tree_Item_Array.H new file mode 100644 index 000000000..f1d2834ba --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Tree_Item_Array.H @@ -0,0 +1,88 @@ +// +// "$Id: Fl_Tree_Item_Array.H 6956 2009-12-08 08:06:44Z greg.ercolano $" +// + +#ifndef _FL_TREE_ITEM_ARRAY_H +#define _FL_TREE_ITEM_ARRAY_H + +class Fl_Tree_Item; // forward decl must *precede* first doxygen comment block + // or doxygen will not document our class.. + +////////////////////////// +// FL/Fl_Tree_Item_Array.H +////////////////////////// +// +// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK +// Copyright (C) 2009 by Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +/// +/// \file +/// \brief This file defines a class that manages an array of Fl_Tree_Item pointers. +/// + +/// \brief Manages an array of Fl_Tree_Item pointers. +/// +/// Because FLTK 1.x.x. has mandated that templates and STL not be used, +/// we use this class to dynamically manage the arrays. +/// +/// None of the methods do range checking on index values; the caller +/// must be sure that index values are within the range 0Once you create a window, you usually add children Fl_Widget - 's to it by using window->add(child) for each new widget. See Fl_Group for more information - on how to add and remove children.

-

There are several subclasses of Fl_Window that provide - double-buffering, overlay, menu, and OpenGL support.

-

The window's callback is done if the user tries to close a window - using the window manager and - Fl::modal() is zero or equal to the window. Fl_Window - has a default callback that calls Fl_Window::hide(). + + Once you create a window, you usually add children Fl_Widget + 's to it by using window->add(child) for each new widget. + See Fl_Group for more information on how to add and remove children. + + There are several subclasses of Fl_Window that provide + double-buffering, overlay, menu, and OpenGL support. + + The window's callback is done if the user tries to close a window + using the window manager and Fl::modal() is zero or equal to the + window. Fl_Window has a default callback that calls Fl_Window::hide(). */ class FL_EXPORT Fl_Window : public Fl_Group { @@ -77,20 +79,42 @@ class FL_EXPORT Fl_Window : public Fl_Group { protected: - /** Stores the last window that was made current. See current() const */ + /** Stores the last window that was made current. See current() const */ static Fl_Window *current_; virtual void draw(); /** Forces the window to be drawn, this window is also made current and calls draw(). */ virtual void flush(); + /** + Sets an internal flag that tells FLTK and the window manager to + honor position requests. + + This is used internally and should not be needed by user code. + + \param[in] force 1 to set the FORCE_POSITION flag, 0 to clear it + */ + void force_position(int force) { + if (force) set_flag(FORCE_POSITION); + else clear_flag(FORCE_POSITION); + } + /** + Returns the internal state of the window's FORCE_POSITION flag. + + \retval 1 if flag is set + \retval 0 otherwise + + \see force_position(int) + */ + int force_position() const { return ((flags() & FORCE_POSITION)?1:0); } + public: /** Creates a window from the given size and title. If Fl_Group::current() is not NULL, the window is created as a - subwindow of the parent window.

+ subwindow of the parent window. -

The first form of the constructor creates a top-level window + The first form of the constructor creates a top-level window and asks the window manager to position the window. The second form of the constructor either creates a subwindow or a top-level window at the specified location (x,y) , subject to window @@ -99,28 +123,31 @@ public: or allow the user to pick a location. Use position(x,y) or hotspot() before calling show() to request a position on the screen. See Fl_Window::resize() - for some more details on positioning windows.

+ for some more details on positioning windows. -

Top-level windows initially have visible() set to 0 + Top-level windows initially have visible() set to 0 and parent() set to NULL. Subwindows initially have visible() set to 1 and parent() set to - the parent window pointer.

+ the parent window pointer. -

Fl_Widget::box() defaults to FL_FLAT_BOX. If you - plan to completely fill the window with children widgets you should + Fl_Widget::box() defaults to FL_FLAT_BOX. If you plan to + completely fill the window with children widgets you should change this to FL_NO_BOX. If you turn the window border off you may want to change this to FL_UP_BOX. + + \see Fl_Window(int x, int y, int w, int h, const char* title = 0) */ Fl_Window(int w, int h, const char* title= 0); - /** Creates a window from the given position, size and title. - See Fl_Window::Fl_Window(int w, int h, const char *title = 0) + /** Creates a window from the given position, size and title. + + \see Fl_Window::Fl_Window(int w, int h, const char *title = 0) */ Fl_Window(int x, int y, int w, int h, const char* title = 0); /** The destructor also deletes all the children. This allows a whole tree to be deleted at once, without having to keep a pointer to all the children in the user code. A kludge has been done so the - Fl_Window and all of it's children can be automatic (local) + Fl_Window and all of its children can be automatic (local) variables, but you must declare the Fl_Window first so that it is destroyed last. */ @@ -129,16 +156,16 @@ public: virtual int handle(int); /** - Changes the size and position of the window. If shown() is - true, these changes are communicated to the window server (which may + Changes the size and position of the window. If shown() is true, + these changes are communicated to the window server (which may refuse that size and cause a further resize). If shown() is false, the size and position are used when show() is called. - See Fl_Group for the effect - of resizing on the child widgets. -

You can also call the Fl_Widget methods size(x,y) - and position(w,h), which are inline wrappers for this virtual - function.

-

A top-level window can not force, but merely suggest a position and + See Fl_Group for the effect of resizing on the child widgets. + + You can also call the Fl_Widget methods size(x,y) and position(w,h), + which are inline wrappers for this virtual function. + + A top-level window can not force, but merely suggest a position and size to the operating system. The window manager may not be willing or able to display a window at the desired position or with the given dimensions. It is up to the application developer to verify window @@ -146,21 +173,21 @@ public: */ virtual void resize(int,int,int,int); /** - Gets or sets whether or not the window manager border is around the - window. The default value is true. border(n) can be used to - turn the border on and off, and returns non-zero if the value has been - changed. Under most X window managers this does not work after - show() has been called, although SGI's 4DWM does work. + Sets whether or not the window manager border is around the + window. The default value is true. void border(int) can be + used to turn the border on and off. Under most X window + managers this does not work after show() has been called, + although SGI's 4DWM does work. */ void border(int b); /** - Fast inline function to turn the border + Fast inline function to turn the window manager border off. It only works before show() is called. */ void clear_border() {set_flag(NOBORDER);} - /** See int Fl_Window::border(int) */ + /** See void Fl_Window::border(int) */ unsigned int border() const {return !(flags() & NOBORDER);} - /** Activate the flags NOBORDER|FL_OVERRIDE */ + /** Activates the flags NOBORDER|FL_OVERRIDE */ void set_override() {set_flag(NOBORDER|OVERRIDE);} /** Returns non zero if FL_OVERRIDE flag is set, 0 otherwise. */ unsigned int override() const { return flags()&OVERRIDE; } @@ -170,8 +197,7 @@ public: remain on top of the other windows (if the X window manager supports the "transient for" property). Several modal windows may be shown at once, in which case only the last one shown gets events. You can see - which window (if any) is modal by calling - Fl::modal(). + which window (if any) is modal by calling Fl::modal(). */ void set_modal() {set_flag(MODAL);} /** Returns true if this window is modal. */ @@ -188,14 +214,14 @@ public: /** Marks the window as a menu window. - + This is intended for internal use, but it can also be used if you write your own menu handling. However, this is not recommended. This flag is used for correct "parenting" of windows in communication with the windowing system. Modern X window managers can use different flags to distinguish menu and tooltip windows from normal windows. - + This must be called before the window is shown and cannot be changed later. */ @@ -206,14 +232,14 @@ public: /** Marks the window as a tooltip window. - + This is intended for internal use, but it can also be used if you write your own tooltip handling. However, this is not recommended. This flag is used for correct "parenting" of windows in communication with the windowing system. Modern X window managers can use different flags to distinguish menu and tooltip windows from normal windows. - + This must be called before the window is shown and cannot be changed later. @@ -226,8 +252,8 @@ public: unsigned int tooltip_window() const {return flags() & TOOLTIP_WINDOW;} /** - Position the window so that the mouse is pointing at the - given position, or at the center of the given widget, which may be the + Positions the window so that the mouse is pointing at the given + position, or at the center of the given widget, which may be the window itself. If the optional offscreen parameter is non-zero, then the window is allowed to extend off the screen (this does not work with some X window managers). \see position() @@ -237,43 +263,49 @@ public: void hotspot(const Fl_Widget*, int offscreen = 0); /** See void Fl_Window::hotspot(int x, int y, int offscreen = 0) */ void hotspot(const Fl_Widget& p, int offscreen = 0) {hotspot(&p,offscreen);} + /** - Undoes the effect of a previous resize() or show() - so that the next time show() is called the window manager is - free to position the window. + Undoes the effect of a previous resize() or show() so that the next time + show() is called the window manager is free to position the window. + + This is for Forms compatibility only. + + \deprecated please use force_position(0) instead */ void free_position() {clear_flag(FORCE_POSITION);} /** - Set the allowable range the user can resize this window to. This only - works for top-level windows. + Sets the allowable range the user can resize this window to. + This only works for top-level windows.

    -
  • minw and minh are the smallest the window can - be. Either value must be greater than 0.
  • -
  • maxw and maxh are the largest the window can be. - If either is equal to the minimum then you cannot resize in - that direction. If either is zero then FLTK picks a maximum size in - that direction such that the window will fill the screen.
  • -
  • dw and dh are size increments. The window will - be constrained to widths of minw + N * dw, where N - is any non-negative integer. If these are less or equal to 1 they - are ignored. (this is ignored on WIN32)
  • -
  • aspect is a flag that indicates that the window should - preserve it's aspect ratio. This only works if both the maximum and - minimum have the same aspect ratio. (ignored on WIN32 and by many X - window managers)
  • +
  • minw and minh are the smallest the window can be. + Either value must be greater than 0.
  • +
  • maxw and maxh are the largest the window can be. If either is + equal to the minimum then you cannot resize in that direction. + If either is zero then FLTK picks a maximum size in that direction + such that the window will fill the screen.
  • +
  • dw and dh are size increments. The window will be constrained + to widths of minw + N * dw, where N is any non-negative integer. + If these are less or equal to 1 they are ignored (this is ignored + on WIN32).
  • +
  • aspect is a flag that indicates that the window should preserve its + aspect ratio. This only works if both the maximum and minimum have + the same aspect ratio (ignored on WIN32 and by many X window managers). +
+ If this function is not called, FLTK tries to figure out the range from the setting of resizable():
    -
  • If resizable() is NULL (this is the default) - then the window cannot be resized and the resize border and max-size - control will not be displayed for the window.
  • -
  • If either dimension of resizable() is less than 100, - then that is considered the minimum size. Otherwise the - resizable() has a minimum size of 100.
  • -
  • If either dimension of resizable() is zero, then that is - also the maximum size (so the window cannot resize in that direction).
  • +
  • If resizable() is NULL (this is the default) then the window cannot + be resized and the resize border and max-size control will not be + displayed for the window.
  • +
  • If either dimension of resizable() is less than 100, then that is + considered the minimum size. Otherwise the resizable() has a minimum + size of 100.
  • +
  • If either dimension of resizable() is zero, then that is also the + maximum size (so the window cannot resize in that direction).
+ It is undefined what happens if the current size does not fit in the constraints passed to size_range(). */ @@ -284,11 +316,11 @@ public: const char* label() const {return Fl_Widget::label();} /** See void Fl_Window::iconlabel(const char*) */ const char* iconlabel() const {return iconlabel_;} - /** Sets the window title bar label. */ + /** Sets the window title bar label. */ void label(const char*); /** Sets the icon label. */ void iconlabel(const char*); - /** Gets or sets the icon label. */ + /** Sets the icon label. */ void label(const char* label, const char* iconlabel); // platform dependent void copy_label(const char* a); /** See void Fl_Window::xclass(const char*) */ @@ -301,36 +333,38 @@ public: the second one if the first is 'x'. Thus "foo" turns into "foo, Foo", and "xprog.1" turns into "xprog, XProg".
This only works if called before calling show(). -

Under Microsoft Windows this string is used as the name of the + + Under Microsoft Windows this string is used as the name of the WNDCLASS structure, though it is not clear if this can have any visible effect. The passed pointer is stored unchanged. The string is not copied. */ void xclass(const char* c) {xclass_ = c;} - /** Gets the current icon window target dependent data */ + /** Gets the current icon window target dependent data. */ const void* icon() const {return icon_;} - /** Sets the current icon window target dependent data */ + /** Sets the current icon window target dependent data. */ void icon(const void * ic) {icon_ = ic;} /** Returns non-zero if show() has been called (but not hide() - ). You can tell if a window is iconified with (w->shown() - &!w->visible()). + ). You can tell if a window is iconified with (w->shown() + && !w->visible()). */ int shown() {return i != 0;} /** - Put the window on the screen. Usually this has the side effect of - opening the display. The second form is used for top-level - windows and allow standard arguments to be parsed from the + Puts the window on the screen. Usually (on X) this has the side + effect of opening the display. The second form is used for top-level + windows and allows standard arguments to be parsed from the command-line. -

If the window is already shown then it is restored and raised to the + + If the window is already shown then it is restored and raised to the top. This is really convenient because your program can call show() at any time, even if the window is already up. It also means that show() serves the purpose of raise() in other toolkits. */ virtual void show(); /** - Remove the window from the screen. If the window is already hidden or + Removes the window from the screen. If the window is already hidden or has not been shown then this does nothing and is harmless. */ virtual void hide(); @@ -353,11 +387,14 @@ public: Iconifies the window. If you call this when shown() is false it will show() it as an icon. If the window is already iconified this does nothing. -

Call show() to restore the window.

-

When a window is iconified/restored (either by these calls or by the + + Call show() to restore the window. + + When a window is iconified/restored (either by these calls or by the user) the handle() method is called with FL_HIDE and - FL_SHOW events and visible() is turned on and off.

-

There is no way to control what is drawn in the icon except with the + FL_SHOW events and visible() is turned on and off. + + There is no way to control what is drawn in the icon except with the string passed to Fl_Window::xclass(). You should not rely on window managers displaying the icons. */ @@ -368,28 +405,37 @@ public: static Fl_Window *current(); /** - Sets things up so that the drawing functions in <FL/fl_draw.H> will go into this - window. This is useful for incremental update of windows, such as in an - idle callback, which will make your program behave much better if it - draws a slow graphic. Danger: incremental update is very hard to + Sets things up so that the drawing functions in will go + into this window. This is useful for incremental update of windows, such + as in an idle callback, which will make your program behave much better + if it draws a slow graphic. Danger: incremental update is very hard to debug and maintain! -

This method only works for the Fl_Window and - Fl_Gl_Window derived classes. + + This method only works for the Fl_Window and Fl_Gl_Window derived classes. */ void make_current(); + /** Returns an Fl_Window pointer if this widget is an Fl_Window. + + \retval NULL if this widget is not derived from Fl_Window. + \note This method is provided to avoid dynamic_cast. + \todo More documentation ... + */ + virtual Fl_Window* as_window() { return this; } + // for back-compatibility only: /** Changes the cursor for this window. This always calls the system, if you are changing the cursor a lot you may want to keep track of how - you set it in a static varaible and call this only if the new cursor - is different. + you set it in a static variable and call this only if the new cursor + is different. -

The type Fl_Cursor is an enumeration defined in <Enumerations.H>. + The type Fl_Cursor is an enumeration defined in . (Under X you can get any XC_cursor value by passing Fl_Cursor((XC_foo/2)+1)). The colors only work on X, they are not implemented on WIN32. -

For back compatibility only. + + For back compatibility only. */ void cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE); // platform dependent void default_cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE); @@ -400,5 +446,5 @@ public: #endif // -// End of "$Id: Fl_Window.H 6907 2009-09-28 14:34:52Z matt $". +// End of "$Id: Fl_Window.H 7280 2010-03-16 22:51:31Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Xutf8.h b/plugins/zynaddsubfx/fltk/FL/Xutf8.h index f8815287b..b4009bd6e 100644 --- a/plugins/zynaddsubfx/fltk/FL/Xutf8.h +++ b/plugins/zynaddsubfx/fltk/FL/Xutf8.h @@ -1,4 +1,4 @@ -/* "$Id: $" +/* "$Id: Xutf8.h 6942 2009-11-18 12:22:51Z AlbrechtS $" * * Author: Jean-Marc Lienher ( http://oksid.ch ) * Copyright 2000-2003 by O'ksi'D. @@ -172,5 +172,5 @@ XUtf8Toupper( #endif /* - * End of "$Id: $". + * End of "$Id: Xutf8.h 6942 2009-11-18 12:22:51Z AlbrechtS $". */ diff --git a/plugins/zynaddsubfx/fltk/FL/dirent.h b/plugins/zynaddsubfx/fltk/FL/dirent.h index 5261b2c52..764a4cba4 100644 --- a/plugins/zynaddsubfx/fltk/FL/dirent.h +++ b/plugins/zynaddsubfx/fltk/FL/dirent.h @@ -1,5 +1,5 @@ // -// "$Id: dirent.h 6614 2009-01-01 16:11:32Z matt $" +// "$Id: dirent.h 7504 2010-04-14 20:17:44Z matt $" // // Directory header file for the Fast Light Tool Kit (FLTK). // @@ -25,9 +25,10 @@ // http://www.fltk.org/str.php // + // this file is for back-compatability only #include "filename.H" // -// End of "$Id: dirent.h 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: dirent.h 7504 2010-04-14 20:17:44Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/filename.H b/plugins/zynaddsubfx/fltk/FL/filename.H index e70e3dac3..7c0187926 100644 --- a/plugins/zynaddsubfx/fltk/FL/filename.H +++ b/plugins/zynaddsubfx/fltk/FL/filename.H @@ -1,5 +1,5 @@ /* - * "$Id: filename.H 6716 2009-03-24 01:40:44Z fabien $" + * "$Id: filename.H 7504 2010-04-14 20:17:44Z matt $" * * Filename header file for the Fast Light Tool Kit (FLTK). * @@ -25,6 +25,12 @@ * http://www.fltk.org/str.php */ +// Xcode on OS X includes files by recursing down into directories. +// This code catches the cycle and directly includes the required file. +#ifdef fl_dirent_h_cyclic_include +# include "/usr/include/dirent.h" +#endif + #ifndef FL_FILENAME_H # define FL_FILENAME_H @@ -34,9 +40,23 @@ @{ */ # define FL_PATH_MAX 256 /**< all path buffers should use this length */ -/** Gets the file name from a path. \return a pointer to the char after the last slash, or to \p filename if there is none. */ +/** Gets the file name from a path. + Similar to basename(3), exceptions shown below. + \code + #include + [..] + const char *out; + out = fl_filename_name("/usr/lib"); // out="lib" + out = fl_filename_name("/usr/"); // out="" (basename(3) returns "usr" instead) + out = fl_filename_name("/usr"); // out="usr" + out = fl_filename_name("/"); // out="" (basename(3) returns "/" instead) + out = fl_filename_name("."); // out="." + out = fl_filename_name(".."); // out=".." + \endcode + \return a pointer to the char after the last slash, or to \p filename if there is none. + */ FL_EXPORT const char *fl_filename_name(const char * filename); -FL_EXPORT const char *fl_filename_ext(const char *); +FL_EXPORT const char *fl_filename_ext(const char *buf); FL_EXPORT char *fl_filename_setext(char *to, int tolen, const char *ext); FL_EXPORT int fl_filename_expand(char *to, int tolen, const char *from); FL_EXPORT int fl_filename_absolute(char *to, int tolen, const char *from); @@ -60,17 +80,6 @@ inline int fl_filename_relative(char *to, const char *from) { return fl_filename struct dirent {char d_name[1];}; -# elif defined(__APPLE__) && defined(__PROJECTBUILDER__) - -/* Apple's ProjectBuilder has the nasty habit of including recursively - * down the file tree. To avoid re-including we must - * directly include the systems math file. (Plus, I could not find a - * predefined macro for ProjectBuilder builds, so we have to define it - * in the project) - */ -# include -# include "/usr/include/dirent.h" - # elif defined(__WATCOMC__) # include # include @@ -91,7 +100,9 @@ struct dirent {char d_name[1];}; * It would be best to create a file that does this... */ # include +# define fl_dirent_h_cyclic_include # include +# undef fl_dirent_h_cyclic_include # endif # if defined (__cplusplus) @@ -161,5 +172,5 @@ int _fl_filename_isdir_quick(const char *name); /** @} */ /* - * End of "$Id: filename.H 6716 2009-03-24 01:40:44Z fabien $". + * End of "$Id: filename.H 7504 2010-04-14 20:17:44Z matt $". */ diff --git a/plugins/zynaddsubfx/fltk/FL/fl_draw.H b/plugins/zynaddsubfx/fltk/FL/fl_draw.H index 69ecaf49c..e515b1c35 100644 --- a/plugins/zynaddsubfx/fltk/FL/fl_draw.H +++ b/plugins/zynaddsubfx/fltk/FL/fl_draw.H @@ -1,5 +1,5 @@ // -// "$Id: fl_draw.H 6878 2009-09-17 22:12:24Z matt $" +// "$Id: fl_draw.H 7659 2010-07-01 13:21:32Z manolo $" // // Portable drawing function header file for the Fast Light Tool Kit (FLTK). // @@ -35,6 +35,7 @@ #include "Enumerations.H" // for the color names #include "Fl_Window.H" // for fl_set_spot() +#include "Fl_Device.H" // Image class... class Fl_Image; @@ -45,11 +46,32 @@ FL_EXPORT extern char fl_draw_shortcut; /** \addtogroup fl_attributes @{ */ + // Colors: -FL_EXPORT void fl_color(Fl_Color i); // select indexed color +/** + Sets the color for all subsequent drawing operations. + For colormapped displays, a color cell will be allocated out of + \p fl_colormap the first time you use a color. If the colormap fills up + then a least-squares algorithm is used to find the closest color. + If no valid graphical context (fl_gc) is available, + the foreground is not set for the current window. + \param[in] c color + */ +inline void fl_color(Fl_Color c) {fl_graphics_driver->color(c); }; // select indexed color /** for back compatibility - use fl_color(Fl_Color c) instead */ inline void fl_color(int c) {fl_color((Fl_Color)c);} -FL_EXPORT void fl_color(uchar r, uchar g, uchar b); // select actual color +/** + Set the color for all subsequent drawing operations. + The closest possible match to the RGB color is used. + The RGB color is used directly on TrueColor displays. + For colormap visuals the nearest index in the gray + ramp or color cube is used. + If no valid graphical context (fl_gc) is available, + the foreground is not set for the current window. + \param[in] r,g,b color components + */ +inline void fl_color(uchar r, uchar g, uchar b) {fl_graphics_driver->color(r,g,b); }; // select actual color +/** \brief The current color */ extern FL_EXPORT Fl_Color fl_color_; /** Returns the last fl_color() that was set. @@ -62,19 +84,103 @@ inline Fl_Color fl_color() {return fl_color_;} @{ */ // clip: -FL_EXPORT void fl_push_clip(int x, int y, int w, int h); +/** + Intersects the current clip region with a rectangle and pushes this + new region onto the stack. + \param[in] x,y,w,h position and size + */ +inline void fl_push_clip(int x, int y, int w, int h) {fl_graphics_driver->push_clip(x,y,w,h); }; /** The fl_clip() name is deprecated and will be removed from future releases */ #define fl_clip fl_push_clip -FL_EXPORT void fl_push_no_clip(); -FL_EXPORT void fl_pop_clip(); -FL_EXPORT int fl_not_clipped(int x, int y, int w, int h); -FL_EXPORT int fl_clip_box(int, int, int, int, int& x, int& y, int& w, int& h); +/** + Pushes an empty clip region onto the stack so nothing will be clipped. + */ +inline void fl_push_no_clip() {fl_graphics_driver->push_no_clip(); }; +/** + Restores the previous clip region. + + You must call fl_pop_clip() once for every time you call fl_push_clip(). + Unpredictable results may occur if the clip stack is not empty when + you return to FLTK. + */ +inline void fl_pop_clip() {fl_graphics_driver->pop_clip(); }; +/** + Does the rectangle intersect the current clip region? + \param[in] x,y,w,h position and size of rectangle + \returns non-zero if any of the rectangle intersects the current clip + region. If this returns 0 you don't have to draw the object. + + \note + Under X this returns 2 if the rectangle is partially clipped, + and 1 if it is entirely inside the clip region. + */ +inline int fl_not_clipped(int x, int y, int w, int h) {return fl_graphics_driver->not_clipped(x,y,w,h); }; +/** + Intersects the rectangle with the current clip region and returns the + bounding box of the result. + + Returns non-zero if the resulting rectangle is different to the original. + This can be used to limit the necessary drawing to a rectangle. + \p W and \p H are set to zero if the rectangle is completely outside + the region. + \param[in] x,y,w,h position and size of rectangle + \param[out] X,Y,W,H position and size of resulting bounding box. + \p W and \p H are set to zero if the rectangle is + completely outside the region. + \returns Non-zero if the resulting rectangle is different to the original. + */ +inline int fl_clip_box(int x , int y, int w, int h, int& X, int& Y, int& W, int& H) + {return fl_graphics_driver->clip_box(x,y,w,h,X,Y,W,H); }; +/** Undoes any clobbering of clip done by your program */ +extern void fl_restore_clip(); +/** + Replaces the top of the clipping stack with a clipping region of any shape. + + Fl_Region is an operating system specific type. + \param[in] r clipping region + */ +FL_EXPORT void fl_clip_region(Fl_Region r); +/** + returns the current clipping region. + */ +extern Fl_Region fl_clip_region(); + // points: -FL_EXPORT void fl_point(int x, int y); +/** + Draws a single pixel at the given coordinates + */ +inline void fl_point(int x, int y) { fl_graphics_driver->point(x,y); }; // line type: -FL_EXPORT void fl_line_style(int style, int width=0, char* dashes=0); +/** + Sets how to draw lines (the "pen"). + If you change this it is your responsibility to set it back to the default + using \c fl_line_style(0). + + \param[in] style A bitmask which is a bitwise-OR of a line style, a cap + style, and a join style. If you don't specify a dash type you + will get a solid line. If you don't specify a cap or join type + you will get a system-defined default of whatever value is + fastest. + \param[in] width The thickness of the lines in pixels. Zero results in the + system defined default, which on both X and Windows is somewhat + different and nicer than 1. + \param[in] dashes A pointer to an array of dash lengths, measured in pixels. + The first location is how long to draw a solid portion, the next + is how long to draw the gap, then the solid, etc. It is terminated + with a zero-length entry. A \c NULL pointer or a zero-length + array results in a solid line. Odd array sizes are not supported + and result in undefined behavior. + + \note Because of how line styles are implemented on Win32 systems, + you \e must set the line style \e after setting the drawing + color. If you set the color after the line style you will lose + the line style settings. + \note The \p dashes array does not work under Windows 95, 98 or Me, + since those operating systems do not support complex line styles. + */ +inline void fl_line_style(int style, int width=0, char* dashes=0) {fl_graphics_driver->line_style(style,width,dashes); }; enum { FL_SOLID = 0, ///< line style: ___________ FL_DASH = 1, ///< line style: _ _ _ _ _ _ @@ -92,11 +198,19 @@ enum { }; // rectangles tweaked to exactly fill the pixel rectangle: -FL_EXPORT void fl_rect(int x, int y, int w, int h); -/** Draws a 1-pixel border \e inside the given bounding box */ + +/** + Draws a 1-pixel border \e inside the given bounding box. + This function is meant for quick drawing of simple boxes. The behavior is + undefined for line widths that are not 1. + */ +inline void fl_rect(int x, int y, int w, int h) { fl_graphics_driver->rect(x,y,w,h); }; + +/** Draws with passed color a 1-pixel border \e inside the given bounding box */ inline void fl_rect(int x, int y, int w, int h, Fl_Color c) {fl_color(c); fl_rect(x,y,w,h);} -FL_EXPORT void fl_rectf(int x, int y, int w, int h); -/** Colors a rectangle that exactly fills the given bounding box */ +/** Colors with current color a rectangle that exactly fills the given bounding box */ +inline void fl_rectf(int x, int y, int w, int h) { fl_graphics_driver->rectf(x,y,w,h); }; +/** Colors with passsed color a rectangle that exactly fills the given bounding box */ inline void fl_rectf(int x, int y, int w, int h, Fl_Color c) {fl_color(c); fl_rectf(x,y,w,h);} /** @@ -109,30 +223,104 @@ inline void fl_rectf(int x, int y, int w, int h, Fl_Color c) {fl_color(c); fl_re FL_EXPORT void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b); // line segments: -FL_EXPORT void fl_line(int x, int y, int x1, int y1); -FL_EXPORT void fl_line(int x, int y, int x1, int y1, int x2, int y2); +/** + Draws a line from (x,y) to (x1,y1) + */ +inline void fl_line(int x, int y, int x1, int y1) {fl_graphics_driver->line(x,y,x1,y1); }; +/** + Draws a line from (x,y) to (x1,y1) and another from (x1,y1) to (x2,y2) + */ +inline void fl_line(int x, int y, int x1, int y1, int x2, int y2) {fl_graphics_driver->line(x,y,x1,y1,x2,y2); }; // closed line segments: -FL_EXPORT void fl_loop(int x, int y, int x1, int y1, int x2, int y2); -FL_EXPORT void fl_loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3); +/** + Outlines a 3-sided polygon with lines + */ +inline void fl_loop(int x, int y, int x1, int y1, int x2, int y2) {fl_graphics_driver->loop(x,y,x1,y1,x2,y2); }; +/** + Outlines a 4-sided polygon with lines + */ +inline void fl_loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) + {fl_graphics_driver->loop(x,y,x1,y1,x2,y2,x3,y3); }; // filled polygons -FL_EXPORT void fl_polygon(int x, int y, int x1, int y1, int x2, int y2); -FL_EXPORT void fl_polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3); +/** + Fills a 3-sided polygon. The polygon must be convex. + */ +inline void fl_polygon(int x, int y, int x1, int y1, int x2, int y2) {fl_graphics_driver->polygon(x,y,x1,y1,x2,y2); }; +/** + Fills a 4-sided polygon. The polygon must be convex. + */ +inline void fl_polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) + { fl_graphics_driver->polygon(x,y,x1,y1,x2,y2,x3,y3); }; // draw rectilinear lines, horizontal segment first: -FL_EXPORT void fl_xyline(int x, int y, int x1); -FL_EXPORT void fl_xyline(int x, int y, int x1, int y2); -FL_EXPORT void fl_xyline(int x, int y, int x1, int y2, int x3); +/** + Draws a horizontal line from (x,y) to (x1,y) + */ +inline void fl_xyline(int x, int y, int x1) {fl_graphics_driver->xyline(x,y,x1);}; +/** + Draws a horizontal line from (x,y) to (x1,y), then vertical from (x1,y) to (x1,y2) + */ +inline void fl_xyline(int x, int y, int x1, int y2) {fl_graphics_driver->xyline(x,y,x1,y2);}; +/** + Draws a horizontal line from (x,y) to (x1,y), then a vertical from (x1,y) to (x1,y2) + and then another horizontal from (x1,y2) to (x3,y2) + */ +inline void fl_xyline(int x, int y, int x1, int y2, int x3) {fl_graphics_driver->xyline(x,y,x1,y2,x3);}; // draw rectilinear lines, vertical segment first: -FL_EXPORT void fl_yxline(int x, int y, int y1); -FL_EXPORT void fl_yxline(int x, int y, int y1, int x2); -FL_EXPORT void fl_yxline(int x, int y, int y1, int x2, int y3); +/** + Draws a vertical line from (x,y) to (x,y1) + */ +inline void fl_yxline(int x, int y, int y1) {fl_graphics_driver->yxline(x,y,y1);}; +/** + Draws a vertical line from (x,y) to (x,y1), then a horizontal from (x,y1) to (x2,y1) + */ +inline void fl_yxline(int x, int y, int y1, int x2) {fl_graphics_driver->yxline(x,y,y1,x2);}; +/** + Draws a vertical line from (x,y) to (x,y1) then a horizontal from (x,y1) + to (x2,y1), then another vertical from (x2,y1) to (x2,y3) + */ +inline void fl_yxline(int x, int y, int y1, int x2, int y3) {fl_graphics_driver->yxline(x,y,y1,x2,y3);}; // circular lines and pie slices (code in fl_arci.C): -FL_EXPORT void fl_arc(int x, int y, int w, int h, double a1, double a2); -FL_EXPORT void fl_pie(int x, int y, int w, int h, double a1, double a2); +/** + Draw ellipse sections using integer coordinates. + + These functions match the rather limited circle drawing code provided by X + and WIN32. The advantage over using fl_arc with floating point coordinates + is that they are faster because they often use the hardware, and they draw + much nicer small circles, since the small sizes are often hard-coded bitmaps. + + If a complete circle is drawn it will fit inside the passed bounding box. + The two angles are measured in degrees counterclockwise from 3 o'clock and + are the starting and ending angle of the arc, \p a2 must be greater or equal + to \p a1. + + fl_arc() draws a series of lines to approximate the arc. Notice that the + integer version of fl_arc() has a different number of arguments than the + double version fl_arc(double x, double y, double r, double start, double end) + + \param[in] x,y,w,h bounding box of complete circle + \param[in] a1,a2 start and end angles of arc measured in degrees + counter-clockwise from 3 o'clock. \p a2 must be greater + than or equal to \p a1. + */ +inline void fl_arc(int x, int y, int w, int h, double a1, double a2) {fl_graphics_driver->arc(x,y,w,h,a1,a2); }; +/** + Draw filled ellipse sections using integer coordinates. + + Like fl_arc(), but fl_pie() draws a filled-in pie slice. + This slice may extend outside the line drawn by fl_arc(); + to avoid this use w - 1 and h - 1. + + \param[in] x,y,w,h bounding box of complete circle + \param[in] a1,a2 start and end angles of arc measured in degrees + counter-clockwise from 3 o'clock. \p a2 must be greater + than or equal to \p a1. + */ +inline void fl_pie(int x, int y, int w, int h, double a1, double a2) {fl_graphics_driver->pie(x,y,w,h,a1,a2); }; /** fl_chord declaration is a place holder - the function does not yet exist */ FL_EXPORT void fl_chord(int x, int y, int w, int h, double a1, double a2); // nyi @@ -144,32 +332,113 @@ FL_EXPORT void fl_scale(double x); FL_EXPORT void fl_translate(double x, double y); FL_EXPORT void fl_rotate(double d); FL_EXPORT void fl_mult_matrix(double a, double b, double c, double d, double x,double y); -FL_EXPORT void fl_begin_points(); -FL_EXPORT void fl_begin_line(); -FL_EXPORT void fl_begin_loop(); -FL_EXPORT void fl_begin_polygon(); -FL_EXPORT void fl_vertex(double x, double y); -FL_EXPORT void fl_curve(double X0, double Y0, double X1, double Y1, double X2, double Y2, double X3, double Y3); -FL_EXPORT void fl_arc(double x, double y, double r, double start, double a); -FL_EXPORT void fl_circle(double x, double y, double r); -FL_EXPORT void fl_end_points(); -FL_EXPORT void fl_end_line(); -FL_EXPORT void fl_end_loop(); -FL_EXPORT void fl_end_polygon(); -FL_EXPORT void fl_begin_complex_polygon(); -FL_EXPORT void fl_gap(); -FL_EXPORT void fl_end_complex_polygon(); +/** + Starts drawing a list of points. Points are added to the list with fl_vertex() + */ +inline void fl_begin_points() {fl_graphics_driver->begin_points(); }; +/** + Starts drawing a list of lines. + */ +inline void fl_begin_line() {fl_graphics_driver->begin_line(); }; +/** + Starts drawing a closed sequence of lines. + */ +inline void fl_begin_loop() {fl_graphics_driver->begin_loop(); }; +/** + Starts drawing a convex filled polygon. + */ +inline void fl_begin_polygon() {fl_graphics_driver->begin_polygon(); }; +/** + Adds a single vertex to the current path. + \param[in] x,y coordinate + */ +inline void fl_vertex(double x, double y) {fl_graphics_driver->vertex(x,y); }; +/** + Add a series of points on a Bezier curve to the path. + The curve ends (and two of the points) are at X0,Y0 and X3,Y3. + \param[in] X0,Y0 curve start point + \param[in] X1,Y1 curve control point + \param[in] X2,Y2 curve control point + \param[in] X3,Y3 curve end point + */ +inline void fl_curve(double X0, double Y0, double X1, double Y1, double X2, double Y2, double X3, double Y3) + {fl_graphics_driver->curve(X0,Y0,X1,Y1,X2,Y2,X3,Y3); }; +/** + Add a series of points to the current path on the arc of a circle; you + can get elliptical paths by using scale and rotate before calling fl_arc(). + \param[in] x,y,r center and radius of circular arc + \param[in] start,end angles of start and end of arc measured in degrees + counter-clockwise from 3 o'clock. If \p end is less than \p start + then it draws the arc in a clockwise direction. + */ +inline void fl_arc(double x, double y, double r, double start, double end) {fl_graphics_driver->arc(x,y,r,start,end); }; +/** + fl_circle() is equivalent to fl_arc(x,y,r,0,360), but may be faster. + + It must be the \e only thing in the path: if you want a circle as part of + a complex polygon you must use fl_arc() + \param[in] x,y,r center and radius of circle + */ +inline void fl_circle(double x, double y, double r) {fl_graphics_driver->circle(x,y,r); }; +/** + Ends list of points, and draws. + */ +inline void fl_end_points() {fl_graphics_driver->end_points(); }; +/** + Ends list of lines, and draws. + */ +inline void fl_end_line() {fl_graphics_driver->end_line(); }; +/** + Ends closed sequence of lines, and draws. + */ +inline void fl_end_loop() {fl_graphics_driver->end_loop(); }; +/** + Ends convex filled polygon, and draws. + */ +inline void fl_end_polygon() {fl_graphics_driver->end_polygon(); }; +/** + Starts drawing a complex filled polygon. + + The polygon may be concave, may have holes in it, or may be several + disconnected pieces. Call fl_gap() to separate loops of the path. + + To outline the polygon, use fl_begin_loop() and replace each fl_gap() + with fl_end_loop();fl_begin_loop() pairs. + + \note + For portability, you should only draw polygons that appear the same + whether "even/odd" or "non-zero" winding rules are used to fill them. + Holes should be drawn in the opposite direction to the outside loop. + */ +inline void fl_begin_complex_polygon() {fl_graphics_driver->begin_complex_polygon(); }; +/** + Call fl_gap() to separate loops of the path. + + It is unnecessary but harmless to call fl_gap() before the first vertex, + after the last vertex, or several times in a row. + */ +inline void fl_gap() {fl_graphics_driver->gap(); }; +/** + Ends complex filled polygon, and draws. + */ +inline void fl_end_complex_polygon() {fl_graphics_driver->end_complex_polygon(); }; // get and use transformed positions: FL_EXPORT double fl_transform_x(double x, double y); FL_EXPORT double fl_transform_y(double x, double y); FL_EXPORT double fl_transform_dx(double x, double y); FL_EXPORT double fl_transform_dy(double x, double y); -FL_EXPORT void fl_transformed_vertex(double x, double y); +/** + Adds coordinate pair to the vertex list without further transformations. + \param[in] xf,yf transformed coordinate + */ +inline void fl_transformed_vertex(double xf, double yf) {fl_graphics_driver->transformed_vertex(xf,yf); }; /** @} */ /** \addtogroup fl_attributes @{ */ /* NOTE: doxygen comments here to avoid triplication in os-specific sources */ + +// Fonts: /** Sets the current font, which is then used in various drawing routines. You may call this outside a draw context if necessary to call fl_width(), @@ -179,9 +448,7 @@ FL_EXPORT void fl_transformed_vertex(double x, double y); The size of the font is measured in pixels and not "points". Lines should be spaced \p size pixels apart or more. */ - -// Fonts: -FL_EXPORT void fl_font(Fl_Font face, Fl_Fontsize size); +inline void fl_font(Fl_Font face, Fl_Fontsize size) { fl_graphics_driver->font(face,size); }; extern FL_EXPORT Fl_Font fl_font_; ///< current font index /** @@ -189,7 +456,7 @@ extern FL_EXPORT Fl_Font fl_font_; ///< current font index This can be used to save/restore the font. */ inline Fl_Font fl_font() {return fl_font_;} -/** current font size */ +/** \brief current font size */ extern FL_EXPORT Fl_Fontsize fl_size_; /** Returns the \p size set by the most recent call to fl_font(). @@ -216,7 +483,7 @@ FL_EXPORT double fl_width(const char* txt, int n); /** Return the typographical width of a single character : \note if a valid fl_gc is NOT found then it uses the first window gc, or the screen gc if no fltk window is available when called. */ -FL_EXPORT double fl_width(Fl_Char); +FL_EXPORT double fl_width(unsigned int); /** Determine the minimum pixel dimensions of a nul-terminated string. Usage: given a string "txt" drawn using fl_draw(txt, x, y) you would determine @@ -280,23 +547,23 @@ FL_EXPORT void fl_draw(const char* str, int x, int y); Draws a nul-terminated string starting at the given location and rotating \p angle degrees counterclockwise. This version of fl_draw provides direct access to the text drawing - function of the underlying OS and suported for Xft, Win32 and MacOS - fltk subset. + function of the underlying OS and is supported by Xft, Win32 and MacOS + fltk subsets. */ -FL_EXPORT void fl_draw(int angle,const char* str, int x, int y); +FL_EXPORT void fl_draw(int angle, const char* str, int x, int y); /** Draws an array of \p n characters starting at the given location. */ -FL_EXPORT void fl_draw(const char* str, int n, int x, int y); +inline void fl_draw(const char* str, int n, int x, int y) {fl_graphics_driver->draw(str,n,x,y); }; /** Draws an array of \p n characters starting at the given location, rotating \p angle degrees counterclockwise. */ -FL_EXPORT void fl_draw(int angle,const char* str, int n, int x, int y); +inline void fl_draw(int angle,const char* str, int n, int x, int y) {fl_graphics_driver->draw(angle,str,n,x,y); }; /** Draws an array of \p n characters right to left starting at given location. */ -FL_EXPORT void fl_rtl_draw(const char*, int n, int x, int y); +inline void fl_rtl_draw(const char* str, int n, int x, int y) {fl_graphics_driver->rtl_draw(str,n,x,y); }; FL_EXPORT void fl_measure(const char* str, int& x, int& y, int draw_symbols = 1); FL_EXPORT void fl_draw(const char* str, int x, int y, int w, int h, @@ -313,15 +580,6 @@ FL_EXPORT void fl_frame2(const char* s, int x, int y, int w, int h); FL_EXPORT void fl_draw_box(Fl_Boxtype, int x, int y, int w, int h, Fl_Color); // images: -/** - signature of image generation callback function. - \param[in] data user data passed to function - \param[in] x,y,w position and width of scan line in image - \param[out] buf buffer for generated image data. You must copy \p w - pixels from scanline \p y, starting at pixel \p x - to this buffer. - */ -typedef void (*Fl_Draw_Image_Cb)(void* data,int x,int y,int w,uchar* buf); /** Draw an 8-bit per color RGB or luminance image. @@ -356,13 +614,15 @@ typedef void (*Fl_Draw_Image_Cb)(void* data,int x,int y,int w,uchar* buf); any visual of 8 bits or less, and all common TrueColor visuals up to 32 bits. */ -FL_EXPORT void fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0); +inline void fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0) + { fl_graphics_driver->draw_image(buf, X, Y, W, H, D, L); }; /** Draw a gray-scale (1 channel) image. \see fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int D, int L) */ -FL_EXPORT void fl_draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0); +inline void fl_draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0) + { fl_graphics_driver->draw_image_mono(buf, X, Y, W, H, D, L); }; /** Draw image using callback function to generate image data. @@ -396,7 +656,8 @@ FL_EXPORT void fl_draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int If \p D is 4 or more, you must fill in the unused bytes with zero. */ -FL_EXPORT void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3); +inline void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3) + { fl_graphics_driver->draw_image(cb, data, X, Y, W, H, D); }; /** Draw gray-scale image using callback function to generate image data. @@ -441,8 +702,9 @@ FL_EXPORT int fl_measure_pixmap(const char* const* cdata, int &w, int &h); // other: FL_EXPORT void fl_scroll(int X, int Y, int W, int H, int dx, int dy, void (*draw_area)(void*, int,int,int,int), void* data); -FL_EXPORT const char* fl_shortcut_label(Fl_Shortcut shortcut); -FL_EXPORT const char* fl_shortcut_label(Fl_Shortcut shortcut, const char **eom); +FL_EXPORT const char* fl_shortcut_label(unsigned int shortcut); +FL_EXPORT const char* fl_shortcut_label(unsigned int shortcut, const char **eom); +FL_EXPORT unsigned int fl_old_shortcut(const char* s); FL_EXPORT void fl_overlay_rect(int x,int y,int w,int h); FL_EXPORT void fl_overlay_clear(); FL_EXPORT void fl_cursor(Fl_Cursor, Fl_Color fg=FL_BLACK, Fl_Color bg=FL_WHITE); @@ -468,5 +730,5 @@ FL_EXPORT int fl_add_symbol(const char* name, void (*drawit)(Fl_Color), int scal #endif // -// End of "$Id: fl_draw.H 6878 2009-09-17 22:12:24Z matt $". +// End of "$Id: fl_draw.H 7659 2010-07-01 13:21:32Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/FL/fl_types.h b/plugins/zynaddsubfx/fltk/FL/fl_types.h index d87cd7387..6175ded02 100644 --- a/plugins/zynaddsubfx/fltk/FL/fl_types.h +++ b/plugins/zynaddsubfx/fltk/FL/fl_types.h @@ -1,5 +1,5 @@ /* - * "$Id: fl_types.h 6299 2008-09-18 19:09:34Z fabien $" + * "$Id: fl_types.h 6942 2009-11-18 12:22:51Z AlbrechtS $" * * Simple "C"-style types for the Fast Light Tool Kit (FLTK). * @@ -62,5 +62,5 @@ typedef unsigned int Fl_Char; #endif /* - * End of "$Id: fl_types.h 6299 2008-09-18 19:09:34Z fabien $". + * End of "$Id: fl_types.h 6942 2009-11-18 12:22:51Z AlbrechtS $". */ diff --git a/plugins/zynaddsubfx/fltk/FL/fl_utf8.h b/plugins/zynaddsubfx/fltk/FL/fl_utf8.h index e7bc9010a..767a2a3a3 100644 --- a/plugins/zynaddsubfx/fltk/FL/fl_utf8.h +++ b/plugins/zynaddsubfx/fltk/FL/fl_utf8.h @@ -1,4 +1,4 @@ -/* "$Id: $" +/* "$Id: fl_utf8.h 7551 2010-04-20 21:43:31Z engelsman $" * * Author: Jean-Marc Lienher ( http://oksid.ch ) * Copyright 2000-2009 by O'ksi'D. @@ -38,8 +38,8 @@ #ifndef _HAVE_FL_UTF8_HDR_ #define _HAVE_FL_UTF8_HDR_ -#include "FL/Fl_Export.H" -#include "FL/fl_types.h" +#include "Fl_Export.H" +#include "fl_types.h" #include #include @@ -142,6 +142,15 @@ FL_EXPORT int fl_utf8locale(); * type of the src text. */ FL_EXPORT int fl_utf8test(const char *src, unsigned len); +/* XX: return width of "raw" ucs character in columns. + * for internal use only */ +FL_EXPORT int fl_wcwidth_(unsigned int ucs); + +/* XX: return width of utf-8 character string in columns. + * NOTE: this may also do C1 control character (0x80 to 0x9f) to CP1252 mapping, + * depending on original build options */ +FL_EXPORT int fl_wcwidth(const char *src); + /* OD: Return true if the character is non-spacing */ FL_EXPORT unsigned int fl_nonspacing(unsigned int ucs); @@ -246,5 +255,5 @@ FL_EXPORT char fl_make_path( const char *path ); #endif /* _HAVE_FL_UTF8_HDR_ */ /* - * End of "$Id: $". + * End of "$Id: fl_utf8.h 7551 2010-04-20 21:43:31Z engelsman $". */ diff --git a/plugins/zynaddsubfx/fltk/FL/mac.H b/plugins/zynaddsubfx/fltk/FL/mac.H index 79cbd10c2..aa8e6fb31 100644 --- a/plugins/zynaddsubfx/fltk/FL/mac.H +++ b/plugins/zynaddsubfx/fltk/FL/mac.H @@ -1,5 +1,5 @@ // -// "$Id: mac.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: mac.H 7663 2010-07-01 16:51:28Z manolo $" // // Mac header file for the Fast Light Tool Kit (FLTK). // @@ -36,24 +36,66 @@ // Standard MacOS Carbon API includes... #include +#include + +#ifndef MAC_OS_X_VERSION_10_3 +#define MAC_OS_X_VERSION_10_3 1030 +#endif +#ifndef MAC_OS_X_VERSION_10_4 +#define MAC_OS_X_VERSION_10_4 1040 +#endif +#ifndef MAC_OS_X_VERSION_10_5 +#define MAC_OS_X_VERSION_10_5 1050 +#endif +#ifndef MAC_OS_X_VERSION_10_6 +#define MAC_OS_X_VERSION_10_6 1060 +#endif +#ifndef MAC_OS_X_VERSION_MAX_ALLOWED +#define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_X_VERSION_10_3 +#endif + +#ifndef CGFLOAT_DEFINED //appears with 10.5 in CGBase.h +#if defined(__LP64__) && __LP64__ +typedef double CGFloat; +#else +typedef float CGFloat; +#endif +#endif // CGFLOAT_DEFINED + // Now make some fixes to the headers... #undef check // Dunno where this comes from... // Some random X equivalents -typedef WindowPtr Window; struct XPoint { int x, y; }; struct XRectangle {int x, y, width, height;}; -typedef RgnHandle Fl_Region; -void fl_clip_region(Fl_Region); + +typedef void *Window; // this is really a pter to the subclass FLWindow of NSWindow +typedef struct flCocoaRegion { + int count; + CGRect *rects; +} *Fl_Region; // a region is the union of a series of rectangles +extern CGRect fl_cgrectmake_cocoa(int x, int y, int w, int h); + inline Fl_Region XRectangleRegion(int x, int y, int w, int h) { - Fl_Region R = NewRgn(); - SetRectRgn(R, x, y, x+w, y+h); + Fl_Region R = (Fl_Region)malloc(sizeof(*R)); + R->count = 1; + R->rects = (CGRect *)malloc(sizeof(CGRect)); + *(R->rects) = fl_cgrectmake_cocoa(x, y, w, h); return R; } inline void XDestroyRegion(Fl_Region r) { - DisposeRgn(r); + if(r) { + free(r->rects); + free(r); + } } +extern void *fl_default_cursor; +extern void *fl_system_menu; +typedef CGContextRef Fl_Offscreen; +typedef CGImageRef Fl_Bitmask; + +void fl_clip_region(Fl_Region); # include "Fl_Window.H" @@ -62,15 +104,15 @@ inline void XDestroyRegion(Fl_Region r) { class Fl_X { public: - Window xid; // Mac WindowPtr - GWorldPtr other_xid; // pointer for offscreen bitmaps (doublebuffer) + Window xid; // Cocoa: FLWindow* ; Carbon: WindowRef + Fl_Offscreen other_xid; // pointer for offscreen bitmaps (doublebuffer) Fl_Window *w; // FLTK window for Fl_Region region; Fl_Region subRegion; // region for this specific subwindow Fl_X *next; // linked tree to support subwindows Fl_X *xidChildren, *xidNext; // more subwindow tree int wait_for_expose; - CursHandle cursor; + void *cursor; // is really NSCursor* static Fl_X* first; static Fl_X* i(const Fl_Window* w) {return w->i;} static int fake_X_wm(const Fl_Window*,int&,int&,int&,int&,int&); @@ -78,8 +120,6 @@ public: void flush(); // Quartz additions: CGContextRef gc; // graphics context (NULL when using QD) - static ATSUTextLayout atsu_layout; // windows share a global font - static ATSUStyle atsu_style; static void q_fill_context(); // fill a Quartz context with current FLTK state static void q_clear_clipping(); // remove all clipping from a Quartz context static void q_release_context(Fl_X *x=0); // free all resources associated with fl_gc @@ -87,9 +127,13 @@ public: static void q_end_image(); }; -extern void MacDestroyWindow(Fl_Window*,WindowPtr); -extern void MacMapWindow(Fl_Window*,WindowPtr); -extern void MacUnmapWindow(Fl_Window*,WindowPtr); +extern void MacDestroyWindow(Fl_Window*,void *); +extern void MacMapWindow(Fl_Window*,void *); +extern void MacUnmapWindow(Fl_Window*,void *); +extern WindowRef MACwindowRef(Fl_Window *w); +extern Fl_Region MacRectRegionIntersect(Fl_Region current, int x,int y,int w, int h); +extern void MacCollapseWindow(Window w); + extern int MacUnlinkWindow(Fl_X*,Fl_X*start=0L); inline Window fl_xid(const Fl_Window*w) @@ -97,8 +141,6 @@ inline Window fl_xid(const Fl_Window*w) return Fl_X::i(w)->xid; } -extern CursHandle fl_default_cursor; - extern struct Fl_XMap { RGBColor rgb; ulong pen; @@ -107,10 +149,8 @@ extern struct Fl_XMap { extern FL_EXPORT void *fl_display; extern FL_EXPORT Window fl_window; extern FL_EXPORT CGContextRef fl_gc; -extern FL_EXPORT Handle fl_system_menu; extern FL_EXPORT class Fl_Sys_Menu_Bar *fl_sys_menu_bar; -typedef GWorldPtr Fl_Offscreen; extern Fl_Offscreen fl_create_offscreen(int w, int h); extern void fl_copy_offscreen(int x,int y,int w,int h, Fl_Offscreen gWorld, int srcx,int srcy); @@ -118,7 +158,6 @@ extern void fl_delete_offscreen(Fl_Offscreen gWorld); extern void fl_begin_offscreen(Fl_Offscreen gWorld); extern void fl_end_offscreen(); -typedef GWorldPtr Fl_Bitmask; // Carbon requires a 1-bit GWorld instead of a BitMap extern FL_EXPORT Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data); extern FL_EXPORT Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *data); @@ -126,12 +165,30 @@ extern FL_EXPORT void fl_delete_bitmask(Fl_Bitmask bm); extern void fl_open_display(); -// Register a function for opening files via the finder... -extern void fl_open_callback(void (*cb)(const char *)); - extern FL_EXPORT int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b); #endif // FL_DOXYGEN + +/** \defgroup group_macosx Mac OS X-specific functions + @{ */ + +/** @brief Register a function called for each file dropped onto an application icon + * \note \#include + */ +extern void fl_open_callback(void (*cb)(const char *)); + +/** + * \brief Attaches a callback to the "About myprog" item of the system application menu. + * \note \#include + * + * \param cb a callback that will be called by "About myprog" menu item + * with NULL 1st argument. + * \param user_data a pointer transmitted as 2nd argument to the callback. + * \param shortcut optional shortcut to attach to the "About myprog" menu item (e.g., FL_META+'a') + */ +extern void fl_mac_set_about( Fl_Callback *cb, void *user_data, int shortcut = 0); +/** @} */ + // -// End of "$Id: mac.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: mac.H 7663 2010-07-01 16:51:28Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/FL/mac.r b/plugins/zynaddsubfx/fltk/FL/mac.r deleted file mode 100644 index 3d71f2ebb..000000000 --- a/plugins/zynaddsubfx/fltk/FL/mac.r +++ /dev/null @@ -1,13 +0,0 @@ -data 'MBAR' (128) { - $"0001 0080" /* ...€ */ -}; - -data 'MENU' (128, "Apple") { - $"0080 0000 0000 0000 0000 FFFF FFFB 0114" /* .€........ÿÿÿû.. */ - $"0A41 626F 7574 2046 4C54 4B00 0000 0001" /* ÂAbout FLTK..... */ - $"2D00 0000 0000" /* -..... */ -}; - -data 'carb' (0) { -}; - diff --git a/plugins/zynaddsubfx/fltk/FL/math.h b/plugins/zynaddsubfx/fltk/FL/math.h index d7a0fb63a..bb7fad393 100644 --- a/plugins/zynaddsubfx/fltk/FL/math.h +++ b/plugins/zynaddsubfx/fltk/FL/math.h @@ -1,5 +1,5 @@ // -// "$Id: math.h 6614 2009-01-01 16:11:32Z matt $" +// "$Id: math.h 7504 2010-04-14 20:17:44Z matt $" // // Math header file for the Fast Light Tool Kit (FLTK). // @@ -25,19 +25,18 @@ // http://www.fltk.org/str.php // +// Xcode on OS X includes files by recursing down into directories. +// This code catches the cycle and directly includes the required file. +#ifdef fl_math_h_cyclic_include +# include "/usr/include/math.h" +#endif + #ifndef fl_math_h # define fl_math_h -// Apple's ProjectBuilder has the nasty habit of including recursively -// down the file tree. To avoid re-including we must -// directly include the systems math file. (Plus, I could not find a -// predefined macro for ProjectBuilder builds, so we have to define it -// in the project) -# if defined(__APPLE__) && defined(__PROJECTBUILDER__) -# include "/usr/include/math.h" -# else -# include -# endif +# define fl_math_h_cyclic_include +# include +# undef fl_math_h_cyclic_include # ifdef __EMX__ # include @@ -68,5 +67,5 @@ inline double copysign(double a, double b) {return b<0 ? -a : a;} // -// End of "$Id: math.h 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: math.h 7504 2010-04-14 20:17:44Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/names.h b/plugins/zynaddsubfx/fltk/FL/names.h index 1c09463f3..85f1bc02a 100644 --- a/plugins/zynaddsubfx/fltk/FL/names.h +++ b/plugins/zynaddsubfx/fltk/FL/names.h @@ -1,5 +1,5 @@ // -// "$Id: names.h 6731 2009-03-31 22:41:10Z greg.ercolano $" +// "$Id: names.h 7159 2010-02-26 18:10:54Z greg.ercolano $" // // Event names header file for the Fast Light Tool Kit (FLTK). // @@ -30,6 +30,25 @@ #ifndef FL_NAMES_H #define FL_NAMES_H +/** \defgroup fl_events Events handling functions + @{ + */ + +/** + This is an array of event names you can use to convert event numbers into names. + + The array gets defined inline wherever your '\#include ' appears. + + \b Example: + \code + #include // array will be defined here + int MyClass::handle(int e) { + printf("Event was %s (%d)\n", fl_eventnames[e], e); + // ..resulting output might be e.g. "Event was FL_PUSH (1)".. + [..] + } + \endcode + */ const char * const fl_eventnames[] = { "FL_NO_EVENT", @@ -58,6 +77,23 @@ const char * const fl_eventnames[] = "FL_DND_RELEASE", }; +/** + This is an array of font names you can use to convert font numbers into names. + + The array gets defined inline wherever your '\#include ' appears. + + \b Example: + \code + #include // array will be defined here + int MyClass::my_callback(Fl_Widget *w, void*) { + int fnum = w->labelfont(); + // Resulting output might be e.g. "Label's font is FL_HELVETICA (0)" + printf("Label's font is %s (%d)\n", fl_fontnames[fnum], fnum); + // ..resulting output might be e.g. "Label's font is FL_HELVETICA (0)".. + [..] + } + \endcode + */ const char * const fl_fontnames[] = { "FL_HELVETICA", @@ -78,8 +114,10 @@ const char * const fl_fontnames[] = "FL_ZAPF_DINGBATS", }; +/** @} */ + #endif /* FL_NAMES_H */ // -// End of "$Id: names.h 6731 2009-03-31 22:41:10Z greg.ercolano $". +// End of "$Id: names.h 7159 2010-02-26 18:10:54Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/FL/win32.H b/plugins/zynaddsubfx/fltk/FL/win32.H index ddd7230f1..46a9ceb57 100644 --- a/plugins/zynaddsubfx/fltk/FL/win32.H +++ b/plugins/zynaddsubfx/fltk/FL/win32.H @@ -1,5 +1,5 @@ // -// "$Id: win32.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: win32.H 7671 2010-07-09 17:31:33Z manolo $" // // WIN32 header file for the Fast Light Tool Kit (FLTK). // @@ -34,7 +34,6 @@ # error "Never use directly; include instead." #endif // !Fl_X_H -#include #include // In some of the distributions, the gcc header files are missing some stuff: #ifndef LPMINMAXINFO @@ -46,15 +45,15 @@ #define VK_APPS 0x5D #endif +#include + // some random X equivalents typedef HWND Window; typedef POINT XPoint; struct XRectangle {int x, y, width, height;}; typedef HRGN Fl_Region; FL_EXPORT void fl_clip_region(Fl_Region); -inline Fl_Region XRectangleRegion(int x, int y, int w, int h) { - return CreateRectRgn(x,y,x+w,y+h); -} +extern Fl_Region XRectangleRegion(int x, int y, int w, int h); inline void XDestroyRegion(Fl_Region r) {DeleteObject(r);} inline void XClipBox(Fl_Region r,XRectangle* rect) { RECT win_rect; GetRgnBox(r,&win_rect); @@ -122,16 +121,19 @@ extern FL_EXPORT void fl_save_dc( HWND w, HDC dc); // off-screen pixmaps: create, destroy, draw into, copy to window typedef HBITMAP Fl_Offscreen; -#define fl_create_offscreen(w, h) CreateCompatibleBitmap(fl_gc, w, h) +#define fl_create_offscreen(w, h) \ + CreateCompatibleBitmap( (fl_gc ? fl_gc : fl_GetDC(0) ) , w, h) extern FL_EXPORT HDC fl_makeDC(HBITMAP); # define fl_begin_offscreen(b) \ HDC _sgc=fl_gc; Window _sw=fl_window; \ + Fl_Surface_Device *_ss = fl_surface; fl_display_device->set_current(); \ fl_gc=fl_makeDC(b); int _savedc = SaveDC(fl_gc); fl_window=(HWND)b; fl_push_no_clip() # define fl_end_offscreen() \ - fl_pop_clip(); RestoreDC(fl_gc, _savedc); DeleteDC(fl_gc); fl_window=_sw; fl_gc = _sgc + fl_pop_clip(); RestoreDC(fl_gc, _savedc); DeleteDC(fl_gc); _ss->set_current(); fl_window=_sw; fl_gc = _sgc + FL_EXPORT void fl_copy_offscreen(int x,int y,int w,int h,HBITMAP pixmap,int srcx,int srcy); FL_EXPORT void fl_copy_offscreen_with_alpha(int x,int y,int w,int h,HBITMAP pixmap,int srcx,int srcy); @@ -150,5 +152,5 @@ inline void fl_open_callback(void (*)(const char *)) {} extern FL_EXPORT int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b); #endif // FL_DOXYGEN // -// End of "$Id: win32.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: win32.H 7671 2010-07-09 17:31:33Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/FL/x.H b/plugins/zynaddsubfx/fltk/FL/x.H index 89efe6ae8..754fe5e4a 100644 --- a/plugins/zynaddsubfx/fltk/FL/x.H +++ b/plugins/zynaddsubfx/fltk/FL/x.H @@ -1,5 +1,5 @@ // -// "$Id: x.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: x.H 7671 2010-07-09 17:31:33Z manolo $" // // X11 header file for the Fast Light Tool Kit (FLTK). // @@ -65,11 +65,35 @@ extern FL_EXPORT int fl_screen; extern FL_EXPORT XVisualInfo *fl_visual; extern FL_EXPORT Colormap fl_colormap; +// access to core fonts: +// This class provides a "smart pointer" that returns a pointer to an XFontStruct. +// The global variable fl_xfont can be called wherever a bitmap "core" font is +// needed, e.g. when rendering to a GL context under X11. +// With Xlib / X11 fonts, fl_xfont will return the current selected font. +// With XFT / X11 fonts, fl_xfont will attempt to return the bitmap "core" font most +// similar to (usually the same as) the current XFT font. +class Fl_XFont_On_Demand +{ +public: + Fl_XFont_On_Demand(XFontStruct* p = NULL) : ptr(p) { } + Fl_XFont_On_Demand& operator=(const Fl_XFont_On_Demand& x) + { ptr = x.ptr; return *this; } + Fl_XFont_On_Demand& operator=(XFontStruct* p) + { ptr = p; return *this; } + XFontStruct* value(); + operator XFontStruct*() { return value(); } + XFontStruct& operator*() { return *value(); } + XFontStruct* operator->() { return value(); } + bool operator==(const Fl_XFont_On_Demand& x) { return ptr == x.ptr; } + bool operator!=(const Fl_XFont_On_Demand& x) { return ptr != x.ptr; } +private: + XFontStruct *ptr; +}; +extern FL_EXPORT Fl_XFont_On_Demand fl_xfont; + // drawing functions: extern FL_EXPORT GC fl_gc; extern FL_EXPORT Window fl_window; -//extern FL_EXPORT XFontStruct* fl_xfont; -extern FL_EXPORT XUtf8FontStruct* fl_xfont; extern FL_EXPORT void *fl_xftfont; FL_EXPORT ulong fl_xpixel(Fl_Color i); FL_EXPORT ulong fl_xpixel(uchar r, uchar g, uchar b); @@ -86,16 +110,20 @@ extern FL_EXPORT ulong fl_event_time; // off-screen pixmaps: create, destroy, draw into, copy to window: typedef ulong Fl_Offscreen; -#define fl_create_offscreen(w,h) \ - XCreatePixmap(fl_display, fl_window, w, h, fl_visual->depth) +# define fl_create_offscreen(w,h) \ + XCreatePixmap(fl_display, \ + (fl_surface->type() == Fl_Display_Device::device_type ? \ + fl_window : fl_xid(Fl::first_window()) ) , \ + w, h, fl_visual->depth) // begin/end are macros that save the old state in local variables: # define fl_begin_offscreen(pixmap) \ - Window _sw=fl_window; fl_window=pixmap; fl_push_no_clip() + Window _sw=fl_window; fl_window=pixmap; \ + Fl_Surface_Device *_ss = fl_surface; fl_display_device->set_current(); \ + fl_push_no_clip() # define fl_end_offscreen() \ - fl_pop_clip(); fl_window = _sw + fl_pop_clip(); fl_window = _sw; _ss->set_current() -# define fl_copy_offscreen(x,y,w,h,pixmap,srcx,srcy) \ - XCopyArea(fl_display, pixmap, fl_window, fl_gc, srcx, srcy, w, h, x, y) +extern void fl_copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy); # define fl_delete_offscreen(pixmap) XFreePixmap(fl_display, pixmap) // Bitmap masks @@ -145,5 +173,5 @@ extern FL_EXPORT int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b) #endif // -// End of "$Id: x.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: x.H 7671 2010-07-09 17:31:33Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/README.123 b/plugins/zynaddsubfx/fltk/README.123 index 1ab0c4f47..00c5ee51d 100644 --- a/plugins/zynaddsubfx/fltk/README.123 +++ b/plugins/zynaddsubfx/fltk/README.123 @@ -4,20 +4,20 @@ This file listst the differences between FLTK 1 and FLTK 2 with annotations for a possible implementation of FLTK 3. The all new and improved FLTK 3 -needs to be compatible with 1 and 2. It must have a moder API, plenty of -widgets, lots of options, customization at run-time, but still be easily -portable, fast, and of course light. +needs to be compatible with 1 and 2. It must have a modern API, a complete set +of widgets, lots of options, customization at run-time, but still be easily +portable, fast, and, of course, light. -FLTK 1 has become a nice starting point for the first steps in GUI -programming. It runs on al major platform (and on many minor ones +FLTK 1 has evolved to be a great starting point for the first steps in GUI +programming. It runs on all major platform (and on many minor ones as well), is small, compact, and easy to use. FLTK 2 was the -attempt to continue the success of FLTK 1 with a much cleaber API +attempt to continue the success of FLTK 1 with a clearer and more modern API and many important details improved. Unfortunately many users never made the jump to FLTK 2 and so it not only ended in a crawling slow branch, it also became instable and at last unmaintainable. FLTK 3 sets out to surprise FLTK 1 users and satisfy FLTK 2 junkies. -It will basically be the improved FLTK 2 API combined with the quite +It will basically be the improved FLTK 2 API combined with the proven and stable innards of FLTK 1. As an extra bonus, FLTK 3 will be compatible to 1 and 2. Just prepend your code with the "coding_style" instruction and FLTK 3 will do the rest. It is even possible to intermix F1 and @@ -34,7 +34,7 @@ on the Forms Library, FLTK 2 is Bill's take on how FLTK 1 should have been. This chapter outlines the biggest differences between version. (1) Coordinate System: FLTK 1 child coordinates are always relative to the -window, not as most would expect to the parent. FLTK 2 does the logical +window, not as most would expect to the parent group. FLTK 2 does the logical thing and uses group-relative origins. This is somewhat difficult to port if we want to stay downward compatible. Fl_Widget will need an additional flag indicating absolute or relative coordinates. @@ -42,10 +42,11 @@ flag indicating absolute or relative coordinates. (2) Pulldown Menus: The developers of the Forms Library did not implement the idea of hierarchies all the way through. Pulldown menus, which are hierarchical by nature, were instead implemented as a list with lots of -tricks and cludges to make them usable. FLTK 2 went half way by using the +tricks and kludges to make them usable. FLTK 2 went half way by using the existing Windget/Group relation to create menus, however, menu items are still specialized widgets. For FLTK 3, I would like to allow any widget -inside a pulldown menu. +inside a pulldown menu, using the hierarchical nature of the FLTK base class +Fl_Widget. (3) Browsers and Tree Views: Browsers in FLTK1 are implemented even worse than Pulldown Menus. FLTK 2 solved the issues in a similar way, and here @@ -53,22 +54,24 @@ again, I prefer the FLTK 2 way very mch, but also would like to extend functionality to allow arbitrary widgets as list items. A Tree-like widget comes free with the FLTK 2 concept. FLTK 1 has no such thing and even Fluid had to hack the library badly to generate a tree view. +FLTK 1.3 now comes with Greg's Fl_Tree widget. (4) Namespaces: this is a minr issue that I include for completeness. FLTK 2 -introduces the ftk namespace, renaming all widgets. FLTK 3 will use the +introduces the fltk namespace, renaming all widgets. FLTK 3 will use the FLTK 2 naming scheme and map FLTK 1 class names using typedefs. This is, as most things in programming are, a compromise. The "coding_style" function must be used to switch between FLTK 1 and FLTK 2 code. No worries though, it's easy and straight forward. (5) Layout: FLTK 1 uses a top-down approach for widget layout in which the -parent widget decides about the childs size "resize(x, y, w, h)". In FLTK 2 -any widget can call "layout()" which will query children for their preffered +parent widget decides about the child's size "resize(x, y, w, h)". In FLTK 2 +any widget can call "layout()" which will query children for their preferred size and propagate the information up. This is a great concept that FLTK 3 should adapt, plus it is compatible. -(6) Ractangle: FLTK 2's base class is fltk::Rectangle. This is nice and -easy to implement. The API is pretty much the same in both versions. +(6) Rectangle: FLTK uses discrete coordinates and sizes. FLTK 2's base class is +fltk::Rectangle. This is nice and easy to implement. The API is pretty much the +same in both versions. (7) Styles: FLTK 2 uses a minimal number of styles to define the basic (and often repeated) parameters of every widget. API's are similar though, @@ -184,8 +187,9 @@ correspond, and how they could be implemented in FLTK 3. 2: class Dial *: should map easily -1: +1: class Fl_Box 2: class Divider +*: 1: class Fl_Double_Window 2: class DoubleBufferWindow @@ -194,7 +198,7 @@ correspond, and how they could be implemented in FLTK 3. 1: class Fl_End 2: -1: +1: Fl_Box 2: class EngravedLabel 1: class Fl_File_Browser @@ -326,8 +330,9 @@ correspond, and how they could be implemented in FLTK 3. 1: 2: class InvisibleBox -1: +1: struct Fl_Menu_Item 2: class Item +*: this will be hard to emulate! 1: 2: class ItemGroup @@ -365,7 +370,7 @@ correspond, and how they could be implemented in FLTK 3. 1: class Fl_Menu_Window 2: class MenuWindow -1: +1: class Fl_Screen? 2: class Monitor 1: class Fl_Multi_Browser @@ -382,7 +387,7 @@ correspond, and how they could be implemented in FLTK 3. 2: class MultiLineOutput *: should map easily -1: +1: Fl::lock() 2: class Mutex 1: class Fl_Nice_Slider @@ -408,7 +413,7 @@ correspond, and how they could be implemented in FLTK 3. 1: class Fl_Pack 2: class PackedGroup -*: should map easily, FLTK 2 has soem additional functionaity +*: should map easily, FLTK 2 has some additional functionaity 1: class Fl_Pixmap 2: @@ -683,4 +688,10 @@ correspond, and how they could be implemented in FLTK 3. 1: 2: struct NamedStyle +--- + +This is how to output all symbols in a library (interestingly, this seems +to output symbols for functions that are likely inlined as well) + +> nm -g -j lib/libfltk.a | c++filt | sort -u | more diff --git a/plugins/zynaddsubfx/fltk/README.win32 b/plugins/zynaddsubfx/fltk/README.win32 index f4039f769..efc34443a 100644 --- a/plugins/zynaddsubfx/fltk/README.win32 +++ b/plugins/zynaddsubfx/fltk/README.win32 @@ -1,6 +1,6 @@ README.win32 - Building FLTK under Windows ------------------------------------------ -Last Update: May 2007 for release 1.1.8 +Last Update: July 2010 for release 1.3.x INTRODUCTION @@ -10,24 +10,30 @@ INTRODUCTION the GNU-like build configurations in the "makefiles" subdirectory. + FLTK 1.3 and later is officially supported on Windows + (2000,) 2003, XP, and later. Older Windows versions are + not officially supported, but may still work. The main + reason is that the OS version needs to support UTF-8. + FLTK 1.3 is known to work on Windows 7 and Vista. + FLTK currently supports the following development environments on the Windows platform: - - Microsoft Visual C++ 6.0, VC2005 and VC.NET using the - supplied workspace and project files. Be sure to get - your service packs! + - Free Microsoft Visual C++ 2008 Express and Visual + C++ 2010 Express using the supplied workspace and + project files. Older and the commercial versions can + be used as well, if they can open the project files. + Be sure to get your service packs! - - Borland C++ Builder 5 and 6 using the supplied IDE - files. These files are not as actively maintained as - the VC and GNU versions, so may not work for you. + The project files can be found in the ide/ directory. + Please read ide/README.IDE for more info about this. - - Watcom. There is a partial solution for the Watcom - toolchain. It is no longer actively maintained. + - GNU toolsets (Cygwin or MinGW) hosted on Windows. - - GNU toolsets (Cygwin or MinGW) hosted on Windows - 9x/2000/NT/XP. + - Watcom. There is a partial solution for the Watcom + toolchain. It is no longer actively maintained. - This remainder of this document gives a brief overview of + The remainder of this document gives a brief overview of compiling and using FLTK with the Cygwin and MinGW compiler toolkits. Both toolkits provide a build environment based around the GNU C/C++ compiler. Further information is @@ -50,13 +56,18 @@ INTRODUCTION the Cygwin DLL (compiled and linked with the "-mno-cygwin" option) may be released under any license freely. + Note: Since December 2009, there is a new gcc 4.x compiler + that doesn't support the -mno-cygwin option anymore. You + must use the older gcc-3 compiler instead. + + The MinGW distribution (Minimalist GNU for Windows) provides a similar toolset but geared solely towards native Windows development without the Unix-like POSIX library. The lack of any libraries under the GPL or any other restrictive license means that programs built with the MinGW environment may always be released under any license freely. MinGW also - supplies a Unix-like build environment for Windows, + supplies a Unix-like build environment for Windows, including MSYS (a Bourne-compatible shell) and the standard Unix file utilities (ls, cat, grep, etc.) @@ -178,7 +189,7 @@ WHY DOES A CONSOLE WINDOW APPEAR WHEN I RUN MY PROGRAM (Note: A special case of this exists if running a MinGW application from the command line of an MSYS shell, when an application is able to write to stdout, even if compiled with - "-mwindows".) + "-mwindows". The same applies to Cygwin.) HOW DO I GET OPENGL TO WORK? @@ -194,13 +205,3 @@ HOW DO I GET OPENGL TO WORK? will change this to compile and link in OpenGL. - - - - - - - - - - diff --git a/plugins/zynaddsubfx/fltk/configh.cmake.in b/plugins/zynaddsubfx/fltk/configh.cmake.in index ec5167a15..a490f39f1 100644 --- a/plugins/zynaddsubfx/fltk/configh.cmake.in +++ b/plugins/zynaddsubfx/fltk/configh.cmake.in @@ -1,5 +1,5 @@ /* - * "$Id: configh.cmake.in 6614 2009-01-01 16:11:32Z matt $" + * "$Id: configh.cmake.in 7563 2010-04-28 03:15:47Z greg.ercolano $" * * Configuration file for the Fast Light Tool Kit (FLTK). * @configure_input@ @@ -21,15 +21,17 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. * - * Please report all bugs and problems to "fltk-bugs@fltk.org". + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php */ /* * Where to find files... */ -#define FLTK_DATADIR "@FLTK_DATADIR@" -#define FLTK_DOCDIR "@FLTK_DOCDIR@" +#define FLTK_DATADIR "@PREFIX_DATA@" +#define FLTK_DOCDIR "@PREFIX_DOC@" /* * BORDER_WIDTH: @@ -47,8 +49,6 @@ #define BORDER_WIDTH 2 -#cmakedefine USE_X11 1 - /* * HAVE_GL: * @@ -56,7 +56,7 @@ * OpenGL, and FLTK will be smaller. */ -#define HAVE_GL @HAVE_GL@ +#cmakedefine01 HAVE_GL /* * HAVE_GL_GLU_H: @@ -65,7 +65,15 @@ * (many broken Mesa RPMs do not...) */ -#cmakedefine HAVE_GL_GLU_H @HAVE_GL_GLU_H@ +#cmakedefine01 HAVE_GL_GLU_H + +/* + * HAVE_GLXGETPROCADDRESSARB: + * + * Do you have the OpenGL glXGetProcAddressARB() function? + */ + +#cmakedefine HAVE_GLXGETPROCADDRESSARB /* * USE_COLORMAP: @@ -76,25 +84,29 @@ #define USE_COLORMAP 1 +/* + * HAVE_XINERAMA + * + * Do we have the Xinerama library to support multi-head displays? + */ + +#cmakedefine01 HAVE_XINERAMA + /* * USE_XFT * * Use the new Xft library to draw anti-aliased text. */ -#cmakedefine FOUND_XFT -#ifdef FOUND_XFT -#define USE_XFT 1 -#else -#define USE_XFT 0 -#endif +#cmakedefine01 USE_XFT + /* * HAVE_XDBE: * * Do we have the X double-buffer extension? */ -#define HAVE_XDBE 0 +#cmakedefine01 HAVE_XDBE /* * USE_XDBE: @@ -114,19 +126,20 @@ * other operating systems. */ -#cmakedefine FLTK_APPLE -#ifdef FLTK_APPLE - #cmakedefine FLTK_QUARTZ - #ifdef FLTK_QUARTZ - #define USE_QUARTZ 1 - #define __APPLE_QUARTZ__ - #undef __APPLE_QD__ - #else - #define USE_QUARTZ 0 - #undef __APPLE_QUARTZ__ - #define __APPLE_QD__ - #endif -#endif +#cmakedefine USE_QUARTZ +#cmakedefine __APPLE_QUARTZ__ @__APPLE_QUARTZ__@ +#cmakedefine __APPLE_COCOA__ @__APPLE_COCOA__@ +#cmakedefine __APPLE_QD__ @__APPLE_QD__@ + + +/* + * USE_X11 + * + * Should we use X11 for the current platform + * + */ + +#cmakedefine USE_X11 @USE_X11@ /* * HAVE_OVERLAY: @@ -154,7 +167,7 @@ * Byte order of your machine: 1 = big-endian, 0 = little-endian. */ -#define WORDS_BIGENDIAN 0 +#define WORDS_BIGENDIAN @WORDS_BIGENDIAN@ /* * U16, U32, U64: @@ -168,7 +181,8 @@ #cmakedefine U64 @U64@ /* - * HAVE_DIRENT_H, HAVE_SYS_NDIR_H, HAVE_SYS_DIR_H, HAVE_NDIR_H, HAVE_SCANDIR: + * HAVE_DIRENT_H, HAVE_SYS_NDIR_H, HAVE_SYS_DIR_H, HAVE_NDIR_H, + * HAVE_SCANDIR, HAVE_SCANDIR_POSIX: * * Where is (used only by fl_file_chooser and scandir). */ @@ -178,6 +192,7 @@ #cmakedefine HAVE_SYS_DIR_H @HAVE_SYS_DIR_H@ #cmakedefine HAVE_NDIR_H @HAVE_NDIR_H@ #cmakedefine HAVE_SCANDIR @HAVE_SCANDIR@ +#cmakedefine HAVE_SCANDIR_POSIX @HAVE_SCANDIR_POSIX@ /* * Possibly missing sprintf-style functions: @@ -196,7 +211,7 @@ #cmakedefine HAVE_STRLCPY @HAVE_STRLCPY@ /* - * 'locale' functions + * Do we have POSIX locale support? */ #cmakedefine HAVE_LOCALE_H @HAVE_LOCALE_H@ @@ -208,7 +223,7 @@ * Whether or not select() call has its own header file. */ -#cmakedefine HAVE_SYS_SELECT_H @HAVE_SYS_SELECT_H@ +#cmakedefine01 HAVE_SYS_SELECT_H /* * HAVE_SYS_STDTYPES_H: @@ -224,7 +239,7 @@ * Use the poll() call provided on Linux and Irix instead of select() */ -#define USE_POLL 0 +#cmakedefine01 USE_POLL /* * Do we have various image libraries? @@ -234,6 +249,23 @@ #cmakedefine HAVE_LIBZ @HAVE_LIBZ@ #cmakedefine HAVE_LIBJPEG @HAVE_LIBJPEG@ +/* + * USE_CAIRO + * + * Do we have the cairo library available and want extended cairo use in fltk ? + * will implies to link cairo.lib in all fltk based apps. + */ + +#cmakedefine USE_CAIRO @USE_CAIRO@ + +/* + * HAVE_CAIRO + * + * Do we have the cairo library available? + */ + +#cmakedefine HAVE_CAIRO @HAVE_CAIRO@ + /* * Which header file do we include for libpng? */ @@ -252,20 +284,45 @@ * Do we have POSIX threading? */ -#cmakedefine CMAKE_USE_PTHREADS -#ifdef CMAKE_USE_PTHREADS -#define HAVE_PTHREAD 1 -#else -#define HAVE_PTHREAD 0 -#endif - -#cmakedefine CMAKE_HAVE_PTHREAD_H -#ifdef CMAKE_HAVE_PTHREAD_H -#define HAVE_PTHREAD_H 1 -#else -#define HAVE_PTHREAD_H 0 -#endif +#cmakedefine HAVE_PTHREAD @HAVE_PTHREAD@ +#cmakedefine01 HAVE_PTHREAD_H /* - * End of "$Id: configh.cmake.in 6614 2009-01-01 16:11:32Z matt $". + * Do we have the ALSA library? + */ + +#cmakedefine HAVE_ALSA_ASOUNDLIB_H @HAVE_ALSA_ASOUNDLIB_H@ +/* + * Do we have the long long type? + */ + +#cmakedefine HAVE_LONG_LONG @HAVE_LONG_LONG@ + +#ifdef HAVE_LONG_LONG +# define FLTK_LLFMT "%lld" +# define FLTK_LLCAST (long long) +#else +# define FLTK_LLFMT "%ld" +# define FLTK_LLCAST (long) +#endif /* HAVE_LONG_LONG */ + +/* + * Do we have the strtoll() function? + */ + +#cmakedefine HAVE_STRTOLL @HAVE_STRTOLL@ + +#ifndef HAVE_STRTOLL +# define strtoll(nptr,endptr,base) strtol((nptr), (endptr), (base)) +#endif /* !HAVE_STRTOLL */ + +/* + * Do we have the dlsym() function and header? + */ + +#cmakedefine HAVE_DLFCN_H @HAVE_DLFCN_H@ +#cmakedefine HAVE_DLSYM @HAVE_DLSYM@ + +/* + * End of "$Id: configh.cmake.in 7563 2010-04-28 03:15:47Z greg.ercolano $". */ diff --git a/plugins/zynaddsubfx/fltk/fltk-config b/plugins/zynaddsubfx/fltk/fltk-config new file mode 100755 index 000000000..10330bf6f --- /dev/null +++ b/plugins/zynaddsubfx/fltk/fltk-config @@ -0,0 +1,388 @@ +#!/bin/sh +# +# "$Id: fltk-config.in 6614 2009-01-01 16:11:32Z matt $" +# +# FLTK configuration utility. +# +# Copyright 2000-2009 by Bill Spitzak and others. +# Original version Copyright 2000 by James Dean Palmer +# Adapted by Vincent Penne and Michael Sweet +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA. +# +# Please report all bugs and problems on the following page: +# +# http://www.fltk.org/str.php +# + +MAJOR_VERSION=1 +MINOR_VERSION=3 +PATCH_VERSION=0 +VERSION="$MAJOR_VERSION.$MINOR_VERSION.$PATCH_VERSION" +APIVERSION="$MAJOR_VERSION.$MINOR_VERSION" + +### BEGIN fltk-config +selfdir=`dirname "$0"` + +prefix=/usr +exec_prefix=${prefix} +exec_prefix_set=no +bindir=${exec_prefix}/bin +includedir=${prefix}/include +libdir=${exec_prefix}/lib +srcdir=. + +# compiler names +CC="gcc" +CXX="g++" + +# flags for C++ compiler: +ARCHFLAGS="" +CFLAGS=" -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_THREAD_SAFE -D_REENTRANT" +CXXFLAGS="-I/usr/include/freetype2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_THREAD_SAFE -D_REENTRANT" +LDFLAGS=" " +LDLIBS="-lXext -lXft -lfontconfig -lXinerama -lpthread -ldl -lm -lX11 " +OPTIM=" -Os -Wall -Wunused -Wno-format-y2k -fno-exceptions -fno-strict-aliasing" +CAIROFLAGS="" + +# Check for local invocation, and update paths accordingly... +if test -f "$selfdir/FL/Fl_Window.H"; then + bindir="$selfdir/fluid" + includedir="$selfdir" + libdir="$selfdir/lib" + + if test -f "$libdir/libfltk_jpeg.a"; then + CFLAGS="-I$includedir/jpeg $CFLAGS" + CXXFLAGS="-I$includedir/jpeg $CXXFLAGS" + fi + + if test -f "$libdir/libfltk_z.a"; then + CFLAGS="-I$includedir/zlib $CFLAGS" + CXXFLAGS="-I$includedir/zlib $CXXFLAGS" + fi + + if test -f "$libdir/libfltk_png.a"; then + CFLAGS="-I$includedir/png $CFLAGS" + CXXFLAGS="-I$includedir/png $CXXFLAGS" + fi +fi + +if test -d $includedir/FL/images; then + CFLAGS="-I$includedir/FL/images $CFLAGS" + CXXFLAGS="-I$includedir/FL/images $CXXFLAGS" +fi + +if test -f "$libdir/libfltk_cairo.a"; then + CFLAGS="$CAIROFLAGS $CFLAGS" + CXXFLAGS="$CAIROFLAGS $CXXFLAGS" +fi + +# libraries to link with: +LIBNAME="../lib/libfltk.a" +DSONAME="" +DSOLINK="" +IMAGELIBS="-lpng -lz -ljpeg " +STATICIMAGELIBS="-lpng -lz -ljpeg " +CAIROLIBS="" +SHAREDSUFFIX="" + +usage () +{ + echo "Usage: fltk-config [OPTIONS] +Options: + [--version] + [--api-version] + +Options telling what we are doing: + [--use-gl] use GL + [--use-images] use extra image formats (PNG, JPEG) + [--use-glut] use glut compatibility layer + [--use-forms] use forms compatibility layer + [--use-cairo] use cairo graphics lib + +Options telling what information we request: + [--cc] return C compiler used to compile FLTK + [--cxx] return C++ compiler used to compile FLTK + [--optim] return compiler optimization used to compile FLTK + [--cflags] return flags to compile C using FLTK + [--cxxflags] return flags to compile C++ using FLTK + [--ldflags] return flags to link against FLTK + [--ldstaticflags] return flags to link against static FLTK library + even if there are DSOs installed + [--libs] return FLTK libraries full path for dependencies + +Options to compile and link an application: + [-g] compile the program with debugging information + [-Dname[=value]] compile the program with the given define + [--compile program.cxx] + [--post program] prepare the program for desktop use +" + exit $1 +} + +if test $# -eq 0; then + usage 1 +fi + +no_plugins=no +compile= +post= +debug= + +# Parse command line options +while test $# -gt 0 +do + case "$1" in + -*=*) + optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` + ;; + *) + optarg= + ;; + esac + + case $1 in + --version) + echo $VERSION + ;; + --api-version) + echo $APIVERSION + ;; + --cc) + echo $CC + ;; + --cxx) + echo $CXX + ;; + --optim) + echo_optim=yes + ;; + --use-gl | --use-glut) + use_gl=yes + ;; + --use-forms) + use_forms=yes + ;; + --use-images) + use_images=yes + ;; + --use-cairo) + use_cairo=yes + ;; + --cflags) + echo_cflags=yes + ;; + --cxxflags) + echo_cxxflags=yes + ;; + --ldflags) + echo_ldflags=yes + ;; + --ldstaticflags) + echo_ldstaticflags=yes + ;; + --libs) + echo_libs=yes + ;; + -g) + debug=-g + ;; + -D*) + CXXFLAGS="$CXXFLAGS $1" + ;; + --compile) + compile="$2" + shift + ;; + --post) + post="$2" + shift + ;; + *) + echo_help=yes + ;; + esac + shift +done + +if test "$includedir" != /usr/include; then + includes=-I$includedir +else + includes= +fi + +if test "$libdir" != /usr/lib -a "$libdir" != /usr/lib32; then + libs=-L$libdir +else + libs= +fi + +# Calculate needed libraries +LDSTATIC="$libdir/libfltk.a $LDLIBS" +LDLIBS="-lfltk$SHAREDSUFFIX $LDLIBS" + +if test x$use_forms = xyes; then + LDLIBS="-lfltk_forms$SHAREDSUFFIX $LDLIBS" + LDSTATIC="$libdir/libfltk_forms.a $LDSTATIC" +fi +if test x$use_gl = xyes; then + LDLIBS="-lfltk_gl$SHAREDSUFFIX -lGLU -lGL $LDLIBS" + LDSTATIC="$libdir/libfltk_gl.a -lGLU -lGL $LDSTATIC" +fi +if test x$use_images = xyes; then + LDLIBS="-lfltk_images$SHAREDSUFFIX $IMAGELIBS $LDLIBS" + LDSTATIC="$libdir/libfltk_images.a $STATICIMAGELIBS $LDSTATIC" +fi + +if test x$use_cairo = xyes; then + LDLIBS="-lfltk_cairo$SHAREDSUFFIX $CAIROLIBS $LDLIBS" + LDSTATIC="$libdir/libfltk_cairo.a $CAIROLIBS $LDSTATIC" +fi + +LDLIBS="$DSOLINK $LDFLAGS $libs $LDLIBS" +LDSTATIC="$LDFLAGS $LDSTATIC" + +# Answer to user requests +if test -n "$echo_help"; then + usage 1 +fi + +if test -n "$compile"; then + case "$compile" in + *.cxx) + prog="`basename \"$compile\" .cxx`" + ;; + *.cpp) + prog="`basename \"$compile\" .cpp`" + ;; + *.cc) + prog="`basename \"$compile\" .cc`" + ;; + *.C) + prog="`basename \"$compile\" .C`" + ;; + *) + echo "ERROR: Unknown/bad C++ source file extension on \"$compile\"!" + exit 1 + ;; + esac + + post="$prog" + + echo $CXX $ARCHFLAGS $includes $CXXFLAGS $debug -o "'$prog'" "'$compile'" $LDSTATIC + $CXX $ARCHFLAGS $includes $CXXFLAGS $debug -o "$prog" "$compile" $LDSTATIC || exit 1 +fi + +if test -n "$post"; then + case "`uname`" in + Darwin) + echo Creating "'$post.app'" bundle for desktop... + id=`echo $post | tr ' ' '_'` + + # Make the bundle directory and move the executable there + rm -rf "$post.app/Contents/MacOS" + mkdir -p "$post.app/Contents/MacOS" + mv "$post" "$post.app/Contents/MacOS" + + # Make a shell script that runs the bundled executable + echo "#!/bin/sh" >"$post" + echo 'dir="`dirname '"'"'$0'"'"'`"' >>"$post" + echo 'exec "$dir/'"$post.app/Contents/MacOS/$post"'" "$@"' >>"$post" + chmod +x "$post" + + # Make the simplest Info.plist needed for an application + cat >"$post.app/Contents/Info.plist" < + + + CFBundleInfoDictionaryVersion + 6.0 + CFBundleExecutable + $post + CFBundleIdentifier + org.fltk.$id + CFBundleName + $post + CFBundlePackageType + APPL + + +EOF + ;; + esac +fi + +if test "$echo_cflags" = "yes"; then + echo $includes $CFLAGS +fi + +if test "$echo_cxxflags" = "yes"; then + echo $includes $CXXFLAGS +fi + +if test "$echo_optim" = "yes"; then + echo $OPTIM +fi + +if test "$echo_ldflags" = "yes"; then + my_libs= + libdirs=$libs + + for i in $LDLIBS ; do + if test $i != -L$libdir ; then + if test -z "$my_libs" ; then + my_libs="$i" + else + my_libs="$my_libs $i" + fi + fi + done + echo $libdirs $my_libs +fi + +if test "$echo_ldstaticflags" = "yes"; then + echo $LDSTATIC +fi + +if test "$echo_libs" = "yes"; then + echo $libdir/libfltk.a + + if test x$use_forms = xyes; then + echo $libdir/libfltk_forms.a + fi + + if test x$use_gl = xyes; then + echo $libdir/libfltk_gl.a + fi + + if test x$use_cairo = xyes; then + echo $libdir/libfltk_cairo.a + fi + + if test x$use_images = xyes; then + echo $libdir/libfltk_images.a + + for lib in fltk_jpeg fltk_png fltk_z; do + if test -f $libdir/lib$lib.a; then + echo $libdir/lib$lib.a + fi + done + fi +fi + +# +# End of "$Id: fltk-config.in 6614 2009-01-01 16:11:32Z matt $". +# diff --git a/plugins/zynaddsubfx/fltk/fltk-config.cmake.in b/plugins/zynaddsubfx/fltk/fltk-config.cmake.in new file mode 100644 index 000000000..500ad785c --- /dev/null +++ b/plugins/zynaddsubfx/fltk/fltk-config.cmake.in @@ -0,0 +1,388 @@ +#!/bin/sh +# +# "$Id: fltk-config.in 6614 2009-01-01 16:11:32Z matt $" +# +# FLTK configuration utility. +# +# Copyright 2000-2009 by Bill Spitzak and others. +# Original version Copyright 2000 by James Dean Palmer +# Adapted by Vincent Penne and Michael Sweet +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA. +# +# Please report all bugs and problems on the following page: +# +# http://www.fltk.org/str.php +# + +MAJOR_VERSION=@FLTK_VERSION_MAJOR@ +MINOR_VERSION=@FLTK_VERSION_MINOR@ +PATCH_VERSION=@FLTK_VERSION_PATCH@ +VERSION=@FLTK_VERSION_FULL@ +APIVERSION=@FLTK_VERSION@ + +### BEGIN fltk-config +selfdir=`dirname "$0"` + +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +exec_prefix_set=no +bindir=@PREFIX_BIN@ +includedir=@CPREFIX_INCLUDE@ +libdir=@PREFIX_LIB@ +srcdir=. + +# compiler names +CC="@CC@" +CXX="@CXX@" + +# flags for C++ compiler: +ARCHFLAGS="@OPTION_ARCHFLAGS@" +CFLAGS="@C_FLAGS@" +CXXFLAGS="@CAIROFLAGS@@C_FLAGS@" +LDFLAGS="@LDFLAGS@" +LDLIBS="@LD_LIBS@" +OPTIM="@OPTION_OPTIM@" +CAIROFLAGS="@CAIROFLAGS@" + +# Check for local invocation, and update paths accordingly... +if test -f "$selfdir/FL/Fl_Window.H"; then + bindir="$selfdir/fluid" + includedir="$selfdir" + libdir="$selfdir/lib" + + if test -f "$libdir/libfltk_jpeg.a"; then + CFLAGS="-I$includedir/jpeg $CFLAGS" + CXXFLAGS="-I$includedir/jpeg $CXXFLAGS" + fi + + if test -f "$libdir/libfltk_z.a"; then + CFLAGS="-I$includedir/zlib $CFLAGS" + CXXFLAGS="-I$includedir/zlib $CXXFLAGS" + fi + + if test -f "$libdir/libfltk_png.a"; then + CFLAGS="-I$includedir/png $CFLAGS" + CXXFLAGS="-I$includedir/png $CXXFLAGS" + fi +fi + +if test -d $includedir/FL/images; then + CFLAGS="-I$includedir/FL/images $CFLAGS" + CXXFLAGS="-I$includedir/FL/images $CXXFLAGS" +fi + +if test -f "$libdir/libfltk_cairo.a"; then + CFLAGS="$CAIROFLAGS $CFLAGS" + CXXFLAGS="$CAIROFLAGS $CXXFLAGS" +fi + +# libraries to link with: +LIBNAME="@LIBNAME@" +DSONAME="@DSONAME@" +DSOLINK="@DSOLINK@" +IMAGELIBS="@IMAGELIBS@" +STATICIMAGELIBS="@STATICIMAGELIBS@" +CAIROLIBS="@CAIROLIBS@" +SHAREDSUFFIX="@SHAREDSUFFIX@" + +usage () +{ + echo "Usage: fltk-config [OPTIONS] +Options: + [--version] + [--api-version] + +Options telling what we are doing: + [--use-gl] use GL + [--use-images] use extra image formats (PNG, JPEG) + [--use-glut] use glut compatibility layer + [--use-forms] use forms compatibility layer + [--use-cairo] use cairo graphics lib + +Options telling what information we request: + [--cc] return C compiler used to compile FLTK + [--cxx] return C++ compiler used to compile FLTK + [--optim] return compiler optimization used to compile FLTK + [--cflags] return flags to compile C using FLTK + [--cxxflags] return flags to compile C++ using FLTK + [--ldflags] return flags to link against FLTK + [--ldstaticflags] return flags to link against static FLTK library + even if there are DSOs installed + [--libs] return FLTK libraries full path for dependencies + +Options to compile and link an application: + [-g] compile the program with debugging information + [-Dname[=value]] compile the program with the given define + [--compile program.cxx] + [--post program] prepare the program for desktop use +" + exit $1 +} + +if test $# -eq 0; then + usage 1 +fi + +no_plugins=no +compile= +post= +debug= + +# Parse command line options +while test $# -gt 0 +do + case "$1" in + -*=*) + optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` + ;; + *) + optarg= + ;; + esac + + case $1 in + --version) + echo $VERSION + ;; + --api-version) + echo $APIVERSION + ;; + --cc) + echo $CC + ;; + --cxx) + echo $CXX + ;; + --optim) + echo_optim=yes + ;; + --use-gl | --use-glut) + use_gl=yes + ;; + --use-forms) + use_forms=yes + ;; + --use-images) + use_images=yes + ;; + --use-cairo) + use_cairo=yes + ;; + --cflags) + echo_cflags=yes + ;; + --cxxflags) + echo_cxxflags=yes + ;; + --ldflags) + echo_ldflags=yes + ;; + --ldstaticflags) + echo_ldstaticflags=yes + ;; + --libs) + echo_libs=yes + ;; + -g) + debug=-g + ;; + -D*) + CXXFLAGS="$CXXFLAGS $1" + ;; + --compile) + compile="$2" + shift + ;; + --post) + post="$2" + shift + ;; + *) + echo_help=yes + ;; + esac + shift +done + +if test "$includedir" != /usr/include; then + includes=-I$includedir +else + includes= +fi + +if test "$libdir" != /usr/lib -a "$libdir" != /usr/lib32; then + libs=-L$libdir +else + libs= +fi + +# Calculate needed libraries +LDSTATIC="$libdir/libfltk.a $LDLIBS" +LDLIBS="-lfltk$SHAREDSUFFIX $LDLIBS" + +if test x$use_forms = xyes; then + LDLIBS="-lfltk_forms$SHAREDSUFFIX $LDLIBS" + LDSTATIC="$libdir/libfltk_forms.a $LDSTATIC" +fi +if test x$use_gl = xyes; then + LDLIBS="-lfltk_gl$SHAREDSUFFIX @GLLIB@ $LDLIBS" + LDSTATIC="$libdir/libfltk_gl.a @GLLIB@ $LDSTATIC" +fi +if test x$use_images = xyes; then + LDLIBS="-lfltk_images$SHAREDSUFFIX $IMAGELIBS $LDLIBS" + LDSTATIC="$libdir/libfltk_images.a $STATICIMAGELIBS $LDSTATIC" +fi + +if test x$use_cairo = xyes; then + LDLIBS="-lfltk_cairo$SHAREDSUFFIX $CAIROLIBS $LDLIBS" + LDSTATIC="$libdir/libfltk_cairo.a $CAIROLIBS $LDSTATIC" +fi + +LDLIBS="$DSOLINK $LDFLAGS $libs $LDLIBS" +LDSTATIC="$LDFLAGS $LDSTATIC" + +# Answer to user requests +if test -n "$echo_help"; then + usage 1 +fi + +if test -n "$compile"; then + case "$compile" in + *.cxx) + prog="`basename \"$compile\" .cxx`" + ;; + *.cpp) + prog="`basename \"$compile\" .cpp`" + ;; + *.cc) + prog="`basename \"$compile\" .cc`" + ;; + *.C) + prog="`basename \"$compile\" .C`" + ;; + *) + echo "ERROR: Unknown/bad C++ source file extension on \"$compile\"!" + exit 1 + ;; + esac + + post="$prog" + + echo $CXX $ARCHFLAGS $includes $CXXFLAGS $debug -o "'$prog'" "'$compile'" $LDSTATIC + $CXX $ARCHFLAGS $includes $CXXFLAGS $debug -o "$prog" "$compile" $LDSTATIC || exit 1 +fi + +if test -n "$post"; then + case "`uname`" in + Darwin) + echo Creating "'$post.app'" bundle for desktop... + id=`echo $post | tr ' ' '_'` + + # Make the bundle directory and move the executable there + rm -rf "$post.app/Contents/MacOS" + mkdir -p "$post.app/Contents/MacOS" + mv "$post" "$post.app/Contents/MacOS" + + # Make a shell script that runs the bundled executable + echo "#!/bin/sh" >"$post" + echo 'dir="`dirname '"'"'$0'"'"'`"' >>"$post" + echo 'exec "$dir/'"$post.app/Contents/MacOS/$post"'" "$@"' >>"$post" + chmod +x "$post" + + # Make the simplest Info.plist needed for an application + cat >"$post.app/Contents/Info.plist" < + + + CFBundleInfoDictionaryVersion + 6.0 + CFBundleExecutable + $post + CFBundleIdentifier + org.fltk.$id + CFBundleName + $post + CFBundlePackageType + APPL + + +EOF + ;; + esac +fi + +if test "$echo_cflags" = "yes"; then + echo $includes $CFLAGS +fi + +if test "$echo_cxxflags" = "yes"; then + echo $includes $CXXFLAGS +fi + +if test "$echo_optim" = "yes"; then + echo $OPTIM +fi + +if test "$echo_ldflags" = "yes"; then + my_libs= + libdirs=$libs + + for i in $LDLIBS ; do + if test $i != -L$libdir ; then + if test -z "$my_libs" ; then + my_libs="$i" + else + my_libs="$my_libs $i" + fi + fi + done + echo $libdirs $my_libs +fi + +if test "$echo_ldstaticflags" = "yes"; then + echo $LDSTATIC +fi + +if test "$echo_libs" = "yes"; then + echo $libdir/libfltk.a + + if test x$use_forms = xyes; then + echo $libdir/libfltk_forms.a + fi + + if test x$use_gl = xyes; then + echo $libdir/libfltk_gl.a + fi + + if test x$use_cairo = xyes; then + echo $libdir/libfltk_cairo.a + fi + + if test x$use_images = xyes; then + echo $libdir/libfltk_images.a + + for lib in fltk_jpeg fltk_png fltk_z; do + if test -f $libdir/lib$lib.a; then + echo $libdir/lib$lib.a + fi + done + fi +fi + +# +# End of "$Id: fltk-config.in 6614 2009-01-01 16:11:32Z matt $". +# diff --git a/plugins/zynaddsubfx/fltk/fltk-config.in b/plugins/zynaddsubfx/fltk/fltk-config.in index 0c9eef992..3bc1ae772 100644 --- a/plugins/zynaddsubfx/fltk/fltk-config.in +++ b/plugins/zynaddsubfx/fltk/fltk-config.in @@ -232,19 +232,19 @@ fi # Calculate needed libraries LDSTATIC="$libdir/libfltk.a $LDLIBS" -LDLIBS="-lfltk$SHAREDSUFFIX" +LDLIBS="-lfltk$SHAREDSUFFIX $LDLIBS" if test x$use_forms = xyes; then LDLIBS="-lfltk_forms$SHAREDSUFFIX $LDLIBS" LDSTATIC="$libdir/libfltk_forms.a $LDSTATIC" fi if test x$use_gl = xyes; then - LDLIBS="-lfltk_gl$SHAREDSUFFIX $LDLIBS" + LDLIBS="-lfltk_gl$SHAREDSUFFIX @GLLIB@ $LDLIBS" LDSTATIC="$libdir/libfltk_gl.a @GLLIB@ $LDSTATIC" fi if test x$use_images = xyes; then - LDLIBS="-lfltk_images$SHAREDSUFFIX $LDLIBS" - LDSTATIC="$libdir/libfltk_images.a $IMAGELIBS $LDSTATIC" + LDLIBS="-lfltk_images$SHAREDSUFFIX $IMAGELIBS $LDLIBS" + LDSTATIC="$libdir/libfltk_images.a $STATICIMAGELIBS $LDSTATIC" fi if test x$use_cairo = xyes; then diff --git a/plugins/zynaddsubfx/fltk/fltk-diff.diff b/plugins/zynaddsubfx/fltk/fltk-diff.diff new file mode 100644 index 000000000..341a0e57d --- /dev/null +++ b/plugins/zynaddsubfx/fltk/fltk-diff.diff @@ -0,0 +1,126 @@ +diff -upr /home/toby/development/svn/fltk/branch-1.3-r6970/src//CMakeLists.txt src//CMakeLists.txt +--- /home/toby/development/svn/fltk/branch-1.3-r6970/src//CMakeLists.txt 2010-07-26 12:08:34.947829872 +0200 ++++ src//CMakeLists.txt 2010-07-26 12:10:34.290829872 +0200 +@@ -1,3 +1,7 @@ ++IF(COMMAND cmake_policy) ++ cmake_policy(SET CMP0003 NEW) ++ENDIF(COMMAND cmake_policy) ++ + SET(CPPFILES + Fl.cxx + Fl_Adjuster.cxx +@@ -190,30 +194,30 @@ IF(X11_FOUND) + TARGET_LINK_LIBRARIES(fltk ${X11_LIBRARIES}) + ENDIF(X11_FOUND) + +-IF(OPENGL_FOUND) +- ADD_LIBRARY(fltk_gl ${GLCPPFILES}) +- INSTALL_TARGETS(/lib fltk_gl) +- TARGET_LINK_LIBRARIES(fltk_gl fltk ${OPENGL_LIBRARIES}) +- SET_TARGET_PROPERTIES(fltk_gl +- PROPERTIES +- VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} +- SOVERSION ${FLTK_VERSION_PATCH}) +-ENDIF(OPENGL_FOUND) +- +-ADD_LIBRARY(fltk_forms ${FLCPPFILES}) +-INSTALL_TARGETS(/lib fltk_forms) +-TARGET_LINK_LIBRARIES(fltk_forms fltk) +-SET_TARGET_PROPERTIES(fltk_forms +- PROPERTIES +- VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} +- SOVERSION ${FLTK_VERSION_PATCH}) +- +-ADD_LIBRARY(fltk_images ${IMGCPPFILES}) +-INSTALL_TARGETS(/lib fltk_images) +-TARGET_LINK_LIBRARIES(fltk_images fltk ${FLTK_PNG_LIBRARIES} +- ${FLTK_JPEG_LIBRARIES} ${FLTK_ZLIB_LIBRARIES}) +-SET_TARGET_PROPERTIES(fltk_images +- PROPERTIES +- VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} +- SOVERSION ${FLTK_VERSION_PATCH}) +- ++#IF(OPENGL_FOUND) ++# ADD_LIBRARY(fltk_gl ${GLCPPFILES}) ++# INSTALL_TARGETS(/lib fltk_gl) ++# TARGET_LINK_LIBRARIES(fltk_gl fltk ${OPENGL_LIBRARIES}) ++# SET_TARGET_PROPERTIES(fltk_gl ++# PROPERTIES ++# VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} ++# SOVERSION ${FLTK_VERSION_PATCH}) ++#ENDIF(OPENGL_FOUND) ++ ++#ADD_LIBRARY(fltk_forms ${FLCPPFILES}) ++#INSTALL_TARGETS(/lib fltk_forms) ++#TARGET_LINK_LIBRARIES(fltk_forms fltk) ++#SET_TARGET_PROPERTIES(fltk_forms ++# PROPERTIES ++# VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} ++# SOVERSION ${FLTK_VERSION_PATCH}) ++# ++#ADD_LIBRARY(fltk_images ${IMGCPPFILES}) ++#INSTALL_TARGETS(/lib fltk_images) ++#TARGET_LINK_LIBRARIES(fltk_images fltk ${FLTK_PNG_LIBRARIES} ++# ${FLTK_JPEG_LIBRARIES} ${FLTK_ZLIB_LIBRARIES}) ++#SET_TARGET_PROPERTIES(fltk_images ++# PROPERTIES ++# VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} ++# SOVERSION ${FLTK_VERSION_PATCH}) ++# +diff -upr /home/toby/development/svn/fltk/branch-1.3-r6970/src//filename_list.cxx src//filename_list.cxx +--- /home/toby/development/svn/fltk/branch-1.3-r6970/src//filename_list.cxx 2010-07-26 12:08:34.596829871 +0200 ++++ src//filename_list.cxx 2010-07-26 12:10:34.343829872 +0200 +@@ -77,8 +77,8 @@ int fl_filename_list(const char *d, dire + Fl_File_Sort_F *sort) { + #ifndef HAVE_SCANDIR + int n = scandir(d, list, 0, sort); +-#elif defined(HAVE_SCANDIR_POSIX) +- // POSIX (2008) defines the comparison function like this: ++#elif defined(__hpux) || defined(__CYGWIN__) || (__GLIBC__ >= 2 && __GLIBC_MINOR__ >= 10 ) ++ // HP-UX, Cygwin and POSIX (2008) define the comparison function like this: + int n = scandir(d, list, 0, (int(*)(const dirent **, const dirent **))sort); + #elif defined(__osf__) + // OSF, DU 4.0x +diff -upr /home/toby/development/svn/fltk/branch-1.3-r6970/src//fl_font_xft.cxx src//fl_font_xft.cxx +--- /home/toby/development/svn/fltk/branch-1.3-r6970/src//fl_font_xft.cxx 2010-07-26 12:08:34.594829871 +0200 ++++ src//fl_font_xft.cxx 2010-07-26 12:10:34.355829872 +0200 +@@ -128,6 +128,8 @@ void fl_font(Fl_Font fnum, Fl_Fontsize s + fl_fontsize = f; + #if XFT_MAJOR < 2 + fl_xfont = f->font->u.core.font; ++#else ++ fl_xfont = NULL; // invalidate + #endif // XFT_MAJOR < 2 + fl_xftfont = (void*)f->font; + } +@@ -413,6 +415,19 @@ static XFontStruct* load_xfont_for_xft2( + default: name--; // no prefix, restore name + } + ++ // map generic Xft names to customary XLFD faces ++ if (!strcmp(name, "sans")) { ++ name = "helvetica"; ++ } else if (!strcmp(name, "mono")) { ++ name = "courier"; ++ } else if (!strcmp(name, "serif")) { ++ name = "times"; ++ } else if (!strcmp(name, "screen")) { ++ name = "lucidatypewriter"; ++ } else if (!strcmp(name, "dingbats")) { ++ name = "zapf dingbats"; ++ } ++ + // first, we do a query with no prefered size, to see if the font exists at all + snprintf(xlfd, 128, "-*-*%s*-%s-%c-*--*-*-*-*-*-*-*-*", name, weight, slant); // make up xlfd style name + xgl_font = XLoadQueryFont(fl_display, xlfd); +diff -upr /home/toby/development/svn/fltk/branch-1.3-r6970/src//Fl_lock.cxx src//Fl_lock.cxx +--- /home/toby/development/svn/fltk/branch-1.3-r6970/src//Fl_lock.cxx 2009-05-31 13:06:24.000000000 +0200 ++++ src//Fl_lock.cxx 2010-07-26 12:10:34.335829872 +0200 +@@ -187,6 +187,7 @@ int Fl::awake(Fl_Awake_Handler func, voi + See also: \ref advanced_multithreading + */ + #ifdef WIN32 ++# include + # include + # include + # include diff --git a/plugins/zynaddsubfx/fltk/fltk.list.in b/plugins/zynaddsubfx/fltk/fltk.list.in index 5f3d27758..2a834ce39 100644 --- a/plugins/zynaddsubfx/fltk/fltk.list.in +++ b/plugins/zynaddsubfx/fltk/fltk.list.in @@ -235,6 +235,7 @@ l 0000 root sys $includedir/FL/Enumerations.h Enumerations.H l 0000 root sys $includedir/FL/Fl.h Fl.H l 0000 root sys $includedir/FL/Fl_Adjuster.h Fl_Adjuster.H l 0000 root sys $includedir/FL/Fl_Bitmap.h Fl_Bitmap.H +l 0000 root sys $includedir/FL/Fl_BMP_Image.h Fl_BMP_Image.H l 0000 root sys $includedir/FL/Fl_Box.h Fl_Box.H l 0000 root sys $includedir/FL/Fl_Browser.h Fl_Browser.H l 0000 root sys $includedir/FL/Fl_Browser_.h Fl_Browser_.H @@ -257,6 +258,8 @@ l 0000 root sys $includedir/FL/Fl_Float_Input.h Fl_Float_Input.H l 0000 root sys $includedir/FL/Fl_FormsBitmap.h Fl_FormsBitmap.H l 0000 root sys $includedir/FL/Fl_FormsPixmap.h Fl_FormsPixmap.H l 0000 root sys $includedir/FL/Fl_Free.h Fl_Free.H +l 0000 root sys $includedir/FL/Fl_GIF_Image.h Fl_GIF_Image.H +l 0000 root sys $includedir/FL/Fl_Gl_Window.h Fl_Gl_Window.H l 0000 root sys $includedir/FL/Fl_Group.h Fl_Group.H l 0000 root sys $includedir/FL/Fl_Help_Dialog.h Fl_Help_Dialog.H l 0000 root sys $includedir/FL/Fl_Help_View.h Fl_Help_View.H @@ -266,6 +269,7 @@ l 0000 root sys $includedir/FL/Fl_Hor_Nice_Slider.h Fl_Hor_Nice_Slider.H l 0000 root sys $includedir/FL/Fl_Hor_Slider.h Fl_Hor_Slider.H l 0000 root sys $includedir/FL/Fl_Hor_Value_Slider.h Fl_Hor_Value_Slider.H l 0000 root sys $includedir/FL/Fl_Image.h Fl_Image.H +l 0000 root sys $includedir/FL/Fl_JPEG_Image.h Fl_JPEG_Image.H l 0000 root sys $includedir/FL/Fl_Input.h Fl_Input.H l 0000 root sys $includedir/FL/Fl_Input_.h Fl_Input_.H l 0000 root sys $includedir/FL/Fl_Input_Choice.h Fl_Input_Choice.H @@ -288,6 +292,8 @@ l 0000 root sys $includedir/FL/Fl_Output.h Fl_Output.H l 0000 root sys $includedir/FL/Fl_Overlay_Window.h Fl_Overlay_Window.H l 0000 root sys $includedir/FL/Fl_Pack.h Fl_Pack.H l 0000 root sys $includedir/FL/Fl_Pixmap.h Fl_Pixmap.H +l 0000 root sys $includedir/FL/Fl_PNG_Image.h Fl_PNG_Image.H +l 0000 root sys $includedir/FL/Fl_PNM_Image.h Fl_PNM_Image.H l 0000 root sys $includedir/FL/Fl_Positioner.h Fl_Positioner.H l 0000 root sys $includedir/FL/Fl_Progress.h Fl_Progress.H l 0000 root sys $includedir/FL/Fl_Radio_Button.h Fl_Radio_Button.H @@ -329,6 +335,9 @@ l 0000 root sys $includedir/FL/fl_file_chooser.H Fl_File_Chooser.H l 0000 root sys $includedir/FL/fl_message.h fl_message.H l 0000 root sys $includedir/FL/fl_show_colormap.h fl_show_colormap.H l 0000 root sys $includedir/FL/fl_show_input.h fl_show_input.H +l 0000 root sys $includedir/FL/forms.h forms.H +l 0000 root sys $includedir/FL/gl_draw.h gl_draw.H +l 0000 root sys $includedir/FL/glut.h glut.H l 0000 root sys $includedir/FL/win32.h win32.H l 0000 root sys $includedir/FL/x.h x.H %system all diff --git a/plugins/zynaddsubfx/fltk/src/CMakeLists.txt b/plugins/zynaddsubfx/fltk/src/CMakeLists.txt index d12f04db2..2f05dd4d7 100644 --- a/plugins/zynaddsubfx/fltk/src/CMakeLists.txt +++ b/plugins/zynaddsubfx/fltk/src/CMakeLists.txt @@ -1,8 +1,6 @@ -IF(COMMAND cmake_policy) - cmake_policy(SET CMP0003 NEW) -ENDIF(COMMAND cmake_policy) +include_regular_expression("[.][cxx|c|h]$") -SET(CPPFILES +set(CPPFILES Fl.cxx Fl_Adjuster.cxx Fl_Bitmap.cxx @@ -18,6 +16,7 @@ SET(CPPFILES Fl_Clock.cxx Fl_Color_Chooser.cxx Fl_Counter.cxx + Fl_Device.cxx Fl_Dial.cxx Fl_Double_Window.cxx Fl_File_Browser.cxx @@ -40,10 +39,13 @@ SET(CPPFILES Fl_Menu_add.cxx Fl_Menu_global.cxx Fl_Multi_Label.cxx + Fl_Native_File_Chooser.cxx Fl_Overlay_Window.cxx Fl_Pack.cxx + Fl_Paged_Device.cxx Fl_Pixmap.cxx Fl_Positioner.cxx + Fl_Printer.cxx Fl_Preferences.cxx Fl_Progress.cxx Fl_Repeat_Button.cxx @@ -55,6 +57,8 @@ SET(CPPFILES Fl_Shared_Image.cxx Fl_Single_Window.cxx Fl_Slider.cxx + Fl_Table.cxx + Fl_Table_Row.cxx Fl_Tabs.cxx Fl_Text_Buffer.cxx Fl_Text_Display.cxx @@ -62,6 +66,10 @@ SET(CPPFILES Fl_Tile.cxx Fl_Tiled_Image.cxx Fl_Tooltip.cxx + Fl_Tree.cxx + Fl_Tree_Item_Array.cxx + Fl_Tree_Item.cxx + Fl_Tree_Prefs.cxx Fl_Valuator.cxx Fl_Value_Input.cxx Fl_Value_Output.cxx @@ -128,21 +136,25 @@ SET(CPPFILES fl_show_colormap.cxx fl_symbols.cxx fl_vertex.cxx + ps_image.cxx screen_xywh.cxx fl_utf8.cxx fl_encoding_latin1.cxx fl_encoding_mac_roman.cxx - ) -SET(FLCPPFILES +) + +set(FLCPPFILES forms_compatability.cxx forms_bitmap.cxx forms_free.cxx forms_fselect.cxx forms_pixmap.cxx forms_timer.cxx - ) -SET(GLCPPFILES +) + +set(GLCPPFILES Fl_Gl_Choice.cxx + Fl_Gl_Device_Plugin.cxx Fl_Gl_Overlay.cxx Fl_Gl_Window.cxx freeglut_geometry.cxx @@ -153,8 +165,9 @@ SET(GLCPPFILES gl_start.cxx glut_compatability.cxx glut_font.cxx - ) -SET(IMGCPPFILES +) + +set(IMGCPPFILES fl_images_core.cxx Fl_BMP_Image.cxx Fl_File_Icon2.cxx @@ -163,10 +176,9 @@ SET(IMGCPPFILES Fl_JPEG_Image.cxx Fl_PNG_Image.cxx Fl_PNM_Image.cxx - ) +) -SET(CFILES - fl_call_main.c +set(CFILES flstring.c scandir.c numericsort.c @@ -179,45 +191,162 @@ SET(CFILES xutf8/utf8Wrap.c xutf8/keysym2Ucs.c fl_utf.c - ) +) -ADD_LIBRARY(fltk ${CPPFILES} ${CFILES}) -INSTALL_TARGETS(/lib fltk) -SET_TARGET_PROPERTIES(fltk - PROPERTIES - VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} - SOVERSION ${FLTK_VERSION_PATCH}) +if(APPLE) + set_source_files_properties( + Fl.cxx Fl_Native_File_Chooser.cxx Fl_Printer.cxx + PROPERTIES COMPILE_FLAGS "-x objective-c++") +endif(APPLE) -TARGET_LINK_LIBRARIES(fltk ${FLTK_PLATFORM_DEPENDENT_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +####################################################################### +add_library(fltk STATIC ${CPPFILES} ${CFILES} fl_call_main.c) +set_target_properties(fltk PROPERTIES CLEAN_DIRECT_OUTPUT 1) +if(MSVC) + if(OPTION_LARGE_FILE) + set_target_properties(fltk PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE) + endif() + set_target_properties(fltk + PROPERTIES + OUTPUT_NAME fltk + DEBUG_OUTPUT_NAME fltkd + ) +endif(MSVC) -IF(X11_FOUND) - TARGET_LINK_LIBRARIES(fltk ${X11_LIBRARIES}) -ENDIF(X11_FOUND) +if(USE_THREADS) + target_link_libraries(fltk ${CMAKE_THREAD_LIBS_INIT}) +endif(USE_THREADS) -#IF(OPENGL_FOUND) -# ADD_LIBRARY(fltk_gl ${GLCPPFILES}) -# INSTALL_TARGETS(/lib fltk_gl) -# TARGET_LINK_LIBRARIES(fltk_gl fltk ${OPENGL_LIBRARIES}) -# SET_TARGET_PROPERTIES(fltk_gl -# PROPERTIES -# VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} -# SOVERSION ${FLTK_VERSION_PATCH}) -#ENDIF(OPENGL_FOUND) +if(USE_X11) + target_link_libraries(fltk ${X11_LIBRARIES}) +endif(USE_X11) -#ADD_LIBRARY(fltk_forms ${FLCPPFILES}) -#INSTALL_TARGETS(/lib fltk_forms) -#TARGET_LINK_LIBRARIES(fltk_forms fltk) -#SET_TARGET_PROPERTIES(fltk_forms -# PROPERTIES -# VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} -# SOVERSION ${FLTK_VERSION_PATCH}) -# -#ADD_LIBRARY(fltk_images ${IMGCPPFILES}) -#INSTALL_TARGETS(/lib fltk_images) -#TARGET_LINK_LIBRARIES(fltk_images fltk ${FLTK_PNG_LIBRARIES} -# ${FLTK_JPEG_LIBRARIES} ${FLTK_ZLIB_LIBRARIES}) -#SET_TARGET_PROPERTIES(fltk_images -# PROPERTIES -# VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} -# SOVERSION ${FLTK_VERSION_PATCH}) -# +if(WIN32) + target_link_libraries(fltk comctl32) +endif(WIN32) + +if(HAVE_CAIRO) + target_link_libraries(fltk fltk_cairo ${PKG_CAIRO_LIBRARIES}) +ENDif(HAVE_CAIRO) + +if(USE_XINERAMA) + target_link_libraries(fltk ${X11_Xinerama_LIB}) +endif(USE_XINERAMA) + +if(USE_XFT) + target_link_libraries(fltk ${X11_Xft_LIB}) +endif(USE_XFT) + +if(LIB_fontconfig) + target_link_libraries(fltk ${LIB_fontconfig}) +endif(LIB_fontconfig) + +####################################################################### + +####################################################################### +install(TARGETS fltk + EXPORT fltk-install + DESTINATION ${PREFIX_LIB} +) + +####################################################################### +####################################################################### +if(OPTION_BUILD_SHARED_LIBS) + +####################################################################### +add_library(fltk_SHARED SHARED ${CPPFILES} ${CFILES}) +set_target_properties(fltk_SHARED + PROPERTIES CLEAN_DIRECT_OUTPUT 1 + VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} + SOVERSION ${FLTK_VERSION_PATCH} +) +if(MSVC) + set_target_properties(fltk_SHARED + PROPERTIES + OUTPUT_NAME fltkdll + DEBUG_OUTPUT_NAME fltkdlld + COMPILE_DEFINITIONS "FL_DLL;FL_LIBRARY" + ) + if(OPTION_LARGE_FILE) + set_target_properties(fltk_SHARED PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE) + endif(OPTION_LARGE_FILE) +else() + set_target_properties(fltk_SHARED PROPERTIES OUTPUT_NAME fltk) +endif(MSVC) + +if(USE_THREADS) + target_link_libraries(fltk_SHARED ${CMAKE_THREAD_LIBS_INIT}) +endif(USE_THREADS) + +if(USE_X11) + target_link_libraries(fltk_SHARED ${X11_LIBRARIES}) +endif(USE_X11) + +if(WIN32) + target_link_libraries(fltk_SHARED comctl32) +endif(WIN32) + +if(HAVE_CAIRO) + target_link_libraries(fltk_SHARED fltk_cairo ${PKG_CAIRO_LIBRARIES}) +ENDif(HAVE_CAIRO) + +if(USE_XINERAMA) + target_link_libraries(fltk_SHARED ${X11_Xinerama_LIB}) +endif(USE_XINERAMA) + +if(USE_XFT) + target_link_libraries(fltk_SHARED ${X11_Xft_LIB}) +endif(USE_XFT) + +if(LIB_fontconfig) + target_link_libraries(fltk_SHARED ${LIB_fontconfig}) +endif(LIB_fontconfig) + +####################################################################### + +if(USE_THREADS) + target_link_libraries(fltk_SHARED ${CMAKE_THREAD_LIBS_INIT}) +endif(USE_THREADS) + +if(USE_X11) + target_link_libraries(fltk_SHARED ${X11_LIBRARIES}) +endif(USE_X11) + +####################################################################### + +####################################################################### +install(TARGETS fltk_SHARED + EXPORT fltk-install + DESTINATION ${PREFIX_LIB} +) + +####################################################################### +if(OPENGL_FOUND) + add_library(fltk_gl_SHARED SHARED ${GLCPPFILES}) + target_link_libraries(fltk_gl_SHARED fltk ${OPENGL_LIBRARIES}) + set_target_properties(fltk_gl_SHARED + PROPERTIES CLEAN_DIRECT_OUTPUT 1 + VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} + SOVERSION ${FLTK_VERSION_PATCH} + ) + if(MSVC) + set_target_properties(fltk_gl_SHARED + PROPERTIES + OUTPUT_NAME fltkgldll + DEBUG_OUTPUT_NAME fltkgldlld + COMPILE_DEFINITIONS "FL_DLL;FL_LIBRARY" + ) + if(OPTION_LARGE_FILE) + set_target_properties(fltk_gl_SHARED PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE) + endif(OPTION_LARGE_FILE) + else() + set_target_properties(fltk_gl_SHARED PROPERTIES OUTPUT_NAME fltk_gl) + endif(MSVC) + + install(TARGETS fltk_gl_SHARED + EXPORT fltk-install + DESTINATION ${PREFIX_LIB} + ) +endif(OPENGL_FOUND) + +endif(OPTION_BUILD_SHARED_LIBS) diff --git a/plugins/zynaddsubfx/fltk/src/Fl.cxx b/plugins/zynaddsubfx/fltk/src/Fl.cxx index 2d6e03fe3..116e25705 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl.cxx 6836 2009-07-25 12:56:16Z AlbrechtS $" +// "$Id: Fl.cxx 7354 2010-03-29 11:07:29Z matt $" // // Main event handling code for the Fast Light Tool Kit (FLTK). // @@ -40,9 +40,13 @@ #include #include "flstring.h" -#ifdef DEBUG +#if defined(__APPLE__) +#import +#endif + +#if defined(DEBUG) || defined(DEBUG_WATCH) # include -#endif // DEBUG +#endif // DEBUG || DEBUG_WATCH #ifdef WIN32 # include @@ -406,10 +410,13 @@ double Fl::wait(double time_to_wait) { // the idle function may turn off idle, we can then wait: if (idle) time_to_wait = 0.0; } + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; flush(); if (idle && !in_idle) // 'idle' may have been set within flush() time_to_wait = 0.0; - return fl_wait(time_to_wait); + double retval = fl_wait(time_to_wait); + [pool release]; + return retval; #else @@ -586,12 +593,13 @@ Fl_Window* fl_find(Window xid) { Fl_X *window; for (Fl_X **pp = &Fl_X::first; (window = *pp); pp = &window->next) #if defined(WIN32) || defined(USE_X11) - if (window->xid == xid) { + if (window->xid == xid) #elif defined(__APPLE_QUARTZ__) - if (window->xid == xid && !window->w->window()) { + if (window->xid == xid && !window->w->window()) #else # error unsupported platform #endif // __APPLE__ + { if (window != Fl_X::first && !Fl::modal()) { // make this window be first to speed up searches // this is not done if modal is true to avoid messing up modal stack @@ -704,7 +712,7 @@ static handler_link *handlers = 0; zero from its handle() method. Exactly which ones may change in future versions, however. */ -void Fl::add_handler(int (*ha)(int)) { +void Fl::add_handler(Fl_Event_Handler ha) { handler_link *l = new handler_link; l->handle = ha; l->next = handlers; @@ -714,7 +722,7 @@ void Fl::add_handler(int (*ha)(int)) { /** Removes a previously added event handler. */ -void Fl::remove_handler(int (*ha)(int)) { +void Fl::remove_handler(Fl_Event_Handler ha) { handler_link *l, *p; // Search for the handler in the list... @@ -1278,7 +1286,7 @@ int Fl_Window::handle(int ev) #if defined(USE_X11) || defined(WIN32) XMapWindow(fl_display, fl_xid(this)); // extra map calls are harmless #elif defined(__APPLE_QUARTZ__) - MacMapWindow(this, fl_xid(this)); + MacMapWindow(this, i->xid); #else # error unsupported platform #endif // __APPLE__ @@ -1300,7 +1308,7 @@ int Fl_Window::handle(int ev) #if defined(USE_X11) || defined(WIN32) XUnmapWindow(fl_display, fl_xid(this)); #elif defined(__APPLE_QUARTZ__) - MacUnmapWindow(this, fl_xid(this)); + MacUnmapWindow(this, i->xid); #else # error platform unsupported #endif @@ -1453,10 +1461,15 @@ void Fl_Widget::damage(uchar fl, int X, int Y, int W, int H) { CombineRgn(i->region, i->region, R, RGN_OR); XDestroyRegion(R); #elif defined(__APPLE_QUARTZ__) - Fl_Region R = NewRgn(); - SetRectRgn(R, X, Y, X+W, Y+H); - UnionRgn(R, i->region, i->region); - DisposeRgn(R); + CGRect arg = fl_cgrectmake_cocoa(X, Y, W, H); + int j; // don't add a rectangle totally inside the Fl_Region + for(j = 0; j < i->region->count; j++) { + if(CGRectContainsRect(i->region->rects[j], arg)) break; + } + if( j >= i->region->count) { + i->region->rects = (CGRect*)realloc(i->region->rects, (++(i->region->count)) * sizeof(CGRect)); + i->region->rects[i->region->count - 1] = arg; + } #else # error unsupported platform #endif @@ -1480,7 +1493,7 @@ void Fl_Window::flush() { #ifdef WIN32 # include "Fl_win32.cxx" #elif defined(__APPLE__) -# include "Fl_mac.cxx" +# include "Fl_cocoa.mm" #endif // @@ -1612,11 +1625,11 @@ void Fl::watch_widget_pointer(Fl_Widget *&w) widget_watch = (Fl_Widget***)realloc(widget_watch, sizeof(Fl_Widget**)*max_widget_watch); } widget_watch[num_widget_watch++] = wp; -#ifdef DEBUG +#ifdef DEBUG_WATCH printf ("\nwatch_widget_pointer: (%d/%d) %8p => %8p\n", num_widget_watch,num_widget_watch,wp,*wp); fflush(stdout); -#endif // DEBUG +#endif // DEBUG_WATCH } /** @@ -1638,18 +1651,18 @@ void Fl::release_widget_pointer(Fl_Widget *&w) if (j %8p\n", i+1,num_widget_watch,wp,*wp); } -#endif //DEBUG +#endif //DEBUG_WATCH } num_widget_watch = j; -#ifdef DEBUG +#ifdef DEBUG_WATCH printf (" num_widget_watch = %d\n\n",num_widget_watch); fflush(stdout); -#endif // DEBUG +#endif // DEBUG_WATCH return; } /** @@ -1699,5 +1712,5 @@ Fl_Widget_Tracker::~Fl_Widget_Tracker() { } // -// End of "$Id: Fl.cxx 6836 2009-07-25 12:56:16Z AlbrechtS $". +// End of "$Id: Fl.cxx 7354 2010-03-29 11:07:29Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Adjuster.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Adjuster.cxx index f6d9ec3ac..189d0412f 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Adjuster.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Adjuster.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Adjuster.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_Adjuster.cxx 7115 2010-02-20 17:40:07Z AlbrechtS $" // // Adjuster widget for the Fast Light Tool Kit (FLTK). // @@ -69,6 +69,7 @@ int Fl_Adjuster::handle(int event) { double v; int delta; int mx = Fl::event_x(); + // Fl_Widget_Tracker wp(this); switch (event) { case FL_PUSH: if (Fl::visible_focus()) Fl::focus(this); @@ -77,7 +78,10 @@ int Fl_Adjuster::handle(int event) { drag = 3*(mx-x())/w() + 1; else drag = 3-3*(Fl::event_y()-y()-1)/h(); - handle_push(); + { Fl_Widget_Tracker wp(this); + handle_push(); + if (wp.deleted()) return 1; + } redraw(); return 1; case FL_DRAG: @@ -98,9 +102,9 @@ int Fl_Adjuster::handle(int event) { delta = 0; } switch (drag) { - case 3: v = increment(previous_value(), delta); break; - case 2: v = increment(previous_value(), delta*10); break; - default:v = increment(previous_value(), delta*100); break; + case 3: v = increment(previous_value(), delta); break; + case 2: v = increment(previous_value(), delta*10); break; + default:v = increment(previous_value(), delta*100); break; } handle_drag(soft() ? softclamp(v) : clamp(v)); return 1; @@ -109,11 +113,13 @@ int Fl_Adjuster::handle(int event) { if (Fl::event_state()&0xF0000) delta = -10; else delta = 10; switch (drag) { - case 3: v = increment(previous_value(), delta); break; - case 2: v = increment(previous_value(), delta*10); break; - default:v = increment(previous_value(), delta*100); break; + case 3: v = increment(previous_value(), delta); break; + case 2: v = increment(previous_value(), delta*10); break; + default:v = increment(previous_value(), delta*100); break; } + Fl_Widget_Tracker wp(this); handle_drag(soft() ? softclamp(v) : clamp(v)); + if (wp.deleted()) return 1; } drag = 0; redraw(); @@ -172,5 +178,5 @@ Fl_Adjuster::Fl_Adjuster(int X, int Y, int W, int H, const char* l) } // -// End of "$Id: Fl_Adjuster.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_Adjuster.cxx 7115 2010-02-20 17:40:07Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Bitmap.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Bitmap.cxx index fe054f3d6..7f472c68b 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Bitmap.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Bitmap.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Bitmap.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_Bitmap.cxx 7659 2010-07-01 13:21:32Z manolo $" // // Bitmap drawing routines for the Fast Light Tool Kit (FLTK). // @@ -37,9 +37,12 @@ #include #include #include +#include #include "flstring.h" #if defined(__APPLE_QUARTZ__) + + Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *array) { static uchar reverse[16] = /* Bit reversal lookup table */ { 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee, @@ -51,14 +54,18 @@ Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *array) { *dst++ = ((reverse[*src & 0x0f] & 0xf0) | (reverse[(*src >> 4) & 0x0f] & 0x0f))^0xff; } CGDataProviderRef srcp = CGDataProviderCreateWithData( 0L, bmask, rowBytes*h, 0L); - CGImageRef id = CGImageMaskCreate( w, h, 1, 1, rowBytes, srcp, 0L, false); + CGImageRef id_ = CGImageMaskCreate( w, h, 1, 1, rowBytes, srcp, 0L, false); CGDataProviderRelease(srcp); - return (Fl_Bitmask)id; + return (Fl_Bitmask)id_; } -void fl_delete_bitmask(Fl_Bitmask id) { - if (id) CGImageRelease((CGImageRef)id); +void fl_delete_bitmask(Fl_Bitmask bm) { + if (bm) CGImageRelease((CGImageRef)bm); } + + #elif defined(WIN32) // Windows bitmask functions... + + // 'fl_create_bitmap()' - Create a 1-bit bitmap for drawing... static Fl_Bitmask fl_create_bitmap(int w, int h, const uchar *data) { // we need to pad the lines out to words & swap the bits @@ -68,7 +75,7 @@ static Fl_Bitmask fl_create_bitmap(int w, int h, const uchar *data) { uchar* newarray = new uchar[w2*h]; const uchar* src = data; uchar* dest = newarray; - Fl_Bitmask id; + Fl_Bitmask bm; static uchar reverse[16] = /* Bit reversal lookup table */ { 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee, 0x11, 0x99, 0x55, 0xdd, 0x33, 0xbb, 0x77, 0xff }; @@ -80,18 +87,18 @@ static Fl_Bitmask fl_create_bitmap(int w, int h, const uchar *data) { dest += w2-w1; } - id = CreateBitmap(w, h, 1, 1, newarray); + bm = CreateBitmap(w, h, 1, 1, newarray); delete[] newarray; - return id; + return bm; } // 'fl_create_bitmask()' - Create an N-bit bitmap for masking... Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data) { // this won't work when the user changes display mode during run or // has two screens with differnet depths - Fl_Bitmask id; + Fl_Bitmask bm; static uchar hiNibble[16] = { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0 }; @@ -140,45 +147,21 @@ Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data) { dst += pad; } - id = CreateBitmap(w, h, np, bpp, newarray); + bm = CreateBitmap(w, h, np, bpp, newarray); delete[] newarray; - return id; + return bm; } -#if 0 // This doesn't appear to be used anywhere... -Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data, int for_mask) { - // we need to pad the lines out to words & swap the bits - // in each byte. - int w1 = (w+7)/8; - int w2 = ((w+15)/16)*2; - uchar* newarray = new uchar[w2*h]; - const uchar* src = data; - uchar* dest = newarray; - Fl_Bitmask id; - static uchar reverse[16] = /* Bit reversal lookup table */ - { 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee, - 0x11, 0x99, 0x55, 0xdd, 0x33, 0xbb, 0x77, 0xff }; - - for (int y=0; y < h; y++) { - for (int n = 0; n < w1; n++, src++) - *dest++ = (reverse[*src & 0x0f] & 0xf0) | - (reverse[(*src >> 4) & 0x0f] & 0x0f); - dest += w2-w1; - } - - id = CreateBitmap(w, h, 1, 1, newarray); - - delete[] newarray; - - return (id); -} -# endif // 0 void fl_delete_bitmask(Fl_Bitmask bm) { DeleteObject((HGDIOBJ)bm); } + + #else // X11 bitmask functions + + Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data) { return XCreateBitmapFromData(fl_display, fl_window, (const char *)data, (w+7)&-8, h); @@ -187,12 +170,14 @@ Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data) { void fl_delete_bitmask(Fl_Bitmask bm) { fl_delete_offscreen((Fl_Offscreen)bm); } + + #endif // __APPLE__ // Create a 1-bit mask used for alpha blending Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *array) { - Fl_Bitmask mask; + Fl_Bitmask bm; int bmw = (w + 7) / 8; uchar *bitmap = new uchar[bmw * h]; uchar *bitptr, bit; @@ -257,62 +242,133 @@ Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *array) } } - mask = fl_create_bitmask(w, h, bitmap); + bm = fl_create_bitmask(w, h, bitmap); delete[] bitmap; - return (mask); + return (bm); } void Fl_Bitmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) { - if (!array) { - draw_empty(XP, YP); - return; - } + fl_graphics_driver->draw(this, XP, YP, WP, HP, cx, cy); +} +static int start(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int w, int h, int &cx, int &cy, + int &X, int &Y, int &W, int &H) +{ // account for current clip region (faster on Irix): - int X,Y,W,H; fl_clip_box(XP,YP,WP,HP,X,Y,W,H); + fl_clip_box(XP,YP,WP,HP,X,Y,W,H); cx += X-XP; cy += Y-YP; // clip the box down to the size of image, quit if empty: if (cx < 0) {W += cx; X -= cx; cx = 0;} - if ((cx+W) > w()) W = w()-cx; - if (W <= 0) return; + if (cx+W > w) W = w-cx; + if (W <= 0) return 1; if (cy < 0) {H += cy; Y -= cy; cy = 0;} - if ((cy+H) > h()) H = h()-cy; - if (H <= 0) return; + if (cy+H > h) H = h-cy; + if (H <= 0) return 1; + return 0; +} -#if defined(USE_X11) - if (!id) id = fl_create_bitmask(w(), h(), array); +#ifdef __APPLE__ +void Fl_Quartz_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + if (!bm->array) { + bm->draw_empty(XP, YP); + return; + } + if (start(bm, XP, YP, WP, HP, bm->w(), bm->h(), cx, cy, X, Y, W, H)) { + return; + } + if (!bm->id_) bm->id_ = fl_create_bitmask(bm->w(), bm->h(), bm->array); + if (bm->id_ && fl_gc) { + CGRect rect = { { X, Y }, { W, H } }; + Fl_X::q_begin_image(rect, cx, cy, bm->w(), bm->h()); + CGContextDrawImage(fl_gc, rect, (CGImageRef)bm->id_); + Fl_X::q_end_image(); + } +} - XSetStipple(fl_display, fl_gc, id); - int ox = X-cx; if (ox < 0) ox += w(); - int oy = Y-cy; if (oy < 0) oy += h(); +#elif defined(WIN32) +void Fl_GDI_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + if (!bm->array) { + bm->draw_empty(XP, YP); + return; + } + if (start(bm, XP, YP, WP, HP, bm->w(), bm->h(), cx, cy, X, Y, W, H)) { + return; + } + if (!bm->id_) bm->id_ = fl_create_bitmap(bm->w(), bm->h(), bm->array); + + typedef BOOL (WINAPI* fl_transp_func) (HDC,int,int,int,int,HDC,int,int,int,int,UINT); + static fl_transp_func fl_TransparentBlt; + HDC tempdc; + int save; + BOOL use_print_algo = false; + if (fl_surface->type() == Fl_Printer::device_type) { + static HMODULE hMod = NULL; + if (!hMod) { + hMod = LoadLibrary("MSIMG32.DLL"); + if (hMod) fl_TransparentBlt = (fl_transp_func)GetProcAddress(hMod, "TransparentBlt"); + } + if (hMod) use_print_algo = true; + } + if (use_print_algo) { // algorithm for bitmap output to Fl_GDI_Printer + Fl_Offscreen tmp_id = fl_create_offscreen(W, H); + fl_begin_offscreen(tmp_id); + Fl_Color save_c = fl_color(); // save bitmap's desired color + uchar r, g, b; + Fl::get_color(save_c, r, g, b); + r = 255-r; + g = 255-g; + b = 255-b; + Fl_Color background = fl_rgb_color(r, g, b); // a color very different from the bitmap's + fl_color(background); + fl_rectf(0,0,W,H); // use this color as offscreen background + fl_color(save_c); // back to bitmap's color + tempdc = CreateCompatibleDC(fl_gc); + save = SaveDC(tempdc); + SelectObject(tempdc, (HGDIOBJ)bm->id_); + SelectObject(fl_gc, fl_brush()); // use bitmap's desired color + BitBlt(fl_gc, 0, 0, W, H, tempdc, 0, 0, 0xE20746L); // draw bitmap to offscreen + fl_end_offscreen(); // offscreen data is in tmp_id + SelectObject(tempdc, (HGDIOBJ)tmp_id); // use offscreen data + // draw it to printer context with background color as transparent + fl_TransparentBlt(fl_gc, X,Y,W,H, tempdc, cx, cy, bm->w(), bm->h(), RGB(r, g, b) ); + fl_delete_offscreen(tmp_id); + } + else { // algorithm for bitmap output to display + tempdc = CreateCompatibleDC(fl_gc); + save = SaveDC(tempdc); + SelectObject(tempdc, (HGDIOBJ)bm->id_); + SelectObject(fl_gc, fl_brush()); + // secret bitblt code found in old MSWindows reference manual: + BitBlt(fl_gc, X, Y, W, H, tempdc, cx, cy, 0xE20746L); + } + RestoreDC(tempdc, save); + DeleteDC(tempdc); +} + +#else // Xlib +void Fl_Xlib_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + if (!bm->array) { + bm->draw_empty(XP, YP); + return; + } + if (start(bm, XP, YP, WP, HP, bm->w(), bm->h(), cx, cy, X, Y, W, H)) { + return; + } + if (!bm->id_) bm->id_ = fl_create_bitmask(bm->w(), bm->h(), bm->array); + + XSetStipple(fl_display, fl_gc, bm->id_); + int ox = X-cx; if (ox < 0) ox += bm->w(); + int oy = Y-cy; if (oy < 0) oy += bm->h(); XSetTSOrigin(fl_display, fl_gc, ox, oy); XSetFillStyle(fl_display, fl_gc, FillStippled); XFillRectangle(fl_display, fl_window, fl_gc, X, Y, W, H); XSetFillStyle(fl_display, fl_gc, FillSolid); -#elif defined(WIN32) - if (!id) id = fl_create_bitmap(w(), h(), array); - - HDC tempdc = CreateCompatibleDC(fl_gc); - int save = SaveDC(tempdc); - SelectObject(tempdc, (HGDIOBJ)id); - SelectObject(fl_gc, fl_brush()); - // secret bitblt code found in old MSWindows reference manual: - BitBlt(fl_gc, X, Y, W, H, tempdc, cx, cy, 0xE20746L); - RestoreDC(tempdc, save); - DeleteDC(tempdc); -#elif defined(__APPLE_QUARTZ__) - if (!id) id = fl_create_bitmask(w(), h(), array); - if (id && fl_gc) { - CGRect rect = { { X, Y }, { W, H } }; - Fl_X::q_begin_image(rect, cx, cy, w(), h()); - CGContextDrawImage(fl_gc, rect, (CGImageRef)id); - Fl_X::q_end_image(); - } -#else -# error unsupported platform -#endif } +#endif /** The destructor free all memory and server resources that are used by @@ -324,9 +380,13 @@ Fl_Bitmap::~Fl_Bitmap() { } void Fl_Bitmap::uncache() { - if (id) { - fl_delete_bitmask((Fl_Offscreen)id); - id = 0; + if (id_) { +#ifdef __APPLE_QUARTZ__ + fl_delete_bitmask((Fl_Bitmask)id_); +#else + fl_delete_bitmask((Fl_Offscreen)id_); +#endif + id_ = 0; } } @@ -418,5 +478,5 @@ Fl_Image *Fl_Bitmap::copy(int W, int H) { // -// End of "$Id: Fl_Bitmap.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_Bitmap.cxx 7659 2010-07-01 13:21:32Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Browser_.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Browser_.cxx index 2eb24415e..c1c97ba51 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Browser_.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Browser_.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Browser_.cxx 6737 2009-04-02 06:44:34Z greg.ercolano $" +// "$Id: Fl_Browser_.cxx 7115 2010-02-20 17:40:07Z AlbrechtS $" // // Base Browser widget class for the Fast Light Tool Kit (FLTK). // @@ -678,11 +678,15 @@ int Fl_Browser_::deselect(int docallbacks) { int Fl_Browser_::select_only(void* item, int docallbacks) { if (!item) return deselect(docallbacks); int change = 0; + Fl_Widget_Tracker wp(this); if (type() == FL_MULTI_BROWSER) { - for (void* p = item_first(); p; p = item_next(p)) + for (void* p = item_first(); p; p = item_next(p)) { if (p != item) change |= select(p, 0, docallbacks); + if (wp.deleted()) return change; + } } change |= select(item, 1, docallbacks); + if (wp.deleted()) return change; display(item); return change; } @@ -693,6 +697,20 @@ int Fl_Browser_::select_only(void* item, int docallbacks) { \returns 1 if event was processed, 0 if not. */ int Fl_Browser_::handle(int event) { + + // NOTE: + // We use Fl_Widget_Tracker to test if the user has deleted + // this widget in a callback. Callbacks can be called by: + // - do_callback() + // - select() + // - select_only() + // - deselect() + // Thus we must test wp.deleted() after each of these calls, + // unless we return directly after one of these. + // If wp.deleted() is true, we return 1 because we used the event. + + Fl_Widget_Tracker wp(this); + // must do shortcuts first or the scrollbar will get them... if (event == FL_ENTER || event == FL_LEAVE) return 1; if (event == FL_KEYBOARD && type() >= FL_HOLD_BROWSER) { @@ -706,8 +724,12 @@ int Fl_Browser_::handle(int event) { if (item_height(l)>0) {select_only(l, when()); break;} return 1; case FL_Up: - while ((l = item_prev(l))) if (item_height(l)>0) { - select_only(l, when()); break;} + while ((l = item_prev(l))) { + if (item_height(l)>0) { + select_only(l, when()); + break; // no need to test wp (return 1) + } + } return 1; } } else { @@ -715,6 +737,7 @@ int Fl_Browser_::handle(int event) { case FL_Enter: case FL_KP_Enter: select_only(l, when() & ~FL_WHEN_ENTER_KEY); + if (wp.deleted()) return 1; if (when() & FL_WHEN_ENTER_KEY) { set_changed(); do_callback(); @@ -728,6 +751,7 @@ int Fl_Browser_::handle(int event) { while ((l = item_next(l))) { if (Fl::event_state(FL_SHIFT|FL_CTRL)) select(l, l1 ? item_selected(l1) : 1, when()); + if (wp.deleted()) return 1; if (item_height(l)>0) goto J1; } return 1; @@ -735,6 +759,7 @@ int Fl_Browser_::handle(int event) { while ((l = item_prev(l))) { if (Fl::event_state(FL_SHIFT|FL_CTRL)) select(l, l1 ? item_selected(l1) : 1, when()); + if (wp.deleted()) return 1; if (item_height(l)>0) goto J1; } return 1; @@ -749,6 +774,8 @@ J1: } if (Fl_Group::handle(event)) return 1; + if (wp.deleted()) return 1; + int X, Y, W, H; bbox(X, Y, W, H); int my; // NOTE: @@ -784,9 +811,11 @@ J1: ; else if (type() != FL_MULTI_BROWSER) { change = select_only(find_item(my), 0); + if (wp.deleted()) return 1; if (change && (when() & FL_WHEN_CHANGED)) { set_changed(); do_callback(); + if (wp.deleted()) return 1; } } else { void* l = find_item(my); @@ -796,9 +825,11 @@ J1: if (l) { whichway = !item_selected(l); change = select(l, whichway, 0); + if (wp.deleted()) return 1; if (change && (when() & FL_WHEN_CHANGED)) { set_changed(); do_callback(); + if (wp.deleted()) return 1; } } } else if (Fl::event_state(FL_SHIFT)) { // extend selection: @@ -814,23 +845,29 @@ J1: if (!m) {down = 0; break;} }} if (down) { - for (void* m = selection_; m != l; m = item_next(m)) + for (void* m = selection_; m != l; m = item_next(m)) { select(m, whichway, when() & FL_WHEN_CHANGED); + if (wp.deleted()) return 1; + } } else { void* e = selection_; for (void* m = item_next(l); m; m = item_next(m)) { select(m, whichway, when() & FL_WHEN_CHANGED); + if (wp.deleted()) return 1; if (m == e) break; } } // do the clicked item last so the select box is around it: change = 1; if (l) select(l, whichway, when() & FL_WHEN_CHANGED); + if (wp.deleted()) return 1; } else { // select only this item change = select_only(l, 0); + if (wp.deleted()) return 1; if (change && (when() & FL_WHEN_CHANGED)) { set_changed(); do_callback(); + if (wp.deleted()) return 1; } } } @@ -863,10 +900,12 @@ J1: for (; t && t != b; t = item_next(t)) { char change_t; change_t = select(t, whichway, 0); + if (wp.deleted()) return 1; change |= change_t; if (change_t && (when() & FL_WHEN_CHANGED)) { set_changed(); do_callback(); + if (wp.deleted()) return 1; } } if (l) selection_ = l; @@ -877,12 +916,16 @@ J1: find_item(my); change = (l != l1); select_only(l, when() & FL_WHEN_CHANGED); + if (wp.deleted()) return 1; } py = my; return 1; case FL_RELEASE: if (type() == FL_SELECT_BROWSER) { - void* t = selection_; deselect(); selection_ = t; + void* t = selection_; + deselect(); + if (wp.deleted()) return 1; + selection_ = t; } if (change) { set_changed(); @@ -890,7 +933,8 @@ J1: } else { if (when() & FL_WHEN_NOT_CHANGED) do_callback(); } - + if (wp.deleted()) return 1; + // double click calls the callback: (like Enter Key) if (Fl::event_clicks() && (when() & FL_WHEN_ENTER_KEY)) { set_changed(); @@ -962,7 +1006,7 @@ void Fl_Browser_::sort(int flags) { a = item_next(a); n++; } - for (i=n-1; i>0; i--) { + for (i=n; i>0; i--) { char swapped = 0; a = item_first(); b = item_next(a); @@ -981,6 +1025,7 @@ void Fl_Browser_::sort(int flags) { swapped = 1; } } + if (!c) break; b = c; a = item_prev(b); } if (!swapped) @@ -1058,5 +1103,5 @@ void Fl_Browser_::item_select(void *item, int val) {} int Fl_Browser_::item_selected(void* item) const { return item==selection_ ? 1 : 0; } // -// End of "$Id: Fl_Browser_.cxx 6737 2009-04-02 06:44:34Z greg.ercolano $". +// End of "$Id: Fl_Browser_.cxx 7115 2010-02-20 17:40:07Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Button.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Button.cxx index 686de5de7..391f9311a 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Button.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Button.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Button.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_Button.cxx 7476 2010-04-09 22:18:05Z matt $" // // Button widget for the Fast Light Tool Kit (FLTK). // @@ -60,7 +60,7 @@ int Fl_Button::value(int v) { */ void Fl_Button::setonly() { // set this radio button on, turn others off value(1); - Fl_Group* g = (Fl_Group*)parent(); + Fl_Group* g = parent(); Fl_Widget*const* a = g->array(); for (int i = g->children(); i--;) { Fl_Widget* o = *a++; @@ -72,6 +72,7 @@ void Fl_Button::draw() { if (type() == FL_HIDDEN_BUTTON) return; Fl_Color col = value() ? selection_color() : color(); draw_box(value() ? (down_box()?down_box():fl_down(box())) : box(), col); + draw_backdrop(); if (labeltype() == FL_NORMAL_LABEL && value()) { Fl_Color c = labelcolor(); labelcolor(fl_contrast(c, col)); @@ -84,7 +85,7 @@ void Fl_Button::draw() { int Fl_Button::handle(int event) { int newval; switch (event) { - case FL_ENTER: + case FL_ENTER: /* FALLTHROUGH */ case FL_LEAVE: // if ((value_?selection_color():color())==FL_GRAY) redraw(); return 1; @@ -117,7 +118,11 @@ int Fl_Button::handle(int event) { else { value(oldval); set_changed(); - if (when() & FL_WHEN_CHANGED) do_callback(); + if (when() & FL_WHEN_CHANGED) { + Fl_Widget_Tracker wp(this); + do_callback(); + if (wp.deleted()) return 1; + } } if (when() & FL_WHEN_RELEASE) do_callback(); return 1; @@ -139,7 +144,7 @@ int Fl_Button::handle(int event) { do_callback(); } else if (when() & FL_WHEN_RELEASE) do_callback(); return 1; - case FL_FOCUS : + case FL_FOCUS : /* FALLTHROUGH */ case FL_UNFOCUS : if (Fl::visible_focus()) { if (box() == FL_NO_BOX) { @@ -156,6 +161,7 @@ int Fl_Button::handle(int event) { if (Fl::focus() == this && Fl::event_key() == ' ' && !(Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) { set_changed(); + Fl_Widget_Tracker wp(this); if (type() == FL_RADIO_BUTTON && !value_) { setonly(); if (when() & FL_WHEN_CHANGED) do_callback(); @@ -163,6 +169,7 @@ int Fl_Button::handle(int event) { value(!value()); if (when() & FL_WHEN_CHANGED) do_callback(); } + if (wp.deleted()) return 1; if (when() & FL_WHEN_RELEASE) do_callback(); return 1; } @@ -186,5 +193,5 @@ Fl_Button::Fl_Button(int X, int Y, int W, int H, const char *L) } // -// End of "$Id: Fl_Button.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_Button.cxx 7476 2010-04-09 22:18:05Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Color_Chooser.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Color_Chooser.cxx index 8cf4c59f1..eb88f8d22 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Color_Chooser.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Color_Chooser.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Color_Chooser.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_Color_Chooser.cxx 7347 2010-03-27 16:35:14Z AlbrechtS $" // // Color chooser for the Fast Light Tool Kit (FLTK). // @@ -123,7 +123,7 @@ void Fl_Color_Chooser::set_valuators() { gvalue.range(0,1); gvalue.step(1,1000); gvalue.value(g_); bvalue.range(0,1); bvalue.step(1,1000); bvalue.value(b_); break; - case M_BYTE: + case M_BYTE: /* FALLTHROUGH */ case M_HEX: rvalue.range(0,255); rvalue.step(1); rvalue.value(int(255*r_+.5)); gvalue.range(0,255); gvalue.step(1); gvalue.value(int(255*g_+.5)); @@ -233,7 +233,7 @@ int Flcc_HueBox::handle(int e) { if (Fl::event_state(FL_CTRL)) H = ih; if (c->hsv(H, S, c->value())) c->do_callback(); } return 1; - case FL_FOCUS : + case FL_FOCUS : /* FALLTHROUGH */ case FL_UNFOCUS : if (Fl::visible_focus()) { redraw(); @@ -354,7 +354,7 @@ int Flcc_ValueBox::handle(int e) { if (fabs(Yf-iv)<(3*1.0/h())) Yf = iv; if (c->hsv(c->hue(),c->saturation(),Yf)) c->do_callback(); } return 1; - case FL_FOCUS : + case FL_FOCUS : /* FALLTHROUGH */ case FL_UNFOCUS : if (Fl::visible_focus()) { redraw(); @@ -516,7 +516,7 @@ void ColorChip::draw() { h()-Fl::box_dh(box()),r,g,b); } -static void chooser_cb(Fl_Object* o, void* vv) { +static void chooser_cb(Fl_Widget* o, void* vv) { Fl_Color_Chooser* c = (Fl_Color_Chooser*)o; ColorChip* v = (ColorChip*)vv; v->r = uchar(255*c->r()+.5); @@ -528,6 +528,27 @@ static void chooser_cb(Fl_Object* o, void* vv) { extern const char* fl_ok; extern const char* fl_cancel; +// fl_color_chooser's callback for ok_button (below) +// [in] o is a pointer to okay_button (below) +// [in] p is a pointer to an int to receive the return value (1) +// closes the fl_color_chooser window +static void cc_ok_cb (Fl_Widget *o, void *p) { + *((int *)p) = 1; // set return value + o->window()->hide(); +} + +// fl_color_chooser's callback for cancel_button and window close +// [in] o is a pointer to cancel_button (below) _or_ the dialog window +// [in] p is a pointer to an int to receive the return value (0) +// closes the fl_color_chooser window +static void cc_cancel_cb (Fl_Widget *o, void *p) { + *((int *)p) = 0; // set return value + if (o->window()) // cancel button + o->window()->hide(); + else // window close + o->hide(); +} + /** \addtogroup group_comdlg @{ */ /** @@ -541,15 +562,19 @@ extern const char* fl_cancel; \relates Fl_Color_Chooser */ int fl_color_chooser(const char* name, double& r, double& g, double& b) { + int ret = 0; Fl_Window window(215,200,name); + window.callback(cc_cancel_cb,&ret); Fl_Color_Chooser chooser(10, 10, 195, 115); ColorChip ok_color(10, 130, 95, 25); Fl_Return_Button ok_button(10, 165, 95, 25, fl_ok); + ok_button.callback(cc_ok_cb,&ret); ColorChip cancel_color(110, 130, 95, 25); cancel_color.r = uchar(255*r+.5); ok_color.r = cancel_color.r; ok_color.g = cancel_color.g = uchar(255*g+.5); ok_color.b = cancel_color.b = uchar(255*b+.5); Fl_Button cancel_button(110, 165, 95, 25, fl_cancel); + cancel_button.callback(cc_cancel_cb,&ret); window.resizable(chooser); chooser.rgb(r,g,b); chooser.callback(chooser_cb, &ok_color); @@ -557,21 +582,13 @@ int fl_color_chooser(const char* name, double& r, double& g, double& b) { window.set_modal(); window.hotspot(window); window.show(); - while (window.shown()) { - Fl::wait(); - for (;;) { - Fl_Widget* o = Fl::readqueue(); - if (!o) break; - if (o == &ok_button) { - r = chooser.r(); - g = chooser.g(); - b = chooser.b(); - return 1; - } - if (o == &window || o == &cancel_button) return 0; - } + while (window.shown()) Fl::wait(); + if (ret) { // ok_button or Enter + r = chooser.r(); + g = chooser.g(); + b = chooser.b(); } - return 0; + return ret; } /** @@ -598,5 +615,5 @@ int fl_color_chooser(const char* name, uchar& r, uchar& g, uchar& b) { } /** @} */ // -// End of "$Id: Fl_Color_Chooser.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_Color_Chooser.cxx 7347 2010-03-27 16:35:14Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Counter.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Counter.cxx index 1b6575407..dd0a43674 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Counter.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Counter.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Counter.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_Counter.cxx 7162 2010-02-26 21:10:46Z matt $" // // Counter widget for the Fast Light Tool Kit (FLTK). // @@ -137,14 +137,19 @@ int Fl_Counter::handle(int event) { return 1; case FL_PUSH: if (Fl::visible_focus()) Fl::focus(this); - handle_push(); + { Fl_Widget_Tracker wp(this); + handle_push(); + if (wp.deleted()) return 1; + } case FL_DRAG: i = calc_mouseobj(); if (i != mouseobj) { Fl::remove_timeout(repeat_callback, this); mouseobj = (uchar)i; if (i) Fl::add_timeout(INITIALREPEAT, repeat_callback, this); + Fl_Widget_Tracker wp(this); increment_cb(); + if (wp.deleted()) return 1; redraw(); } return 1; @@ -160,13 +165,13 @@ int Fl_Counter::handle(int event) { return 0; } // break not required because of switch... - case FL_FOCUS : + case FL_FOCUS : /* FALLTHROUGH */ case FL_UNFOCUS : if (Fl::visible_focus()) { redraw(); return 1; } else return 0; - case FL_ENTER : + case FL_ENTER : /* FALLTHROUGH */ case FL_LEAVE : return 1; default: @@ -202,5 +207,5 @@ Fl_Counter::Fl_Counter(int X, int Y, int W, int H, const char* L) } // -// End of "$Id: Fl_Counter.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_Counter.cxx 7162 2010-02-26 21:10:46Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Device.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Device.cxx new file mode 100644 index 000000000..b37ad5db6 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Device.cxx @@ -0,0 +1,56 @@ +// +// "$Id: Fl_Device.cxx 7659 2010-07-01 13:21:32Z manolo $" +// +// implementation of Fl_Device class for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include + +const char *Fl_Device::device_type = "Fl_Device"; +const char *Fl_Surface_Device::device_type = "Fl_Surface_Device"; +const char *Fl_Display_Device::device_type = "Fl_Display_Device"; +const char *Fl_Graphics_Driver::device_type = "Fl_Graphics_Driver"; +#if defined(__APPLE__) || defined(FL_DOXYGEN) +const char *Fl_Quartz_Graphics_Driver::device_type = "Fl_Quartz_Graphics_Driver"; +#endif +#if defined(WIN32) || defined(FL_DOXYGEN) +const char *Fl_GDI_Graphics_Driver::device_type = "Fl_GDI_Graphics_Driver"; +#endif +#if !(defined(__APPLE__) || defined(WIN32)) +const char *Fl_Xlib_Graphics_Driver::device_type = "Fl_Xlib_Graphics_Driver"; +#endif + + +/** \brief Use this drawing surface for future graphics requests. */ +void Fl_Surface_Device::set_current(void) +{ + fl_graphics_driver = _driver; + fl_surface = this; +} + +// +// End of "$Id: Fl_Device.cxx 7659 2010-07-01 13:21:32Z manolo $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Dial.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Dial.cxx index 3acb26d8e..def4c7103 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Dial.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Dial.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Dial.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_Dial.cxx 7162 2010-02-26 21:10:46Z matt $" // // Circular dial widget for the Fast Light Tool Kit (FLTK). // @@ -109,8 +109,10 @@ void Fl_Dial::draw() { */ int Fl_Dial::handle(int event, int X, int Y, int W, int H) { switch (event) { - case FL_PUSH: + case FL_PUSH: { + Fl_Widget_Tracker wp(this); handle_push(); + if (wp.deleted()) return 1; } case FL_DRAG: { int mx = (Fl::event_x()-X-W/2)*H; int my = (Fl::event_y()-Y-H/2)*W; @@ -132,7 +134,7 @@ int Fl_Dial::handle(int event, int X, int Y, int W, int H) { case FL_RELEASE: handle_release(); return 1; - case FL_ENTER : + case FL_ENTER : /* FALLTHROUGH */ case FL_LEAVE : return 1; default: @@ -160,5 +162,5 @@ Fl_Dial::Fl_Dial(int X, int Y, int W, int H, const char* l) } // -// End of "$Id: Fl_Dial.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_Dial.cxx 7162 2010-02-26 21:10:46Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Double_Window.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Double_Window.cxx index f26951e4d..13725b5d1 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Double_Window.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Double_Window.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Double_Window.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_Double_Window.cxx 7671 2010-07-09 17:31:33Z manolo $" // // Double-buffered window code for the Fast Light Tool Kit (FLTK). // @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -64,8 +65,28 @@ void Fl_Double_Window::show() { Fl_Window::show(); } +static void fl_copy_offscreen_to_display(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy); + +void fl_copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy) { + if( fl_graphics_driver == fl_display_device->driver()) { + fl_copy_offscreen_to_display(x, y, w, h, pixmap, srcx, srcy); + } + else { // when copy is not to the display + fl_begin_offscreen(pixmap); + uchar *img = fl_read_image(NULL, srcx, srcy, w, h, 0); + fl_end_offscreen(); + fl_draw_image(img, x, y, w, h, 3, 0); + delete img; + } +} + #if defined(USE_X11) +static void fl_copy_offscreen_to_display(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy) { + XCopyArea(fl_display, pixmap, fl_window, fl_gc, srcx, srcy, w, h, x, y); +} + + // maybe someone feels inclined to implement alpha blending on X11? char fl_can_do_alpha_blending() { return 0; @@ -100,10 +121,9 @@ char fl_can_do_alpha_blending() { fl_alpha_blend = (fl_alpha_blend_func)GetProcAddress(hMod, "AlphaBlend"); // give up if we can't find it (Win95) if (!fl_alpha_blend) return 0; - // we have the call, but does our display support alpha blending? - HDC dc = 0L;//fl_gc; - // get the current or the desktop's device context - if (!dc) dc = GetDC(0L); + // we have the call, but does our display support alpha blending? + // get the desktop's device context + HDC dc = GetDC(0L); if (!dc) return 0; // check the device capabilities flags. However GetDeviceCaps // does not return anything useful, so we have to do it manually: @@ -117,8 +137,8 @@ char fl_can_do_alpha_blending() { RestoreDC(new_gc, save); DeleteDC(new_gc); DeleteObject(bm); + ReleaseDC(0L, dc); - if (!fl_gc) ReleaseDC(0L, dc); if (alpha_ok) can_do = 1; return can_do; } @@ -134,7 +154,7 @@ HDC fl_makeDC(HBITMAP bitmap) { return new_gc; } -void fl_copy_offscreen(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) { +static void fl_copy_offscreen_to_display(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) { HDC new_gc = CreateCompatibleDC(fl_gc); int save = SaveDC(new_gc); SelectObject(new_gc, bitmap); @@ -149,11 +169,15 @@ void fl_copy_offscreen_with_alpha(int x,int y,int w,int h,HBITMAP bitmap,int src SelectObject(new_gc, bitmap); BOOL alpha_ok = 0; // first try to alpha blend - if (fl_can_do_alpha_blending()) + // if to printer, always try alpha_blend + int to_display = Fl_Surface_Device::surface()->type() == Fl_Display_Device::device_type; // true iff display output + if ( (to_display && fl_can_do_alpha_blending()) || Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) { alpha_ok = fl_alpha_blend(fl_gc, x, y, w, h, new_gc, srcx, srcy, w, h, blendfunc); - // if that failed (it shouldn,t), still copy the bitmap over, but now alpha is 1 - if (!alpha_ok) + } + // if that failed (it shouldn't), still copy the bitmap over, but now alpha is 1 + if (!alpha_ok) { BitBlt(fl_gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY); + } RestoreDC(new_gc, save); DeleteDC(new_gc); } @@ -184,14 +208,24 @@ Fl_Offscreen fl_create_offscreen_with_alpha(int w, int h) { return (Fl_Offscreen)ctx; } -void fl_copy_offscreen(int x,int y,int w,int h,Fl_Offscreen osrc,int srcx,int srcy) { +static void bmProviderRelease (void *src, const void *data, size_t size) +{ + CFIndex count = CFGetRetainCount(src); + CFRelease(src); + if(count == 1) free((void*)data); +} + +static void fl_copy_offscreen_to_display(int x,int y,int w,int h,Fl_Offscreen osrc,int srcx,int srcy) { CGContextRef src = (CGContextRef)osrc; void *data = CGBitmapContextGetData(src); int sw = CGBitmapContextGetWidth(src); int sh = CGBitmapContextGetHeight(src); CGImageAlphaInfo alpha = CGBitmapContextGetAlphaInfo(src); CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); - CGDataProviderRef src_bytes = CGDataProviderCreateWithData( 0L, data, sw*sh*4, 0L); + // when output goes to a Quartz printercontext, release of the bitmap must be + // delayed after the end of the print page + CFRetain(src); + CGDataProviderRef src_bytes = CGDataProviderCreateWithData( src, data, sw*sh*4, bmProviderRelease); CGImageRef img = CGImageCreate( sw, sh, 8, 4*8, 4*sw, lut, alpha, src_bytes, 0L, false, kCGRenderingIntentDefault); // fl_push_clip(); @@ -207,17 +241,20 @@ void fl_copy_offscreen(int x,int y,int w,int h,Fl_Offscreen osrc,int srcx,int sr void fl_delete_offscreen(Fl_Offscreen ctx) { if (!ctx) return; void *data = CGBitmapContextGetData((CGContextRef)ctx); + CFIndex count = CFGetRetainCount(ctx); CGContextRelease((CGContextRef)ctx); - if (!data) return; - free(data); + if(count == 1) free(data); } const int stack_max = 16; static int stack_ix = 0; static CGContextRef stack_gc[stack_max]; static Window stack_window[stack_max]; +static Fl_Surface_Device *_ss; void fl_begin_offscreen(Fl_Offscreen ctx) { + _ss = fl_surface; + fl_display_device->set_current(); if (stack_ix0) stack_ix--; else @@ -243,6 +279,7 @@ void fl_end_offscreen() { fl_gc = stack_gc[stack_ix]; fl_window = stack_window[stack_ix]; } + _ss->set_current(); } extern void fl_restore_clip(); @@ -289,7 +326,7 @@ void Fl_Double_Window::flush(int eraseoverlay) { } #if USE_XDBE if (use_xdbe) { - if (myi->backbuffer_bad) { + if (myi->backbuffer_bad || eraseoverlay) { // Make sure we do a complete redraw... if (myi->region) {XDestroyRegion(myi->region); myi->region = 0;} clear_damage(FL_DAMAGE_ALL); @@ -353,7 +390,15 @@ void Fl_Double_Window::resize(int X,int Y,int W,int H) { int oh = h(); Fl_Window::resize(X,Y,W,H); #if USE_XDBE - if (use_xdbe) return; + if (use_xdbe) { + Fl_X* myi = Fl_X::i(this); + if (myi && myi->other_xid && (ow < w() || oh < h())) { + // STR #2152: Deallocate the back buffer to force creation of a new one. + XdbeDeallocateBackBufferName(fl_display,myi->other_xid); + myi->other_xid = 0; + } + return; + } #endif Fl_X* myi = Fl_X::i(this); if (myi && myi->other_xid && (ow != w() || oh != h())) { @@ -383,5 +428,5 @@ Fl_Double_Window::~Fl_Double_Window() { } // -// End of "$Id: Fl_Double_Window.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_Double_Window.cxx 7671 2010-07-09 17:31:33Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_File_Browser.cxx b/plugins/zynaddsubfx/fltk/src/Fl_File_Browser.cxx index 00b182ccf..78e21aa33 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_File_Browser.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_File_Browser.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_File_Browser.cxx 6853 2009-09-09 05:16:41Z greg.ercolano $" +// "$Id: Fl_File_Browser.cxx 7352 2010-03-29 10:47:11Z matt $" // // Fl_File_Browser routines. // @@ -65,14 +65,11 @@ # include #endif // __EMX__ -// CodeWarrior (__MWERKS__) gets its include paths confused, so we -// temporarily disable this... -#if defined(__APPLE__) && !defined(__MWERKS__) +#if defined(__APPLE__) # include # include # include -#endif // __APPLE__ && !__MWERKS__ - +#endif // __APPLE__ // // FL_BLINE definition from "Fl_Browser.cxx"... @@ -504,7 +501,7 @@ Fl_File_Browser::load(const char *directory,// I - Directory to load num_files ++; } -#elif defined(__APPLE__) && !defined(__MWERKS__) +#elif defined(__APPLE__) // MacOS X and Darwin use getfsstat() system call... int numfs; // Number of file systems struct statfs *fs; // Buffer for file system info @@ -642,5 +639,5 @@ Fl_File_Browser::filter(const char *pattern) // I - Pattern string // -// End of "$Id: Fl_File_Browser.cxx 6853 2009-09-09 05:16:41Z greg.ercolano $". +// End of "$Id: Fl_File_Browser.cxx 7352 2010-03-29 10:47:11Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_File_Chooser2.cxx b/plugins/zynaddsubfx/fltk/src/Fl_File_Chooser2.cxx index 58df478be..fda39ef6a 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_File_Chooser2.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_File_Chooser2.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_File_Chooser2.cxx 6899 2009-09-23 21:32:23Z matt $" +// "$Id: Fl_File_Chooser2.cxx 7672 2010-07-10 09:44:45Z matt $" // // More Fl_File_Chooser routines. // @@ -304,6 +304,9 @@ /** \fn void * Fl_File_Chooser::user_data() const Gets the file chooser user data d */ + + /** \fn Fl_File_Browser* Fl_File_Chooser::browser() + returns a pointer to the underlying Fl_File_Browser object */ // *** END OF OUT OF SOURCE DOC *** // Contents: @@ -858,7 +861,7 @@ Fl_File_Chooser::fileNameCB() } } else { // File doesn't exist, so beep at and alert the user... - fl_alert(existing_file_label); + fl_alert("%s",existing_file_label); } } else if (Fl::event_key() != FL_Delete && @@ -1028,6 +1031,8 @@ Fl_File_Chooser::filter(const char *p) // I - Pattern(s) if (!allfiles) showChoice->add(all_files_label); showChoice->add(custom_filter_label); + + // TODO: add a menu item to switch hidden files on and off showChoice->value(0); showChoiceCB(); @@ -1046,7 +1051,7 @@ Fl_File_Chooser::newdir() // Get a directory name from the user - if ((dir = fl_input(new_directory_label, NULL)) == NULL) + if ((dir = fl_input("%s", NULL, new_directory_label)) == NULL) return; // Make it relative to the current directory as needed... @@ -1213,7 +1218,7 @@ Fl_File_Chooser::showChoiceCB() item = showChoice->text(showChoice->value()); if (strcmp(item, custom_filter_label) == 0) { - if ((item = fl_input(custom_filter_label, pattern_)) != NULL) { + if ((item = fl_input("%s", pattern_, custom_filter_label)) != NULL) { strlcpy(pattern_, item, sizeof(pattern_)); quote_pathname(temp, item, sizeof(temp)); @@ -1284,24 +1289,48 @@ void Fl_File_Chooser::update_preview() { const char *filename; // Current filename - Fl_Shared_Image *image, // New image + const char *newlabel = 0; // New label text + Fl_Shared_Image *image = 0, // New image *oldimage; // Old image int pbw, pbh; // Width and height of preview box int w, h; // Width and height of preview image + int set = 0; // Set this flag as soon as a decent preview is found if (!previewButton->value()) return; - if ((filename = value()) == NULL || fl_filename_isdir(filename)) image = NULL; - else { - window->cursor(FL_CURSOR_WAIT); - Fl::check(); - - image = Fl_Shared_Image::get(filename); - - if (image) { - window->cursor(FL_CURSOR_DEFAULT); - Fl::check(); + filename = value(); + if (filename == NULL) { + // no file name at all, so we have an empty preview + set = 1; + } else if (fl_filename_isdir(filename)) { + // filename is a directory, show a folder icon + newlabel = "@fileopen"; + set = 1; + } else { + struct stat s; + if (fl_stat(filename, &s)==0) { + if ((s.st_mode&S_IFMT)!=S_IFREG) { + // this is no regular file, probably some kind of device + newlabel = "@-3refresh"; // a cross + set = 1; + } else if (s.st_size==0) { + // this file is emty + newlabel = ""; + set = 1; + } else { + // if this file is an image, try to load it + window->cursor(FL_CURSOR_WAIT); + Fl::check(); + + image = Fl_Shared_Image::get(filename); + + if (image) { + window->cursor(FL_CURSOR_DEFAULT); + Fl::check(); + set = 1; + } + } } } @@ -1311,7 +1340,7 @@ Fl_File_Chooser::update_preview() previewBox->image(0); - if (!image) { + if (!set) { FILE *fp; int bytes; char *ptr; @@ -1368,7 +1397,7 @@ Fl_File_Chooser::update_preview() // Non-printable file, just show a big ?... previewBox->label(filename ? "?" : 0); previewBox->align(FL_ALIGN_CLIP); - previewBox->labelsize(100); + previewBox->labelsize(75); previewBox->labelfont(FL_HELVETICA); } else { // Show the first 1k of text... @@ -1382,7 +1411,7 @@ Fl_File_Chooser::update_preview() previewBox->labelsize(size); previewBox->labelfont(FL_COURIER); } - } else { + } else if (image) { pbw = previewBox->w() - 20; pbh = previewBox->h() - 20; @@ -1405,6 +1434,11 @@ Fl_File_Chooser::update_preview() previewBox->align(FL_ALIGN_CLIP); previewBox->label(0); + } else if (newlabel) { + previewBox->label(newlabel); + previewBox->align(FL_ALIGN_CLIP); + previewBox->labelsize(newlabel[0]=='@'?75:12); + previewBox->labelfont(FL_HELVETICA); } previewBox->redraw(); @@ -1616,5 +1650,5 @@ unquote_pathname(char *dst, // O - Destination string // -// End of "$Id: Fl_File_Chooser2.cxx 6899 2009-09-23 21:32:23Z matt $". +// End of "$Id: Fl_File_Chooser2.cxx 7672 2010-07-10 09:44:45Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_File_Input.cxx b/plugins/zynaddsubfx/fltk/src/Fl_File_Input.cxx index d46c98452..dfed97bdd 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_File_Input.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_File_Input.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_File_Input.cxx 6758 2009-04-13 07:32:01Z matt $" +// "$Id: Fl_File_Input.cxx 7115 2010-02-20 17:40:07Z AlbrechtS $" // // File_Input header file for the Fast Light Tool Kit (FLTK). // @@ -215,9 +215,12 @@ Fl_File_Input::handle(int event) // I - Event return Fl_Input::handle(event); default : - if (Fl_Input::handle(event)) { - damage(FL_DAMAGE_BAR); - return 1; + { Fl_Widget_Tracker wp(this); + if (Fl_Input::handle(event)) { + if (wp.exists()) + damage(FL_DAMAGE_BAR); + return 1; + } } return 0; } @@ -290,5 +293,5 @@ Fl_File_Input::handle_button(int event) // I - Event // -// End of "$Id: Fl_File_Input.cxx 6758 2009-04-13 07:32:01Z matt $". +// End of "$Id: Fl_File_Input.cxx 7115 2010-02-20 17:40:07Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Font.H b/plugins/zynaddsubfx/fltk/src/Fl_Font.H index 9869eb752..4e79b3f93 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Font.H +++ b/plugins/zynaddsubfx/fltk/src/Fl_Font.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Font.H 6779 2009-04-24 09:28:30Z yuri $" +// "$Id: Fl_Font.H 7351 2010-03-29 10:35:00Z matt $" // // Font definitions for the Fast Light Tool Kit (FLTK). // @@ -58,15 +58,12 @@ public: TEXTMETRIC metr; int angle; FL_EXPORT Fl_Font_Descriptor(const char* fontname, Fl_Fontsize size); -# elif defined(__APPLE_QD__) - FL_EXPORT Fl_Font_Descriptor(const char* fontname, Fl_Fontsize size); - short font, face, size; - short ascent, descent; - short width[256]; - bool knowMetrics; # elif defined(__APPLE_QUARTZ__) FL_EXPORT Fl_Font_Descriptor(const char* fontname, Fl_Fontsize size); ATSUTextLayout layout; +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + CTFontRef fontref; +# endif ATSUStyle style; short ascent, descent, q_width; // short width[256]; @@ -118,5 +115,5 @@ FL_EXPORT char *fl_find_fontsize(char *name); #endif // -// End of "$Id: Fl_Font.H 6779 2009-04-24 09:28:30Z yuri $". +// End of "$Id: Fl_Font.H 7351 2010-03-29 10:35:00Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Gl_Choice.H b/plugins/zynaddsubfx/fltk/src/Fl_Gl_Choice.H index 3e3f86fd2..3c5bef1a0 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Gl_Choice.H +++ b/plugins/zynaddsubfx/fltk/src/Fl_Gl_Choice.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Gl_Choice.H 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_Gl_Choice.H 7564 2010-04-28 07:21:41Z greg.ercolano $" // // OpenGL definitions for the Fast Light Tool Kit (FLTK). // @@ -20,7 +20,9 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 // USA. // -// Please report all bugs and problems to "fltk-bugs@easysw.com". +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php // // Internal interface to set up OpenGL. @@ -57,10 +59,6 @@ #ifdef WIN32 # include # define GLContext HGLRC -#elif defined(__APPLE_QD__) -# include -# include -# define GLContext AGLContext #elif defined(__APPLE_QUARTZ__) // warning: the Quartz version should probably use Core GL (CGL) instead of AGL # include @@ -80,8 +78,6 @@ public: #ifdef WIN32 int pixelformat; // the visual to use PIXELFORMATDESCRIPTOR pfd; // some wgl calls need this thing -#elif defined(__APPLE_QD__) - AGLPixelFormat pixelformat; #elif defined(__APPLE_QUARTZ__) // warning: the Quartz version should probably use Core GL (CGL) instead of AGL AGLPixelFormat pixelformat; @@ -101,10 +97,6 @@ class Fl_Window; GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice*, int layer=0); -#elif defined(__APPLE_QD__) - -GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice*, int layer=0); - #elif defined(__APPLE_QUARTZ__) // warning: the Quartz version should probably use Core GL (CGL) instead of AGL @@ -128,5 +120,5 @@ void fl_delete_gl_context(GLContext); #endif // -// End of "$Id: Fl_Gl_Choice.H 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_Gl_Choice.H 7564 2010-04-28 07:21:41Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Group.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Group.cxx index 3373b321a..d77a75cfe 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Group.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Group.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Group.cxx 6656 2009-02-09 11:41:56Z AlbrechtS $" +// "$Id: Fl_Group.cxx 7469 2010-04-07 23:17:33Z matt $" // // Group widget for the Fast Light Tool Kit (FLTK). // @@ -77,7 +77,7 @@ void Fl_Group::begin() {current_ = this;} Exactly the same as current(this->parent()). Any new widgets added to the widget tree will be added to the parent of the group. */ -void Fl_Group::end() {current_ = (Fl_Group*)parent();} +void Fl_Group::end() {current_ = parent();} /** Returns the currently active group. @@ -102,7 +102,7 @@ static int send(Fl_Widget* o, int event) { if (o->type() < FL_WINDOW) return o->handle(event); switch ( event ) { - case FL_DND_ENTER: + case FL_DND_ENTER: /* FALLTHROUGH */ case FL_DND_DRAG: // figure out correct type of event: event = (o->contains(Fl::belowmouse())) ? FL_DND_DRAG : FL_DND_ENTER; @@ -114,7 +114,7 @@ static int send(Fl_Widget* o, int event) { Fl::e_x = save_x; switch ( event ) { - case FL_ENTER: + case FL_ENTER: /* FALLTHROUGH */ case FL_DND_ENTER: // Successful completion of FL_ENTER means the widget is now the // belowmouse widget, but only call Fl::belowmouse if the child @@ -227,8 +227,9 @@ int Fl_Group::handle(int event) { for (i = children(); i--;) { o = a[i]; if (o->takesevents() && Fl::event_inside(o)) { + Fl_Widget_Tracker wp(o); if (send(o,FL_PUSH)) { - if (Fl::pushed() && !o->contains(Fl::pushed())) Fl::pushed(o); + if (Fl::pushed() && wp.exists() && !o->contains(Fl::pushed())) Fl::pushed(o); return 1; } } @@ -428,7 +429,7 @@ Fl_Group::~Fl_Group() { */ void Fl_Group::insert(Fl_Widget &o, int index) { if (o.parent()) { - Fl_Group* g = (Fl_Group*)(o.parent()); + Fl_Group* g = o.parent(); int n = g->find(o); if (g == this) { if (index > n) index--; @@ -744,7 +745,23 @@ void Fl_Group::draw_outside_label(const Fl_Widget& widget) const { int Y = widget.y(); int W = widget.w(); int H = widget.h(); - if (a & FL_ALIGN_TOP) { + if ( (a & 0x0f) == FL_ALIGN_LEFT_TOP ) { + a = (a &~0x0f ) | FL_ALIGN_TOP_RIGHT; + X = x(); + W = widget.x()-X-3; + } else if ( (a & 0x0f) == FL_ALIGN_LEFT_BOTTOM ) { + a = (a &~0x0f ) | FL_ALIGN_BOTTOM_RIGHT; + X = x(); + W = widget.x()-X-3; + } else if ( (a & 0x0f) == FL_ALIGN_RIGHT_TOP ) { + a = (a &~0x0f ) | FL_ALIGN_TOP_LEFT; + X = X+W+3; + W = x()+this->w()-X; + } else if ( (a & 0x0f) == FL_ALIGN_RIGHT_BOTTOM ) { + a = (a &~0x0f ) | FL_ALIGN_BOTTOM_LEFT; + X = X+W+3; + W = x()+this->w()-X; + } else if (a & FL_ALIGN_TOP) { a ^= (FL_ALIGN_BOTTOM|FL_ALIGN_TOP); Y = y(); H = widget.y()-Y; @@ -765,5 +782,5 @@ void Fl_Group::draw_outside_label(const Fl_Widget& widget) const { } // -// End of "$Id: Fl_Group.cxx 6656 2009-02-09 11:41:56Z AlbrechtS $". +// End of "$Id: Fl_Group.cxx 7469 2010-04-07 23:17:33Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Image.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Image.cxx index e0ffc14fe..c7cebebb0 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Image.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Image.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Image.cxx 6804 2009-06-29 07:44:25Z AlbrechtS $" +// "$Id: Fl_Image.cxx 7659 2010-07-01 13:21:32Z manolo $" // // Image drawing code for the Fast Light Tool Kit (FLTK). // @@ -180,19 +180,19 @@ Fl_RGB_Image::~Fl_RGB_Image() { void Fl_RGB_Image::uncache() { #ifdef __APPLE_QUARTZ__ - if (id) { - CGImageRelease((CGImageRef)id); - id = 0; + if (id_) { + CGImageRelease((CGImageRef)id_); + id_ = 0; } #else - if (id) { - fl_delete_offscreen((Fl_Offscreen)id); - id = 0; + if (id_) { + fl_delete_offscreen((Fl_Offscreen)id_); + id_ = 0; } - if (mask) { - fl_delete_bitmask((Fl_Bitmask)mask); - mask = 0; + if (mask_) { + fl_delete_bitmask((Fl_Bitmask)mask_); + mask_ = 0; } #endif } @@ -375,7 +375,7 @@ void Fl_RGB_Image::desaturate() { d(new_d); } -#if !defined(WIN32) && !USE_QUARTZ +#if !defined(WIN32) && !defined(__APPLE_QUARTZ__) // Composite an image with alpha on systems that don't have accelerated // alpha compositing... static void alpha_blend(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, int cy) { @@ -431,115 +431,150 @@ static void alpha_blend(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, i delete[] dst; } -#endif // !WIN32 && !USE_QUARTZ +#endif // !WIN32 && !__APPLE_QUARTZ__ void Fl_RGB_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) { - // Don't draw an empty image... - if (!d() || !array) { - draw_empty(XP, YP); - return; - } + fl_graphics_driver->draw(this, XP, YP, WP, HP, cx, cy); +} +static int start(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int w, int h, int &cx, int &cy, + int &X, int &Y, int &W, int &H) +{ // account for current clip region (faster on Irix): - int X,Y,W,H; fl_clip_box(XP,YP,WP,HP,X,Y,W,H); + fl_clip_box(XP,YP,WP,HP,X,Y,W,H); cx += X-XP; cy += Y-YP; // clip the box down to the size of image, quit if empty: if (cx < 0) {W += cx; X -= cx; cx = 0;} - if (cx+W > w()) W = w()-cx; - if (W <= 0) return; + if (cx+W > w) W = w-cx; + if (W <= 0) return 1; if (cy < 0) {H += cy; Y -= cy; cy = 0;} - if (cy+H > h()) H = h()-cy; - if (H <= 0) return; - if (!id) { -#ifdef __APPLE_QUARTZ__ + if (cy+H > h) H = h-cy; + if (H <= 0) return 1; + return 0; +} + +#ifdef __APPLE__ +void Fl_Quartz_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + // Don't draw an empty image... + if (!img->d() || !img->array) { + img->draw_empty(XP, YP); + return; + } + if (start(img, XP, YP, WP, HP, img->w(), img->h(), cx, cy, X, Y, W, H)) { + return; + } + if (!img->id_) { CGColorSpaceRef lut = 0; - if (d()<=2) + if (img->d()<=2) lut = CGColorSpaceCreateDeviceGray(); else lut = CGColorSpaceCreateDeviceRGB(); - CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, w()*h()*d(), 0L); - id = CGImageCreate( w(), h(), 8, d()*8, ld()?ld():w()*d(), - lut, (d()&1)?kCGImageAlphaNone:kCGImageAlphaLast, - src, 0L, false, kCGRenderingIntentDefault); + CGDataProviderRef src = CGDataProviderCreateWithData( 0L, img->array, img->w()*img->h()*img->d(), 0L); + img->id_ = CGImageCreate( img->w(), img->h(), 8, img->d()*8, img->ld()?img->ld():img->w()*img->d(), + lut, (img->d()&1)?kCGImageAlphaNone:kCGImageAlphaLast, + src, 0L, false, kCGRenderingIntentDefault); CGColorSpaceRelease(lut); CGDataProviderRelease(src); + } + if (img->id_ && fl_gc) { + CGRect rect = { { X, Y }, { W, H } }; + Fl_X::q_begin_image(rect, cx, cy, img->w(), img->h()); + CGContextDrawImage(fl_gc, rect, (CGImageRef)img->id_); + Fl_X::q_end_image(); + } +} + #elif defined(WIN32) - id = fl_create_offscreen(w(), h()); - if ((d() == 2 || d() == 4) && fl_can_do_alpha_blending()) { - fl_begin_offscreen((Fl_Offscreen)id); - fl_draw_image(array, 0, 0, w(), h(), d()|FL_IMAGE_WITH_ALPHA, ld()); +void Fl_GDI_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + // Don't draw an empty image... + if (!img->d() || !img->array) { + img->draw_empty(XP, YP); + return; + } + if (start(img, XP, YP, WP, HP, img->w(), img->h(), cx, cy, X, Y, W, H)) { + return; + } + if (!img->id_) { + img->id_ = fl_create_offscreen(img->w(), img->h()); + if ((img->d() == 2 || img->d() == 4) && fl_can_do_alpha_blending()) { + fl_begin_offscreen((Fl_Offscreen)img->id_); + fl_draw_image(img->array, 0, 0, img->w(), img->h(), img->d()|FL_IMAGE_WITH_ALPHA, img->ld()); fl_end_offscreen(); } else { - fl_begin_offscreen((Fl_Offscreen)id); - fl_draw_image(array, 0, 0, w(), h(), d(), ld()); + fl_begin_offscreen((Fl_Offscreen)img->id_); + fl_draw_image(img->array, 0, 0, img->w(), img->h(), img->d(), img->ld()); fl_end_offscreen(); - if (d() == 2 || d() == 4) { - mask = fl_create_alphamask(w(), h(), d(), ld(), array); + if (img->d() == 2 || img->d() == 4) { + img->mask_ = fl_create_alphamask(img->w(), img->h(), img->d(), img->ld(), img->array); } } + } + if (img->mask_) { + HDC new_gc = CreateCompatibleDC(fl_gc); + int save = SaveDC(new_gc); + SelectObject(new_gc, (void*)img->mask_); + BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND); + SelectObject(new_gc, (void*)img->id_); + BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT); + RestoreDC(new_gc,save); + DeleteDC(new_gc); + } else if (img->d()==2 || img->d()==4) { + fl_copy_offscreen_with_alpha(X, Y, W, H, (Fl_Offscreen)img->id_, cx, cy); + } else { + fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)img->id_, cx, cy); + } +} + #else - if (d() == 1 || d() == 3) { - id = fl_create_offscreen(w(), h()); - fl_begin_offscreen((Fl_Offscreen)id); - fl_draw_image(array, 0, 0, w(), h(), d(), ld()); +void Fl_Xlib_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + // Don't draw an empty image... + if (!img->d() || !img->array) { + img->draw_empty(XP, YP); + return; + } + if (start(img, XP, YP, WP, HP, img->w(), img->h(), cx, cy, X, Y, W, H)) { + return; + } + if (!img->id_) { + if (img->d() == 1 || img->d() == 3) { + img->id_ = fl_create_offscreen(img->w(), img->h()); + fl_begin_offscreen((Fl_Offscreen)img->id_); + fl_draw_image(img->array, 0, 0, img->w(), img->h(), img->d(), img->ld()); fl_end_offscreen(); } -#endif } - -#if defined(USE_X11) - if (id) { - if (mask) { + if (img->id_) { + if (img->mask_) { // I can't figure out how to combine a mask with existing region, // so cut the image down to a clipped rectangle: int nx, ny; fl_clip_box(X,Y,W,H,nx,ny,W,H); cx += nx-X; X = nx; cy += ny-Y; Y = ny; // make X use the bitmap as a mask: - XSetClipMask(fl_display, fl_gc, mask); - int ox = X-cx; if (ox < 0) ox += w(); - int oy = Y-cy; if (oy < 0) oy += h(); + XSetClipMask(fl_display, fl_gc, img->mask_); + int ox = X-cx; if (ox < 0) ox += img->w(); + int oy = Y-cy; if (oy < 0) oy += img->h(); XSetClipOrigin(fl_display, fl_gc, X-cx, Y-cy); } - - fl_copy_offscreen(X, Y, W, H, id, cx, cy); - - if (mask) { + + fl_copy_offscreen(X, Y, W, H, img->id_, cx, cy); + + if (img->mask_) { // put the old clip region back XSetClipOrigin(fl_display, fl_gc, 0, 0); fl_restore_clip(); } } else { // Composite image with alpha manually each time... - alpha_blend(this, X, Y, W, H, cx, cy); + alpha_blend(img, X, Y, W, H, cx, cy); } -#elif defined(WIN32) - if (mask) { - HDC new_gc = CreateCompatibleDC(fl_gc); - int save = SaveDC(new_gc); - SelectObject(new_gc, (void*)mask); - BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND); - SelectObject(new_gc, (void*)id); - BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT); - RestoreDC(new_gc,save); - DeleteDC(new_gc); - } else if (d()==2 || d()==4) { - fl_copy_offscreen_with_alpha(X, Y, W, H, (Fl_Offscreen)id, cx, cy); - } else { - fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy); - } -#elif defined(__APPLE_QUARTZ__) - if (id && fl_gc) { - CGRect rect = { { X, Y }, { W, H } }; - Fl_X::q_begin_image(rect, cx, cy, w(), h()); - CGContextDrawImage(fl_gc, rect, (CGImageRef)id); - Fl_X::q_end_image(); - } -#else -# error unsupported platform -#endif } +#endif + void Fl_RGB_Image::label(Fl_Widget* widget) { widget->image(this); } @@ -551,5 +586,5 @@ void Fl_RGB_Image::label(Fl_Menu_Item* m) { // -// End of "$Id: Fl_Image.cxx 6804 2009-06-29 07:44:25Z AlbrechtS $". +// End of "$Id: Fl_Image.cxx 7659 2010-07-01 13:21:32Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Input.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Input.cxx index 7be68aafa..aeb096923 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Input.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Input.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Input.cxx 6888 2009-09-19 21:16:21Z matt $" +// "$Id: Fl_Input.cxx 6968 2009-12-13 14:44:30Z matt $" // // Input widget for the Fast Light Tool Kit (FLTK). // @@ -57,6 +57,7 @@ void Fl_Input::draw() { int Fl_Input::shift_position(int p) { return position(p, Fl::event_state(FL_SHIFT) ? mark() : p); } + int Fl_Input::shift_up_down_position(int p) { return up_down_position(p, Fl::event_state(FL_SHIFT)); } @@ -82,18 +83,18 @@ static const char *legal_fp_chars = ".eE+-"; #endif int Fl_Input::handle_key() { - + char ascii = Fl::event_text()[0]; - + int repeat_num=1; - + int del; if (Fl::compose(del)) { - + // Insert characters into numeric fields after checking for legality: if (input_type() == FL_FLOAT_INPUT || input_type() == FL_INT_INPUT) { Fl::compose_reset(); // ignore any foreign letters... - + // initialize the list of legal characters inside a floating point number #ifdef HAVE_LOCALECONV if (!legal_fp_chars) { @@ -118,20 +119,23 @@ int Fl_Input::handle_key() { } } #endif // HAVE_LOCALECONV - + + // find the insert position + int ip = position()= '0' && ascii <= '9') || - (position()==1 && index(0)=='0' && (ascii=='x' || ascii == 'X')) || - (position()>1 && index(0)=='0' && (index(1)=='x'||index(1)=='X') - && (ascii>='A'&& ascii<='F' || ascii>='a'&& ascii<='f')) || - input_type()==FL_FLOAT_INPUT && ascii && strchr(legal_fp_chars, ascii)) { + if (!ip && (ascii == '+' || ascii == '-') + || (ascii >= '0' && ascii <= '9') + || (ip==1 && index(0)=='0' && (ascii=='x' || ascii == 'X')) + || (ip>1 && index(0)=='0' && (index(1)=='x'||index(1)=='X') + && (ascii>='A'&& ascii<='F' || ascii>='a'&& ascii<='f')) + || input_type()==FL_FLOAT_INPUT && ascii && strchr(legal_fp_chars, ascii)) + { if (readonly()) fl_beep(); else replace(position(), mark(), &ascii, 1); } return 1; } - + if (del || Fl::event_length()) { if (readonly()) fl_beep(); else replace(position(), del ? position()-del : mark(), @@ -139,340 +143,340 @@ int Fl_Input::handle_key() { } return 1; } - + unsigned int mods = Fl::event_state() & (FL_META|FL_CTRL|FL_ALT); switch (Fl::event_key()) { - case FL_Insert: - if (Fl::event_state() & FL_CTRL) ascii = ctrl('C'); - else if (Fl::event_state() & FL_SHIFT) ascii = ctrl('V'); - break; - case FL_Delete: + case FL_Insert: + if (Fl::event_state() & FL_CTRL) ascii = ctrl('C'); + else if (Fl::event_state() & FL_SHIFT) ascii = ctrl('V'); + break; + case FL_Delete: #ifdef __APPLE__ - if (mods==0 || mods==FL_CTRL) { // delete next char - ascii = ctrl('D'); - } else if (mods==FL_ALT) { // delete next word - if (mark() != position()) return cut(); - cut(position(), word_end(position())); - return 1; - } else if (mods==FL_META) { // delete to the end of the line - if (mark() != position()) return cut(); - cut(position(), line_end(position())); - return 1; - } else return 1; + if (mods==0 || mods==FL_CTRL) { // delete next char + ascii = ctrl('D'); + } else if (mods==FL_ALT) { // delete next word + if (mark() != position()) return cut(); + cut(position(), word_end(position())); + return 1; + } else if (mods==FL_META) { // delete to the end of the line + if (mark() != position()) return cut(); + cut(position(), line_end(position())); + return 1; + } else return 1; #else - if (mods==0) { - ascii = ctrl('D'); - } else if (mods==FL_SHIFT) { - ascii = ctrl('X'); - } else return 1; + if (mods==0) { + ascii = ctrl('D'); + } else if (mods==FL_SHIFT) { + ascii = ctrl('X'); + } else return 1; #endif - break; - case FL_Left: + break; + case FL_Left: #ifdef __APPLE__ - if (mods==0) { // char left - ascii = ctrl('B'); - } else if (mods==FL_ALT) { // word left - shift_position(word_start(position())); - return 1; - } else if (mods==FL_CTRL || mods==FL_META) { // start of line - shift_position(line_start(position())); - return 1; - } else return 1; + if (mods==0) { // char left + ascii = ctrl('B'); + } else if (mods==FL_ALT) { // word left + shift_position(word_start(position())); + return 1; + } else if (mods==FL_CTRL || mods==FL_META) { // start of line + shift_position(line_start(position())); + return 1; + } else return 1; #else - if (mods==0) { // char left - ascii = ctrl('B'); - } else if (mods==FL_CTRL) { // word left - shift_position(word_start(position())); - return 1; - } else return 1; + if (mods==0) { // char left + ascii = ctrl('B'); + } else if (mods==FL_CTRL) { // word left + shift_position(word_start(position())); + return 1; + } else return 1; #endif - break; - case FL_Right: + break; + case FL_Right: #ifdef __APPLE__ - if (mods==0) { // char right - ascii = ctrl('F'); - } else if (mods==FL_ALT) { // word right - shift_position(word_end(position())); - return 1; - } else if (mods==FL_CTRL || mods==FL_META) { // end of line - shift_position(line_end(position())); - return 1; - } else return 1; + if (mods==0) { // char right + ascii = ctrl('F'); + } else if (mods==FL_ALT) { // word right + shift_position(word_end(position())); + return 1; + } else if (mods==FL_CTRL || mods==FL_META) { // end of line + shift_position(line_end(position())); + return 1; + } else return 1; #else - if (mods==0) { // char right - ascii = ctrl('F'); - } else if (mods==FL_CTRL) { // word right - shift_position(word_end(position())); - return 1; - } else return 1; + if (mods==0) { // char right + ascii = ctrl('F'); + } else if (mods==FL_CTRL) { // word right + shift_position(word_end(position())); + return 1; + } else return 1; #endif // __APPLE__ - break; - case FL_Page_Up: + break; + case FL_Page_Up: #ifdef __APPLE__ - if (mods==0) { // scroll text one page - // OS X scrolls the view, but does not move the cursor - // Fl_Input has no scroll control, so instead we move the cursor by one page + if (mods==0) { // scroll text one page + // OS X scrolls the view, but does not move the cursor + // Fl_Input has no scroll control, so instead we move the cursor by one page + repeat_num = linesPerPage(); + ascii = ctrl('P'); + } else if (mods==FL_ALT) { // move cursor one page + repeat_num = linesPerPage(); + ascii = ctrl('P'); + } else return 1; + break; +#else repeat_num = linesPerPage(); - ascii = ctrl('P'); - } else if (mods==FL_ALT) { // move cursor one page + // fall through +#endif + case FL_Up: +#ifdef __APPLE__ + if (mods==0) { // line up + ascii = ctrl('P'); + } else if (mods==FL_CTRL) { // scroll text down one page + // OS X scrolls the view, but does not move the cursor + // Fl_Input has no scroll control, so instead we move the cursor by one page + repeat_num = linesPerPage(); + ascii = ctrl('P'); + } else if (mods==FL_ALT) { // line start and up + if (line_start(position())==position() && position()>0) + return shift_position(line_start(position()-1)) + NORMAL_INPUT_MOVE; + else + return shift_position(line_start(position())) + NORMAL_INPUT_MOVE; + } else if (mods==FL_META) { // start of document + shift_position(0); + return 1; + } else return 1; +#else + if (mods==0) { // line up + ascii = ctrl('P'); + } else if (mods==FL_CTRL) { // scroll text down one line + // Fl_Input has no scroll control, so instead we move the cursor by one page + ascii = ctrl('P'); + } else return 1; +#endif + break; + case FL_Page_Down: +#ifdef __APPLE__ + if (mods==0) { // scroll text one page + // OS X scrolls the view, but does not move the cursor + // Fl_Input has no scroll control, so instead we move the cursor by one page + repeat_num = linesPerPage(); + ascii = ctrl('N'); + } else if (mods==FL_ALT) { // move cursor one page + repeat_num = linesPerPage(); + ascii = ctrl('N'); + } else return 1; + break; +#else repeat_num = linesPerPage(); - ascii = ctrl('P'); - } else return 1; - break; -#else - repeat_num = linesPerPage(); - // fall through + // fall through #endif - case FL_Up: + case FL_Down: #ifdef __APPLE__ - if (mods==0) { // line up - ascii = ctrl('P'); - } else if (mods==FL_CTRL) { // scroll text down one page - // OS X scrolls the view, but does not move the cursor - // Fl_Input has no scroll control, so instead we move the cursor by one page - repeat_num = linesPerPage(); - ascii = ctrl('P'); - } else if (mods==FL_ALT) { // line start and up - if (line_start(position())==position() && position()>0) - return shift_position(line_start(position()-1)) + NORMAL_INPUT_MOVE; - else - return shift_position(line_start(position())) + NORMAL_INPUT_MOVE; - } else if (mods==FL_META) { // start of document - shift_position(0); - return 1; - } else return 1; + if (mods==0) { // line down + ascii = ctrl('N'); + } else if (mods==FL_CTRL) { + // OS X scrolls the view, but does not move the cursor + // Fl_Input has no scroll control, so instead we move the cursor by one page + repeat_num = linesPerPage(); + ascii = ctrl('N'); + } else if (mods==FL_ALT) { // line end and down + if (line_end(position())==position() && position()=size()) return 0; + i = line_end(position()); + if (i == position() && i < size()) i++; + cut(position(), i); + return copy_cuts(); + case ctrl('N'): // go down one line + i = position(); + if (line_end(i) >= size()) return NORMAL_INPUT_MOVE; + while (repeat_num--) { + i = line_end(i); + if (i >= size()) break; + i++; + } + shift_up_down_position(i); return 1; - } - if (mark() != position()) cut(); - else cut(-1); - return 1; - case ctrl('K'): // cut to the end of the line - if (readonly()) { - fl_beep(); + case ctrl('P'): // go up one line + i = position(); + if (!line_start(i)) return NORMAL_INPUT_MOVE; + while(repeat_num--) { + i = line_start(i); + if (!i) break; + i--; + } + shift_up_down_position(line_start(i)); return 1; - } - if (position()>=size()) return 0; - i = line_end(position()); - if (i == position() && i < size()) i++; - cut(position(), i); - return copy_cuts(); - case ctrl('N'): // go down one line - i = position(); - if (line_end(i) >= size()) return NORMAL_INPUT_MOVE; - while (repeat_num--) { - i = line_end(i); - if (i >= size()) break; - i++; - } - shift_up_down_position(i); - return 1; - case ctrl('P'): // go up one line - i = position(); - if (!line_start(i)) return NORMAL_INPUT_MOVE; - while(repeat_num--) { - i = line_start(i); - if (!i) break; - i--; - } - shift_up_down_position(line_start(i)); - return 1; - case ctrl('U'): // clear the whole document? - if (readonly()) { - fl_beep(); + case ctrl('U'): // clear the whole document? + if (readonly()) { + fl_beep(); + return 1; + } + return cut(0, size()); + case ctrl('V'): // paste text + case ctrl('Y'): + if (readonly()) { + fl_beep(); + return 1; + } + Fl::paste(*this, 1); return 1; - } - return cut(0, size()); - case ctrl('V'): // paste text - case ctrl('Y'): - if (readonly()) { - fl_beep(); - return 1; - } - Fl::paste(*this, 1); - return 1; - case ctrl('X'): // cut the selected text - case ctrl('W'): - if (readonly()) { - fl_beep(); - return 1; - } - copy(1); - return cut(); - case ctrl('Z'): // undo - case ctrl('_'): - if (readonly()) { - fl_beep(); - return 1; - } - return undo(); - case ctrl('I'): // insert literal - case ctrl('J'): - case ctrl('L'): - case ctrl('M'): - if (readonly()) { - fl_beep(); - return 1; - } - // insert a few selected control characters literally: - if (input_type() != FL_FLOAT_INPUT && input_type() != FL_INT_INPUT) - return replace(position(), mark(), &ascii, 1); + case ctrl('X'): // cut the selected text + case ctrl('W'): + if (readonly()) { + fl_beep(); + return 1; + } + copy(1); + return cut(); + case ctrl('Z'): // undo + case ctrl('_'): + if (readonly()) { + fl_beep(); + return 1; + } + return undo(); + case ctrl('I'): // insert literal + case ctrl('J'): + case ctrl('L'): + case ctrl('M'): + if (readonly()) { + fl_beep(); + return 1; + } + // insert a few selected control characters literally: + if (input_type() != FL_FLOAT_INPUT && input_type() != FL_INT_INPUT) + return replace(position(), mark(), &ascii, 1); } - + return 0; } @@ -480,174 +484,174 @@ int Fl_Input::handle(int event) { static int dnd_save_position, dnd_save_mark, drag_start = -1, newpos; static Fl_Widget *dnd_save_focus; switch (event) { - case FL_FOCUS: - switch (Fl::event_key()) { - case FL_Right: - position(0); - break; - case FL_Left: - position(size()); - break; - case FL_Down: - up_down_position(0); - break; - case FL_Up: - up_down_position(line_start(size())); - break; - case FL_Tab: - case 0xfe20: // XK_ISO_Left_Tab - position(size(),0); - break; - default: - position(position(),mark());// turns off the saved up/down arrow position - break; - } - break; - - case FL_KEYBOARD: - if (Fl::event_key() == FL_Tab && mark() != position()) { - // Set the current cursor position to the end of the selection... - if (mark() > position()) - position(mark()); - else - position(position()); - return (1); - } else { - if (active_r() && window() && this == Fl::belowmouse()) - window()->cursor(FL_CURSOR_NONE); - return handle_key(); - } - - case FL_PUSH: - if (Fl::dnd_text_ops()) { - int oldpos = position(), oldmark = mark(); - Fl_Boxtype b = box(); - Fl_Input_::handle_mouse( - x()+Fl::box_dx(b), y()+Fl::box_dy(b), - w()-Fl::box_dw(b), h()-Fl::box_dh(b), 0); - newpos = position(); - position( oldpos, oldmark ); - if (Fl::focus()==this && !Fl::event_state(FL_SHIFT) && input_type()!=FL_SECRET_INPUT && - (newpos >= mark() && newpos < position() || - newpos >= position() && newpos < mark())) { - // user clicked in the selection, may be trying to drag - drag_start = newpos; - return 1; + case FL_FOCUS: + switch (Fl::event_key()) { + case FL_Right: + position(0); + break; + case FL_Left: + position(size()); + break; + case FL_Down: + up_down_position(0); + break; + case FL_Up: + up_down_position(line_start(size())); + break; + case FL_Tab: + case 0xfe20: // XK_ISO_Left_Tab + position(size(),0); + break; + default: + position(position(),mark());// turns off the saved up/down arrow position + break; } - drag_start = -1; - } - - if (Fl::focus() != this) { - Fl::focus(this); - handle(FL_FOCUS); - } - break; - - case FL_DRAG: - if (Fl::dnd_text_ops()) { - if (drag_start >= 0) { - if (Fl::event_is_click()) return 1; // debounce the mouse - // save the position because sometimes we don't get DND_ENTER: - dnd_save_position = position(); - dnd_save_mark = mark(); - // drag the data: - copy(0); Fl::dnd(); - return 1; + break; + + case FL_KEYBOARD: + if (Fl::event_key() == FL_Tab && mark() != position()) { + // Set the current cursor position to the end of the selection... + if (mark() > position()) + position(mark()); + else + position(position()); + return (1); + } else { + if (active_r() && window() && this == Fl::belowmouse()) + window()->cursor(FL_CURSOR_NONE); + return handle_key(); } - } - break; - - case FL_RELEASE: - if (Fl::event_button() == 2) { - Fl::event_is_click(0); // stop double click from picking a word - Fl::paste(*this, 0); - } else if (!Fl::event_is_click()) { - // copy drag-selected text to the clipboard. - copy(0); - } else if (Fl::event_is_click() && drag_start >= 0) { - // user clicked in the field and wants to reset the cursor position... - position(drag_start, drag_start); - drag_start = -1; - } else if (Fl::event_clicks()) { - // user double or triple clicked to select word or whole text - copy(0); - } - - // For output widgets, do the callback so the app knows the user - // did something with the mouse... - if (readonly()) do_callback(); - - return 1; - - case FL_DND_ENTER: - Fl::belowmouse(this); // send the leave events first - dnd_save_position = position(); - dnd_save_mark = mark(); - dnd_save_focus = Fl::focus(); - if (dnd_save_focus != this) { - Fl::focus(this); - handle(FL_FOCUS); - } - // fall through: - case FL_DND_DRAG: - //int p = mouse_position(X, Y, W, H); + + case FL_PUSH: + if (Fl::dnd_text_ops()) { + int oldpos = position(), oldmark = mark(); + Fl_Boxtype b = box(); + Fl_Input_::handle_mouse( + x()+Fl::box_dx(b), y()+Fl::box_dy(b), + w()-Fl::box_dw(b), h()-Fl::box_dh(b), 0); + newpos = position(); + position( oldpos, oldmark ); + if (Fl::focus()==this && !Fl::event_state(FL_SHIFT) && input_type()!=FL_SECRET_INPUT && + (newpos >= mark() && newpos < position() || + newpos >= position() && newpos < mark())) { + // user clicked in the selection, may be trying to drag + drag_start = newpos; + return 1; + } + drag_start = -1; + } + + if (Fl::focus() != this) { + Fl::focus(this); + handle(FL_FOCUS); + } + break; + + case FL_DRAG: + if (Fl::dnd_text_ops()) { + if (drag_start >= 0) { + if (Fl::event_is_click()) return 1; // debounce the mouse + // save the position because sometimes we don't get DND_ENTER: + dnd_save_position = position(); + dnd_save_mark = mark(); + // drag the data: + copy(0); Fl::dnd(); + return 1; + } + } + break; + + case FL_RELEASE: + if (Fl::event_button() == 2) { + Fl::event_is_click(0); // stop double click from picking a word + Fl::paste(*this, 0); + } else if (!Fl::event_is_click()) { + // copy drag-selected text to the clipboard. + copy(0); + } else if (Fl::event_is_click() && drag_start >= 0) { + // user clicked in the field and wants to reset the cursor position... + position(drag_start, drag_start); + drag_start = -1; + } else if (Fl::event_clicks()) { + // user double or triple clicked to select word or whole text + copy(0); + } + + // For output widgets, do the callback so the app knows the user + // did something with the mouse... + if (readonly()) do_callback(); + + return 1; + + case FL_DND_ENTER: + Fl::belowmouse(this); // send the leave events first + dnd_save_position = position(); + dnd_save_mark = mark(); + dnd_save_focus = Fl::focus(); + if (dnd_save_focus != this) { + Fl::focus(this); + handle(FL_FOCUS); + } + // fall through: + case FL_DND_DRAG: + //int p = mouse_position(X, Y, W, H); #if DND_OUT_XXXX - if (Fl::focus()==this && (p>=dnd_save_position && p<=dnd_save_mark || - p>=dnd_save_mark && p<=dnd_save_position)) { - position(dnd_save_position, dnd_save_mark); - return 0; - } + if (Fl::focus()==this && (p>=dnd_save_position && p<=dnd_save_mark || + p>=dnd_save_mark && p<=dnd_save_position)) { + position(dnd_save_position, dnd_save_mark); + return 0; + } #endif { Fl_Boxtype b = box(); Fl_Input_::handle_mouse( - x()+Fl::box_dx(b), y()+Fl::box_dy(b), - w()-Fl::box_dw(b), h()-Fl::box_dh(b), 0); + x()+Fl::box_dx(b), y()+Fl::box_dy(b), + w()-Fl::box_dw(b), h()-Fl::box_dh(b), 0); } - return 1; - - case FL_DND_LEAVE: - position(dnd_save_position, dnd_save_mark); + return 1; + + case FL_DND_LEAVE: + position(dnd_save_position, dnd_save_mark); #if DND_OUT_XXXX - if (!focused()) + if (!focused()) #endif - if (dnd_save_focus != this) { - Fl::focus(dnd_save_focus); - handle(FL_UNFOCUS); - } - return 1; - - case FL_DND_RELEASE: - take_focus(); - return 1; - -/* TODO: this will scroll the area, but stop if the cursor would become invisible. - That clipping happens in drawtext(). Do we change the clipping or should - we move the cursor (ouch)? - case FL_MOUSEWHEEL: - if (Fl::e_dy > 0) { - yscroll( yscroll() - Fl::e_dy*15 ); - } else if (Fl::e_dy < 0) { - yscroll( yscroll() - Fl::e_dy*15 ); - } - return 1; -*/ - + if (dnd_save_focus != this) { + Fl::focus(dnd_save_focus); + handle(FL_UNFOCUS); + } + return 1; + + case FL_DND_RELEASE: + take_focus(); + return 1; + + /* TODO: this will scroll the area, but stop if the cursor would become invisible. + That clipping happens in drawtext(). Do we change the clipping or should + we move the cursor (ouch)? + case FL_MOUSEWHEEL: + if (Fl::e_dy > 0) { + yscroll( yscroll() - Fl::e_dy*15 ); + } else if (Fl::e_dy < 0) { + yscroll( yscroll() - Fl::e_dy*15 ); + } + return 1; + */ + } Fl_Boxtype b = box(); return Fl_Input_::handletext(event, - x()+Fl::box_dx(b), y()+Fl::box_dy(b), - w()-Fl::box_dw(b), h()-Fl::box_dh(b)); + x()+Fl::box_dx(b), y()+Fl::box_dy(b), + w()-Fl::box_dw(b), h()-Fl::box_dh(b)); } /** - Creates a new Fl_Input widget using the given position, size, - and label string. The default boxtype is FL_DOWN_BOX. -*/ + Creates a new Fl_Input widget using the given position, size, + and label string. The default boxtype is FL_DOWN_BOX. + */ Fl_Input::Fl_Input(int X, int Y, int W, int H, const char *l) : Fl_Input_(X, Y, W, H, l) { } // -// End of "$Id: Fl_Input.cxx 6888 2009-09-19 21:16:21Z matt $". +// End of "$Id: Fl_Input.cxx 6968 2009-12-13 14:44:30Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Input_.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Input_.cxx index ca6638c60..6a94ad19a 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Input_.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Input_.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Input_.cxx 6887 2009-09-19 20:57:48Z matt $" +// "$Id: Fl_Input_.cxx 7672 2010-07-10 09:44:45Z matt $" // // Common input widget routines for the Fast Light Tool Kit (FLTK). // @@ -722,12 +722,12 @@ static void undobuffersize(int n) { when() & FL_WHEN_CHANGED and there is a change. Set \p b and \p e equal to not delete anything. - Set insert to \c NULL to not insert anything. + Set \p text to \c NULL to not insert anything. - \p ilen must be zero or strlen(insert), this + \p ilen can be zero or strlen(text), which saves a tiny bit of time if you happen to already know the length of the insertion, or can be used to insert a portion of a - string or a string containing nul's. + string. \p b and \p e are clamped to the 0..size() range, so it is safe to pass any values. @@ -1247,12 +1247,12 @@ int Fl_Input_::linesPerPage() { \param [in] i index into the value field \return the character at index \p i */ -Fl_Char Fl_Input_::index(int i) const +unsigned int Fl_Input_::index(int i) const { int len = 0; return fl_utf8decode(value_+i, value_+size_, &len); } // -// End of "$Id: Fl_Input_.cxx 6887 2009-09-19 20:57:48Z matt $". +// End of "$Id: Fl_Input_.cxx 7672 2010-07-10 09:44:45Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Menu.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Menu.cxx index f49d89668..d8a7c1273 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Menu.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Menu.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Menu.cxx 6841 2009-08-03 06:26:32Z AlbrechtS $" +// "$Id: Fl_Menu.cxx 7151 2010-02-26 13:28:36Z matt $" // // Menu code for the Fast Light Tool Kit (FLTK). // @@ -330,12 +330,24 @@ menuwindow::menuwindow(const Fl_Menu_Item* m, int X, int Y, int Wp, int Hp, if (hh+LEADING>itemheight) itemheight = hh+LEADING; if (m->flags&(FL_SUBMENU|FL_SUBMENU_POINTER)) w1 += 14; if (w1 > W) W = w1; + // calculate the maximum width of all shortcuts if (m->shortcut_) { + // s is a pointerto the utf8 string for the entire shortcut + // k points only to the key part (minus the modifier keys) const char *k, *s = fl_shortcut_label(m->shortcut_, &k); - w1 = int(fl_width(s, k-s)); - if (w1 > hotModsw) hotModsw = w1; - w1 = int(fl_width(k))+4; - if (w1 > hotKeysw) hotKeysw = w1; + if (fl_utf_nb_char((const unsigned char*)k, strlen(k))<=4) { + // a regular shortcut has a right-justified modifier followed by a left-justified key + w1 = int(fl_width(s, k-s)); + if (w1 > hotModsw) hotModsw = w1; + w1 = int(fl_width(k))+4; + if (w1 > hotKeysw) hotKeysw = w1; + } else { + // a shortcut with a long modifier is right-justified to the menu + w1 = int(fl_width(s))+4; + if (w1 > (hotModsw+hotKeysw)) { + hotModsw = w1-hotKeysw; + } + } } if (m->labelcolor_ || Fl::scheme() || m->labeltype_ > FL_NO_LABEL) clear_overlay(); } @@ -446,9 +458,15 @@ void menuwindow::drawentry(const Fl_Menu_Item* m, int n, int eraseit) { fl_font(f, m->labelsize_ ? m->labelsize_ : button ? button->textsize() : FL_NORMAL_SIZE); const char *k, *s = fl_shortcut_label(m->shortcut_, &k); - char buf[32]; strcpy(buf, s); buf[k-s] = 0; - fl_draw(buf, xx, yy, ww-shortcutWidth, hh, FL_ALIGN_RIGHT); - fl_draw( k, xx+ww-shortcutWidth, yy, shortcutWidth, hh, FL_ALIGN_LEFT); + if (fl_utf_nb_char((const unsigned char*)k, strlen(k))<=4) { + // righ-align the modifiers and left-align the key + char buf[32]; strcpy(buf, s); buf[k-s] = 0; + fl_draw(buf, xx, yy, ww-shortcutWidth, hh, FL_ALIGN_RIGHT); + fl_draw( k, xx+ww-shortcutWidth, yy, shortcutWidth, hh, FL_ALIGN_LEFT); + } else { + // right-align to the menu + fl_draw(s, xx, yy, ww-4, hh, FL_ALIGN_RIGHT); + } } if (m->flags & FL_MENU_DIVIDER) { @@ -1014,5 +1032,5 @@ const Fl_Menu_Item* Fl_Menu_Item::test_shortcut() const { } // -// End of "$Id: Fl_Menu.cxx 6841 2009-08-03 06:26:32Z AlbrechtS $". +// End of "$Id: Fl_Menu.cxx 7151 2010-02-26 13:28:36Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Menu_.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Menu_.cxx index 3c83ae7b9..af855f957 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Menu_.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Menu_.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Menu_.cxx 6904 2009-09-27 11:39:02Z matt $" +// "$Id: Fl_Menu_.cxx 7517 2010-04-16 17:55:45Z greg.ercolano $" // // Common menu code for the Fast Light Tool Kit (FLTK). // @@ -39,12 +39,36 @@ #define SAFE_STRCAT(s) { len += strlen(s); if ( len >= namelen ) { *name='\0'; return(-2); } else strcat(name,(s)); } -/** Set 'pathname' of specified menuitem - If finditem==NULL, mvalue() is used (the most recently picked menuitem) - Returns: - - 0 : OK - - -1 : item not found (name="") - - -2 : 'name' not large enough (name="") +/** Get the menu 'pathname' for the specified menuitem. + + If finditem==NULL, mvalue() is used (the most recently picked menuitem). + + \b Example: + \code + Fl_Menu_Bar *menubar = 0; + void my_menu_callback(Fl_Widget*,void*) { + char name[80]; + if ( menubar->item_pathname(name, sizeof(name)-1) == 0 ) { // recently picked item + if ( strcmp(name, "File/&Open") == 0 ) { .. } // open invoked + if ( strcmp(name, "File/&Save") == 0 ) { .. } // save invoked + if ( strcmp(name, "Edit/&Copy") == 0 ) { .. } // copy invoked + } + } + int main() { + [..] + menubar = new Fl_Menu_Bar(..); + menubar->add("File/&Open", 0, my_menu_callback); + menubar->add("File/&Save", 0, my_menu_callback); + menubar->add("Edit/&Copy", 0, my_menu_callback); + [..] + } + \endcode + + \returns + - 0 : OK (name has menuitem's pathname) + - -1 : item not found (name="") + - -2 : 'name' not large enough (name="") + \see find_item() */ int Fl_Menu_::item_pathname(char *name, int namelen, const Fl_Menu_Item *finditem) const { int len = 0; @@ -55,6 +79,7 @@ int Fl_Menu_::item_pathname(char *name, int namelen, const Fl_Menu_Item *findite if ( m->submenu() ) { // submenu? descend if (*name) SAFE_STRCAT("/"); if (m->label()) SAFE_STRCAT(m->label()); + if ( m == finditem ) return(0); // found? done. } else { if (m->label()) { // menu item? if ( m == finditem ) { // found? tack on itemname, done. @@ -75,23 +100,106 @@ int Fl_Menu_::item_pathname(char *name, int namelen, const Fl_Menu_Item *findite } /** - Find menu item index, given menu pathname - eg. "Edit/Copy" - Will also return submenus, eg. "Edit" - Returns NULL if not found. -*/ -const Fl_Menu_Item * Fl_Menu_::find_item(const char *name) { - char menupath[1024] = ""; // File/Export + Find the menu item for a given menu \p pathname, such as "Edit/Copy". + + This method finds a menu item in the menu array, also traversing submenus, but + not submenu pointers. + To get the menu item's index, use find_index(const char*) + + \b Example: + \code + Fl_Menu_Bar *menubar = new Fl_Menu_Bar(..); + menubar->add("File/&Open"); + menubar->add("File/&Save"); + menubar->add("Edit/&Copy"); + // [..] + Fl_Menu_Item *item; + if ( ( item = (Fl_Menu_Item*)menubar->find_item("File/&Open") ) != NULL ) { + item->labelcolor(FL_RED); + } + if ( ( item = (Fl_Menu_Item*)menubar->find_item("Edit/&Copy") ) != NULL ) { + item->labelcolor(FL_GREEN); + } + \endcode + + \param pathname The path and name of the menu item + \returns The item found, or NULL if not found + \see find_index(const char*), find_item(Fl_Callback*), item_pathname() +*/ +const Fl_Menu_Item * Fl_Menu_::find_item(const char *pathname) { + int i = find_index(pathname); + return( (i==-1) ? 0 : (const Fl_Menu_Item*)(menu_+i)); +} + +/** + Find the index the menu array for given \p item. + + A way to convert a menu item pointer into an index. + + Current implementation is fast and not expensive. + + \code + // Convert an index-to-item + int index = 12; + const Fl_Menu_Item *item = mymenu->menu() + index; + + // Convert an item-to-index + int index = mymenu->find_index(item); + if ( index == -1 ) { ..error.. } + \endcode + + \param item The *item to be found + \returns The index of the item, or -1 if not found. + \see menu() +*/ +int Fl_Menu_::find_index(const Fl_Menu_Item *item) const { + Fl_Menu_Item *max = menu_+size(); + if (item=max) return(-1); + return(item-menu_); +} + +/** + Find the index into the menu array for a given callback \p cb. + + This method finds a menu item's index position, also traversing submenus, but + not submenu pointers. This is useful if an application uses internationalisation + and a menu item can not be found using its label. This search is also much faster. + + \param cb Find the first item with this callback + \returns The index of the item with the specific callback, or -1 if not found + \see find_index(const char*) + */ +int Fl_Menu_::find_index(Fl_Callback *cb) const { + for ( int t=0; t < size(); t++ ) + if (menu_[t].callback_==cb) + return(t); + return(-1); +} + +/** + Find the menu item index for a given menu \p pathname, such as "Edit/Copy". + + This method finds a menu item's index position for the given menu pathname, + also traversing submenus, but not submenu pointers. + + To get the menu item pointer for a pathname, use find_item() + + \param pathname The path and name of the menu item index to find + \returns The index of the matching item, or -1 if not found. + \see item_pathname() + +*/ +int Fl_Menu_::find_index(const char *pathname) const { + char menupath[1024] = ""; // File/Export for ( int t=0; t < size(); t++ ) { Fl_Menu_Item *m = menu_ + t; - if (m->flags&FL_SUBMENU) { // IT'S A SUBMENU // we do not support searches through FL_SUBMENU_POINTER links if (menupath[0]) strlcat(menupath, "/", sizeof(menupath)); strlcat(menupath, m->label(), sizeof(menupath)); - if (!strcmp(menupath, name)) return m; + if (!strcmp(menupath, pathname)) return(t); } else { if (!m->label()) { // END OF SUBMENU? Pop back one level. @@ -100,16 +208,36 @@ const Fl_Menu_Item * Fl_Menu_::find_item(const char *name) { else menupath[0] = '\0'; continue; } - // IT'S A MENU ITEM char itempath[1024]; // eg. Edit/Copy strcpy(itempath, menupath); if (itempath[0]) strlcat(itempath, "/", sizeof(itempath)); strlcat(itempath, m->label(), sizeof(itempath)); - if (!strcmp(itempath, name)) return m; + if (!strcmp(itempath, pathname)) return(t); } } + return(-1); +} +/** + Find the menu item for the given callback \p cb. + + This method finds a menu item in a menu array, also traversing submenus, but + not submenu pointers. This is useful if an application uses + internationalisation and a menu item can not be found using its label. This + search is also much faster. + + \param cb find the first item with this callback + \returns The item found, or NULL if not found + \see find_item(const char*) + */ +const Fl_Menu_Item * Fl_Menu_::find_item(Fl_Callback *cb) { + for ( int t=0; t < size(); t++ ) { + const Fl_Menu_Item *m = menu_ + t; + if (m->callback_==cb) { + return m; + } + } return (const Fl_Menu_Item *)0; } @@ -206,7 +334,7 @@ int Fl_Menu_::size() const { Sets the menu array pointer directly. If the old menu is private it is deleted. NULL is allowed and acts the same as a zero-length menu. If you try to modify the array (with add(), replace(), or - delete()) a private copy is automatically done. + remove()) a private copy is automatically done. */ void Fl_Menu_::menu(const Fl_Menu_Item* m) { clear(); @@ -217,7 +345,7 @@ void Fl_Menu_::menu(const Fl_Menu_Item* m) { /** Sets the menu array pointer with a copy of m that will be automatically deleted. - If ud is not NULL, then all user data pointers are changed in the menus as well. + If userdata \p ud is not NULL, then all user data pointers are changed in the menus as well. See void Fl_Menu_::menu(const Fl_Menu_Item* m). */ void Fl_Menu_::copy(const Fl_Menu_Item* m, void* ud) { @@ -261,6 +389,47 @@ void Fl_Menu_::clear() { } } +/** + Clears the specified submenu pointed to by \p index of all menu items. + + This method is useful for clearing a submenu so that it can be + re-populated with new items. Example: a "File/Recent Files/..." submenu + that shows the last few files that have been opened. + + The specified \p index must point to a submenu. + + The submenu is cleared with remove(). + If the menu array was directly set with menu(x), then copy() + is done to make a private array. + + \warning Since this method can change the internal menu array, any menu + item pointers or indecies the application may have cached can become + stale, and should be recalculated/refreshed. + + \b Example: + \code + int index = menubar->find_index("File/Recent"); // get index of "File/Recent" submenu + if ( index != -1 ) menubar->clear_submenu(index); // clear the submenu + menubar->add("File/Recent/Aaa"); + menubar->add("File/Recent/Bbb"); + [..] + \endcode + + \param index The index of the submenu to be cleared + \returns 0 on success, -1 if the index is out of range or not a submenu + \see remove(int) + */ +int Fl_Menu_::clear_submenu(int index) { + if ( index < 0 || index >= size() ) return(-1); + if ( ! (menu_[index].flags & FL_SUBMENU) ) return(-1); + ++index; // advance to first item in submenu + while ( index < size() ) { // keep remove()ing top item until end is reached + if ( menu_[index].text == 0 ) break; // end of this submenu? done + remove(index); // remove items/submenus + } + return(0); +} + // -// End of "$Id: Fl_Menu_.cxx 6904 2009-09-27 11:39:02Z matt $". +// End of "$Id: Fl_Menu_.cxx 7517 2010-04-16 17:55:45Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Menu_Button.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Menu_Button.cxx index 0334b2e35..a808d3194 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Menu_Button.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Menu_Button.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Menu_Button.cxx 6659 2009-02-15 13:49:34Z AlbrechtS $" +// "$Id: Fl_Menu_Button.cxx 7162 2010-02-26 21:10:46Z matt $" // // Menu button widget for the Fast Light Tool Kit (FLTK). // @@ -73,7 +73,7 @@ const Fl_Menu_Item* Fl_Menu_Button::popup() { int Fl_Menu_Button::handle(int e) { if (!menu() || !menu()->text) return 0; switch (e) { - case FL_ENTER: + case FL_ENTER: /* FALLTHROUGH */ case FL_LEAVE: return (box() && !type()) ? 1 : 0; case FL_PUSH: @@ -95,7 +95,7 @@ int Fl_Menu_Button::handle(int e) { case FL_SHORTCUT: if (Fl_Widget::test_shortcut()) {popup(); return 1;} return test_shortcut() != 0; - case FL_FOCUS: + case FL_FOCUS: /* FALLTHROUGH */ case FL_UNFOCUS: if (box() && Fl::visible_focus()) { redraw(); @@ -118,5 +118,5 @@ Fl_Menu_Button::Fl_Menu_Button(int X,int Y,int W,int H,const char *l) } // -// End of "$Id: Fl_Menu_Button.cxx 6659 2009-02-15 13:49:34Z AlbrechtS $". +// End of "$Id: Fl_Menu_Button.cxx 7162 2010-02-26 21:10:46Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Menu_add.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Menu_add.cxx index cbeeb631a..c36eb2939 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Menu_add.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Menu_add.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Menu_add.cxx 6878 2009-09-17 22:12:24Z matt $" +// "$Id: Fl_Menu_add.cxx 7519 2010-04-16 19:50:40Z greg.ercolano $" // // Menu utilities for the Fast Light Tool Kit (FLTK). // @@ -53,11 +53,12 @@ extern Fl_Menu_* fl_menu_array_owner; // in Fl_Menu_.cxx // Insert a single Fl_Menu_Item into an array of size at offset n, // if this is local_array it will be reallocated if needed. -static Fl_Menu_Item* insert( - Fl_Menu_Item* array, int size, - int n, - const char *text, - int flags +static Fl_Menu_Item* array_insert( + Fl_Menu_Item* array, // array to modify + int size, // size of array + int n, // index of new insert position + const char *text, // text of new item (copy is made) + int flags // flags for new item ) { if (array == local_array && size >= local_array_alloc) { local_array_alloc = 2*size; @@ -106,6 +107,27 @@ int Fl_Menu_Item::add( Fl_Callback *cb, void *data, int myflags +) { + return(insert(-1,mytext,sc,cb,data,myflags)); // -1: append +} + +/** Inserts an item at position \p index. + + If \p index is -1, the item is added the same way as Fl_Menu_Item::add(). + + If 'mytext' contains any un-escaped front slashes (/), it's assumed + a menu pathname is being specified, and the value of \p index + will be ignored. + + In all other aspects, the behavior of insert() is the same as add(). +*/ +int Fl_Menu_Item::insert( + int index, + const char *mytext, + int sc, + Fl_Callback *cb, + void *data, + int myflags ) { Fl_Menu_Item *array = this; Fl_Menu_Item *m = this; @@ -133,17 +155,18 @@ int Fl_Menu_Item::add( item = buf; if (*p != '/') break; /* not a menu title */ - mytext = p+1; /* point at item title */ + index = -1; /* any submenu specified overrides insert position */ + mytext = p+1; /* point at item title */ /* find a matching menu title: */ for (; m->text; m = m->next()) if (m->flags&FL_SUBMENU && !compare(item, m->text)) break; if (!m->text) { /* create a new menu */ - int n = m-array; - array = insert(array, msize, n, item, FL_SUBMENU|flags1); + int n = (index==-1) ? m-array : index; + array = array_insert(array, msize, n, item, FL_SUBMENU|flags1); msize++; - array = insert(array, msize, n+1, 0, 0); + array = array_insert(array, msize, n+1, 0, 0); msize++; m = array+n; } @@ -156,11 +179,11 @@ int Fl_Menu_Item::add( if (!(m->flags&FL_SUBMENU) && !compare(m->text,item)) break; if (!m->text) { /* add a new menu item */ - int n = m-array; - array = insert(array, msize, n, item, myflags|flags1); + int n = (index==-1) ? m-array : index; + array = array_insert(array, msize, n, item, myflags|flags1); msize++; if (myflags & FL_SUBMENU) { // add submenu delimiter - array = insert(array, msize, n+1, 0, 0); + array = array_insert(array, msize, n+1, 0, 0); msize++; } m = array+n; @@ -179,17 +202,21 @@ int Fl_Menu_Item::add( /** Adds a new menu item. - \param[in] label The text label for the menu item. + \param[in] label The text label for the menu item. \param[in] shortcut Optional keyboard shortcut that can be an int or string; (FL_CTRL+'a') or "^a". Default 0 if none. \param[in] callback Optional callback invoked when user clicks the item. Default 0 if none. \param[in] userdata Optional user data passed as an argument to the callback. Default 0 if none. - \param[in] flags Optional flags that control the type of menu item; see below. Default is 0 for none. - \returns The index into the menu() array, where the entry was added. + \param[in] flags Optional flags that control the type of menu item; see below. Default is 0 for none. + \returns The index into the menu() array, where the entry was added. \par Description If the menu array was directly set with menu(x), then copy() is done to make a private array. \par + Since this method can change the internal menu array, any menu item + pointers or indecies the application may have cached can become stale, + and should be recalculated/refreshed. + \par A menu item's callback must not add() items to its parent menu during the callback. Detailed Description of Parameters @@ -219,23 +246,32 @@ int Fl_Menu_Item::add( \par This parameter is optional, and defaults to 0 to indicate no shortcut. \par - Shortcut can be 0L, or either a modifier/key combination (for example - FL_CTRL+'A') or a string describing the shortcut in one of two ways: + The shortcut can either be a raw integer value (eg. FL_CTRL+'A') + or a string (eg. "^c" or "^97"). + \par + Raw integer shortcuts can be a combination of keyboard chars (eg. 'A') + and optional keyboard modifiers (see Fl::event_state(), e.g. FL_SHIFT, etc). + \par + String shortcuts can be specified in one of two ways: + \par \verbatim [#+^] e.g. "97", "^97", "+97", "#97" [#+^] e.g. "a", "^a", "+a", "#a" \endverbatim + \par ..where \ is a decimal value representing an - ascii character (eg. 97 is the ascii for 'a'), and the optional + ascii character (eg. 97 is the ascii code for 'a'), and the optional prefixes enhance the value that follows. Multiple prefixes must appear in the above order. + \par \verbatim # - Alt + - Shift ^ - Control \endverbatim - Text shortcuts are converted to integer shortcut by calling - Fl_Shortcut fl_old_shortcut(const char*). + \par + Internally, the text shortcuts are converted to integer values using + fl_old_shortcut(const char*). \par callback The callback to invoke when this menu item is selected. @@ -264,8 +300,52 @@ int Fl_Menu_Item::add( FL_MENU_DIVIDER // Creates divider line below this item. Also ends a group of radio buttons. \endcode + \todo Raw integer shortcut needs examples. + Dependent on responses to http://fltk.org/newsgroups.php?gfltk.development+v:10086 and results of STR#2344 */ int Fl_Menu_::add(const char *label,int shortcut,Fl_Callback *callback,void *userdata,int flags) { + return(insert(-1,label,shortcut,callback,userdata,flags)); // -1: append +} + +/** + Inserts a new menu item at the specified \p index position. + + If \p index is -1, the menu item is appended; same behavior as add(). + + To properly insert a menu item, \p label must be the name of the item (eg. "Quit"), + and not a 'menu pathname' (eg. "File/Quit"). If a menu pathname is specified, + the value of \p index is \em ignored, the new item's position defined by the pathname. + + For more details, see add(). Except for the \p index parameter, add() + has more detailed information on parameters and behavior, and is + functionally equivalent. + + \param[in] index The menu array's index position where the new item + is inserted. If -1, behavior is the same as add(). + \param[in] label The text label for the menu item. If the label + is a menu pathname, \p index is ignored, and the pathname + indicates the position of the new item. + \param[in] shortcut Optional keyboard shortcut. Can be an int (FL_CTRL+'a') + or a string ("^a"). Default is 0. + \param[in] callback Optional callback invoked when user clicks the item. + Default 0 if none. + \param[in] userdata Optional user data passed as an argument to the callback. + Default 0 if none. + \param[in] flags Optional flags that control the type of menu item; + see add() for more info. Default is 0 for none. + \returns The index into the menu() array, where the entry was added. + + \see add() + + */ +int Fl_Menu_::insert( + int index, + const char *label, + int shortcut, + Fl_Callback *callback, + void *userdata, + int flags +) { // make this widget own the local array: if (this != fl_menu_array_owner) { if (fl_menu_array_owner) { @@ -299,7 +379,7 @@ int Fl_Menu_::add(const char *label,int shortcut,Fl_Callback *callback,void *use } fl_menu_array_owner = this; } - int r = menu_->add(label,shortcut,callback,userdata,flags); + int r = menu_->insert(index,label,shortcut,callback,userdata,flags); // if it rellocated array we must fix the pointer: int value_offset = value_-menu_; menu_ = local_array; // in case it reallocated it @@ -374,5 +454,5 @@ void Fl_Menu_::remove(int i) { } // -// End of "$Id: Fl_Menu_add.cxx 6878 2009-09-17 22:12:24Z matt $". +// End of "$Id: Fl_Menu_add.cxx 7519 2010-04-16 19:50:40Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Native_File_Chooser.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Native_File_Chooser.cxx new file mode 100644 index 000000000..ffef8b362 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Native_File_Chooser.cxx @@ -0,0 +1,45 @@ +// "$Id: Fl_Native_File_Chooser.cxx 7003 2010-01-14 20:47:59Z greg.ercolano $" +// +// FLTK native OS file chooser widget +// +// Copyright 1998-2005 by Bill Spitzak and others. +// Copyright 2004 Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +// Use Windows' chooser +#ifdef WIN32 +#include "Fl_Native_File_Chooser_WIN32.cxx" +#endif + +// Use Apple's chooser +#ifdef __APPLE__ +#include "Fl_Native_File_Chooser_MAC.cxx" +#endif + +// All else falls back to FLTK's own chooser +#if ! defined(__APPLE__) && !defined(WIN32) +#include "Fl_Native_File_Chooser_FLTK.cxx" +#endif + +// +// End of "$Id: Fl_Native_File_Chooser.cxx 7003 2010-01-14 20:47:59Z greg.ercolano $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Native_File_Chooser_FLTK.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Native_File_Chooser_FLTK.cxx new file mode 100644 index 000000000..7f910a18a --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Native_File_Chooser_FLTK.cxx @@ -0,0 +1,504 @@ +// "$Id: Fl_Native_File_Chooser_FLTK.cxx 7015 2010-01-17 17:09:00Z greg.ercolano $" +// +// FLTK native OS file chooser widget +// +// Copyright 1998-2005 by Bill Spitzak and others. +// Copyright 2004 Greg Ercolano. +// API changes + filter improvements by Nathan Vander Wilt 2005 +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +#include +#include +#define FLTK_CHOOSER_SINGLE Fl_File_Chooser::SINGLE +#define FLTK_CHOOSER_DIRECTORY Fl_File_Chooser::DIRECTORY +#define FLTK_CHOOSER_MULTI Fl_File_Chooser::MULTI +#define FLTK_CHOOSER_CREATE Fl_File_Chooser::CREATE + +#include "Fl_Native_File_Chooser_common.cxx" +#include +#include + +/** + The constructor. Internally allocates the native widgets. + Optional \p val presets the type of browser this will be, + which can also be changed with type(). +*/ +Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) { + //// CANT USE THIS -- MESSES UP LINKING/CREATES DEPENDENCY ON fltk_images. + //// Have app call this from main() instead. + //// + //// static int init = 0; // 'first time' initialize flag + //// if ( init == 0 ) { + //// // Initialize when instanced for first time + //// Fl_File_Icon::load_system_icons(); + //// init = 1; + //// } + _btype = val; + _options = NO_OPTIONS; + _filter = NULL; + _filtvalue = 0; + _parsedfilt = NULL; + _preset_file = NULL; + _prevvalue = NULL; + _directory = NULL; + _errmsg = NULL; + _file_chooser = new Fl_File_Chooser(NULL, NULL, 0, NULL); + type(val); // do this after _file_chooser created + _nfilters = 0; + + // Added by MG + Fl_Button *b = _file_chooser->previewButton; + Fl_Window *w = b->window(); + Fl_Group::current(w); // adds a "Show hidden files" check button in _file_chooser's window + show_hidden = new Fl_Check_Button(b->x() + b->w() + 10, b->y(), 145, b->h(), "Show hidden files"); + show_hidden->callback((Fl_Callback*)show_hidden_cb, this); + my_fileList = _file_chooser->browser(); + _old_dir = 0; // to detect directory changes + prev_filtervalue = _file_chooser->filter_value(); // to detect filter changes +} + +/** + Destructor. + Deallocates any resources allocated to this widget. +*/ +Fl_Native_File_Chooser::~Fl_Native_File_Chooser() { + delete _file_chooser; + _filter = strfree(_filter); + _parsedfilt = strfree(_parsedfilt); + _preset_file = strfree(_preset_file); + _prevvalue = strfree(_prevvalue); + _directory = strfree(_directory); + _errmsg = strfree(_errmsg); + _old_dir = strfree(_old_dir); +} + +// PRIVATE: SET ERROR MESSAGE +void Fl_Native_File_Chooser::errmsg(const char *msg) { + _errmsg = strfree(_errmsg); + _errmsg = strnew(msg); +} + +// PRIVATE: translate Native types to Fl_File_Chooser types +int Fl_Native_File_Chooser::type_fl_file(int val) { + switch (val) { + case BROWSE_FILE: + return(FLTK_CHOOSER_SINGLE); + case BROWSE_DIRECTORY: + return(FLTK_CHOOSER_SINGLE | FLTK_CHOOSER_DIRECTORY); + case BROWSE_MULTI_FILE: + return(FLTK_CHOOSER_MULTI); + case BROWSE_MULTI_DIRECTORY: + return(FLTK_CHOOSER_DIRECTORY | FLTK_CHOOSER_MULTI); + case BROWSE_SAVE_FILE: + return(FLTK_CHOOSER_SINGLE | FLTK_CHOOSER_CREATE); + case BROWSE_SAVE_DIRECTORY: + return(FLTK_CHOOSER_DIRECTORY | FLTK_CHOOSER_MULTI | FLTK_CHOOSER_CREATE); + default: + return(FLTK_CHOOSER_SINGLE); + } +} + +/** + Sets the current Fl_Native_File_Chooser::Type of browser. + */ +void Fl_Native_File_Chooser::type(int val) { + _btype = val; + _file_chooser->type(type_fl_file(val)); +} + +/** + Gets the current Fl_Native_File_Chooser::Type of browser. + */ +int Fl_Native_File_Chooser::type() const { + return(_btype); +} + +/** + Sets the platform specific chooser options to \p val. + \p val is expected to be one or more Fl_Native_File_Chooser::Option flags ORed together. + Some platforms have OS-specific functions that can be enabled/disabled via this method. +

+ \code + Flag Description Win Mac Other + -------------- ----------------------------------------------- ------- ------- ------- + NEW_FOLDER Shows the 'New Folder' button. Ignored Used Used + PREVIEW Enables the 'Preview' mode by default. Ignored Ignored Used + SAVEAS_CONFIRM Confirm dialog if BROWSE_SAVE_FILE file exists. Ignored Used Used + \endcode +*/ +void Fl_Native_File_Chooser::options(int val) { + _options = val; +} + +/** + Gets the platform specific Fl_Native_File_Chooser::Option flags. +*/ +int Fl_Native_File_Chooser::options() const { + return(_options); +} + +/** + Post the chooser's dialog. Blocks until dialog has been completed or cancelled. + \returns + - 0 -- user picked a file + - 1 -- user cancelled + - -1 -- failed; errmsg() has reason +*/ +int Fl_Native_File_Chooser::show() { + // FILTER + if ( _parsedfilt ) { + _file_chooser->filter(_parsedfilt); + } + + // FILTER VALUE + // Set this /after/ setting the filter + // + _file_chooser->filter_value(_filtvalue); + + // DIRECTORY + if ( _directory && _directory[0] ) { + _file_chooser->directory(_directory); + } else { + _file_chooser->directory(_prevvalue); + } + + // PRESET FILE + if ( _preset_file ) { + _file_chooser->value(_preset_file); + } + + // OPTIONS: PREVIEW + _file_chooser->preview( (options() & PREVIEW) ? 1 : 0); + + // OPTIONS: NEW FOLDER + if ( options() & NEW_FOLDER ) + _file_chooser->type(_file_chooser->type() | FLTK_CHOOSER_CREATE); // on + + // SHOW + _file_chooser->show(); + + // BLOCK WHILE BROWSER SHOWN + while ( _file_chooser->shown() ) { + if (_old_dir==0 || strcmp(_old_dir, _file_chooser->directory()) != 0) { + _old_dir = strfree(_old_dir); + _old_dir = strnew(_file_chooser->directory()); + if (!show_hidden->value()) remove_hidden_files(my_fileList); + } else if (prev_filtervalue != _file_chooser->filter_value() ) { + prev_filtervalue = _file_chooser->filter_value(); + if (!show_hidden->value() ) remove_hidden_files(my_fileList); + } + Fl::wait(); + } + + if ( _file_chooser->value() && _file_chooser->value()[0] ) { + _prevvalue = strfree(_prevvalue); + _prevvalue = strnew(_file_chooser->value()); + _filtvalue = _file_chooser->filter_value(); // update filter value + + // HANDLE SHOWING 'SaveAs' CONFIRM + if ( options() & SAVEAS_CONFIRM && type() == BROWSE_SAVE_FILE ) { + struct stat buf; + if ( stat(_file_chooser->value(), &buf) != -1 ) { + if ( buf.st_mode & S_IFREG ) { // Regular file + exists? + if ( exist_dialog() == 0 ) { + return(1); + } + } + } + } + } + + if ( _file_chooser->count() ) return(0); + else return(1); +} + +/** + Returns a system dependent error message for the last method that failed. + This message should at least be flagged to the user in a dialog box, or to some kind of error log. + Contents will be valid only for methods that document errmsg() will have info on failures. + */ +const char *Fl_Native_File_Chooser::errmsg() const { + return(_errmsg ? _errmsg : "No error"); +} + +/** + Return the filename the user choose. + Use this if only expecting a single filename. + If more than one filename is expected, use filename(int) instead. + Return value may be "" if no filename was chosen (eg. user cancelled). + */ +const char* Fl_Native_File_Chooser::filename() const { + if ( _file_chooser->count() > 0 ) return(_file_chooser->value()); + return(""); +} + +/** + Return one of the filenames the user selected. + Use count() to determine how many filenames the user selected. +

+ \b Example: + \code + if ( fnfc->show() == 0 ) { + // Print all filenames user selected + for (int n=0; ncount(); n++ ) { + printf("%d) '%s'\n", n, fnfc->filename(n)); + } + } + \endcode + */ +const char* Fl_Native_File_Chooser::filename(int i) const { + if ( i < _file_chooser->count() ) + return(_file_chooser->value(i+1)); // convert fltk 1 based to our 0 based + return(""); +} + +/** + Set the title of the file chooser's dialog window. + Can be NULL if no title desired. + The default title varies according to the platform, so you are advised to set the title explicitly. +*/ +void Fl_Native_File_Chooser::title(const char *val) { + _file_chooser->label(val); +} + +/** + Get the title of the file chooser's dialog window. + Return value may be NULL if no title was set. +*/ +const char *Fl_Native_File_Chooser::title() const { + return(_file_chooser->label()); +} + +/** + Sets the filename filters used for browsing. + The default is NULL, which browses all files. +

+ The filter string can be any of: +

+ - A single wildcard (eg. "*.txt") + - Multiple wildcards (eg. "*.{cxx,h,H}") + - A descriptive name followed by a "\t" and a wildcard (eg. "Text Files\t*.txt") + - A list of separate wildcards with a "\n" between each (eg. "*.{cxx,H}\n*.txt") + - A list of descriptive names and wildcards (eg. "C++ Files\t*.{cxx,H}\nTxt Files\t*.txt") +

+ The format of each filter is a wildcard, or an optional user description + followed by '\\t' and the wildcard. +

+ On most platforms, each filter is available to the user via a pulldown menu + in the file chooser. The 'All Files' option is always available to the user. +*/ +void Fl_Native_File_Chooser::filter(const char *val) { + _filter = strfree(_filter); + _filter = strnew(val); + parse_filter(); +} + +/** + Returns the filter string last set. + Can be NULL if no filter was set. + */ +const char *Fl_Native_File_Chooser::filter() const { + return(_filter); +} + +/** +Gets how many filters were available, not including "All Files" +*/ +int Fl_Native_File_Chooser::filters() const { + return(_nfilters); +} + +/** + Sets which filter will be initially selected. + + The first filter is indexed as 0. + If filter_value()==filters(), then "All Files" was chosen. + If filter_value() > filters(), then a custom filter was set. + */ +void Fl_Native_File_Chooser::filter_value(int val) { + _filtvalue = val; +} + +/** + Returns which filter value was last selected by the user. + This is only valid if the chooser returns success. + */ +int Fl_Native_File_Chooser::filter_value() const { + return(_filtvalue); +} + +/** + Returns the number of filenames (or directory names) the user selected. +

+ \b Example: + \code + if ( fnfc->show() == 0 ) { + // Print all filenames user selected + for (int n=0; ncount(); n++ ) { + printf("%d) '%s'\n", n, fnfc->filename(n)); + } + } + \endcode +*/ +int Fl_Native_File_Chooser::count() const { + return(_file_chooser->count()); +} + +/** + Preset the directory the browser will show when opened. + If \p val is NULL, or no directory is specified, the chooser will attempt + to use the last non-cancelled folder. +*/ +void Fl_Native_File_Chooser::directory(const char *val) { + _directory = strfree(_directory); + _directory = strnew(val); +} + +/** + Returns the current preset directory() value. +*/ +const char *Fl_Native_File_Chooser::directory() const { + return(_directory); +} + +// PRIVATE: Convert our filter format to fltk's chooser format +// FROM TO (FLTK) +// ------------------------- -------------------------- +// "*.cxx" "*.cxx Files(*.cxx)" +// "C Files\t*.{cxx,h}" "C Files(*.{cxx,h})" +// "C Files\t*.{cxx,h}\nText Files\t*.txt" "C Files(*.{cxx,h})\tText Files(*.txt)" +// +// Returns a modified version of the filter that the caller is responsible +// for freeing with strfree(). +// +void Fl_Native_File_Chooser::parse_filter() { + _parsedfilt = strfree(_parsedfilt); // clear previous parsed filter (if any) + _nfilters = 0; + char *in = _filter; + if ( !in ) return; + + int has_name = strchr(in, '\t') ? 1 : 0; + + char mode = has_name ? 'n' : 'w'; // parse mode: n=title, w=wildcard + char wildcard[1024] = ""; // parsed wildcard + char name[1024] = ""; + + // Parse filter user specified + for ( ; 1; in++ ) { + /*** DEBUG + printf("WORKING ON '%c': mode=<%c> name=<%s> wildcard=<%s>\n", + *in, mode, name, wildcard); + ***/ + + switch (*in) { + // FINISHED PARSING NAME? + case '\t': + if ( mode != 'n' ) goto regchar; + mode = 'w'; + break; + // ESCAPE NEXT CHAR + case '\\': + ++in; + goto regchar; + // FINISHED PARSING ONE OF POSSIBLY SEVERAL FILTERS? + case '\r': + case '\n': + case '\0': + // APPEND NEW FILTER TO LIST + if ( wildcard[0] ) { + // OUT: "name(wild)\tname(wild)" + char comp[2048]; + sprintf(comp, "%s%.511s(%.511s)", ((_parsedfilt)?"\t":""), + name, wildcard); + _parsedfilt = strapp(_parsedfilt, comp); + _nfilters++; + //DEBUG printf("DEBUG: PARSED FILT NOW <%s>\n", _parsedfilt); + } + // RESET + wildcard[0] = name[0] = '\0'; + mode = strchr(in, '\t') ? 'n' : 'w'; + // DONE? + if ( *in == '\0' ) return; // done + else continue; // not done yet, more filters + + // Parse all other chars + default: // handle all non-special chars + regchar: // handle regular char + switch ( mode ) { + case 'n': chrcat(name, *in); continue; + case 'w': chrcat(wildcard, *in); continue; + } + break; + } + } + //NOTREACHED +} + +/** + Sets the default filename for the chooser. + Use directory() to set the default directory. + Mainly used to preset the filename for save dialogs, + and on most platforms can be used for opening files as well. + */ +void Fl_Native_File_Chooser::preset_file(const char* val) { + _preset_file = strfree(_preset_file); + _preset_file = strnew(val); +} + +/** + Get the preset filename. + */ +const char* Fl_Native_File_Chooser::preset_file() const { + return(_preset_file); +} + +void Fl_Native_File_Chooser::show_hidden_cb(Fl_Check_Button *o, void *data) +{ + Fl_Native_File_Chooser *mychooser = (Fl_Native_File_Chooser *)data; + if (o->value()) { + mychooser->my_fileList->load(mychooser->_file_chooser->directory()); + } else { + remove_hidden_files(mychooser->my_fileList); + mychooser->my_fileList->redraw(); + } +} + +// PRIVATE: Don't show hidden files +void Fl_Native_File_Chooser::remove_hidden_files(Fl_File_Browser *my_fileList) +{ + int count = my_fileList->size(); + for(int num = count; num >= 1; num--) { + const char *p = my_fileList->text(num); + if (*p == '.' && strcmp(p, "../") != 0) my_fileList->remove(num); + } + my_fileList->topline(1); +} + +// PRIVATE: Don't show hidden files +int Fl_Native_File_Chooser::exist_dialog() { + return(fl_choice("File exists. Are you sure you want to overwrite?", + "Cancel", " OK ", NULL)); +} + +// +// End of "$Id: Fl_Native_File_Chooser_FLTK.cxx 7015 2010-01-17 17:09:00Z greg.ercolano $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Native_File_Chooser_MAC.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Native_File_Chooser_MAC.cxx new file mode 100644 index 000000000..485376e69 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Native_File_Chooser_MAC.cxx @@ -0,0 +1,583 @@ +// "$Id: Fl_Native_File_Chooser_MAC.cxx 7354 2010-03-29 11:07:29Z matt $" +// +// FLTK native OS file chooser widget +// +// Copyright 1998-2005 by Bill Spitzak and others. +// Copyright 2004 Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +// TODO: +// o When doing 'open file', only dir is preset, not filename. +// Possibly 'preset_file' could be used to select the filename. +// + +#ifndef FL_DOXYGEN // PREVENT DOXYGEN'S USE OF THIS FILE + +#include "Fl_Native_File_Chooser_common.cxx" // strnew/strfree/strapp/chrcat +#include // dirname(3) +#include // stat(2) +#include // stat(2) + + +#include +#include +#include + +// FREE PATHNAMES ARRAY, IF IT HAS ANY CONTENTS +void Fl_Native_File_Chooser::clear_pathnames() { + if ( _pathnames ) { + while ( --_tpathnames >= 0 ) { + _pathnames[_tpathnames] = strfree(_pathnames[_tpathnames]); + } + delete [] _pathnames; + _pathnames = NULL; + } + _tpathnames = 0; +} + +// SET A SINGLE PATHNAME +void Fl_Native_File_Chooser::set_single_pathname(const char *s) { + clear_pathnames(); + _pathnames = new char*[1]; + _pathnames[0] = strnew(s); + _tpathnames = 1; +} + +// CONSTRUCTOR +Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) { + _btype = val; + _panel = NULL; + _options = NO_OPTIONS; + _pathnames = NULL; + _tpathnames = 0; + _title = NULL; + _filter = NULL; + _filt_names = NULL; + memset(_filt_patt, 0, sizeof(char*) * MAXFILTERS); + _filt_total = 0; + _filt_value = 0; + _directory = NULL; + _preset_file = NULL; + _errmsg = NULL; +} + +// DESTRUCTOR +Fl_Native_File_Chooser::~Fl_Native_File_Chooser() { + // _opts // nothing to manage + // _options // nothing to manage + // _keepstate // nothing to manage + // _tempitem // nothing to manage + clear_pathnames(); + _directory = strfree(_directory); + _title = strfree(_title); + _preset_file = strfree(_preset_file); + _filter = strfree(_filter); + //_filt_names // managed by clear_filters() + //_filt_patt[i] // managed by clear_filters() + //_filt_total // managed by clear_filters() + clear_filters(); + //_filt_value // nothing to manage + _errmsg = strfree(_errmsg); +} + +// GET TYPE OF BROWSER +int Fl_Native_File_Chooser::type() const { + return(_btype); +} + +// SET OPTIONS +void Fl_Native_File_Chooser::options(int val) { + _options = val; +} + +// GET OPTIONS +int Fl_Native_File_Chooser::options() const { + return(_options); +} + +// SHOW THE BROWSER WINDOW +// Returns: +// 0 - user picked a file +// 1 - user cancelled +// -1 - failed; errmsg() has reason +// +int Fl_Native_File_Chooser::show() { + + // Make sure fltk interface updates before posting our dialog + Fl::flush(); + + // POST BROWSER + int err = post(); + + _filt_total = 0; + + return(err); +} + +// SET ERROR MESSAGE +// Internal use only. +// +void Fl_Native_File_Chooser::errmsg(const char *msg) { + _errmsg = strfree(_errmsg); + _errmsg = strnew(msg); +} + +// RETURN ERROR MESSAGE +const char *Fl_Native_File_Chooser::errmsg() const { + return(_errmsg ? _errmsg : "No error"); +} + +// GET FILENAME +const char* Fl_Native_File_Chooser::filename() const { + if ( _pathnames && _tpathnames > 0 ) return(_pathnames[0]); + return(""); +} + +// GET FILENAME FROM LIST OF FILENAMES +const char* Fl_Native_File_Chooser::filename(int i) const { + if ( _pathnames && i < _tpathnames ) return(_pathnames[i]); + return(""); +} + +// GET TOTAL FILENAMES CHOSEN +int Fl_Native_File_Chooser::count() const { + return(_tpathnames); +} + +// PRESET PATHNAME +// Value can be NULL for none. +// +void Fl_Native_File_Chooser::directory(const char *val) { + _directory = strfree(_directory); + _directory = strnew(val); +} + +// GET PRESET PATHNAME +// Returned value can be NULL if none set. +// +const char* Fl_Native_File_Chooser::directory() const { + return(_directory); +} + +// SET TITLE +// Value can be NULL if no title desired. +// +void Fl_Native_File_Chooser::title(const char *val) { + _title = strfree(_title); + _title = strnew(val); +} + +// GET TITLE +// Returned value can be NULL if none set. +// +const char *Fl_Native_File_Chooser::title() const { + return(_title); +} + +// SET FILTER +// Can be NULL if no filter needed +// +void Fl_Native_File_Chooser::filter(const char *val) { + _filter = strfree(_filter); + _filter = strnew(val); + + // Parse filter user specified + // IN: _filter = "C Files\t*.{cxx,h}\nText Files\t*.txt" + // OUT: _filt_names = "C Files\tText Files" + // _filt_patt[0] = "*.{cxx,h}" + // _filt_patt[1] = "*.txt" + // _filt_total = 2 + // + parse_filter(_filter); +} + +// GET FILTER +// Returned value can be NULL if none set. +// +const char *Fl_Native_File_Chooser::filter() const { + return(_filter); +} + +// CLEAR ALL FILTERS +// Internal use only. +// +void Fl_Native_File_Chooser::clear_filters() { + _filt_names = strfree(_filt_names); + for (int i=0; i<_filt_total; i++) { + _filt_patt[i] = strfree(_filt_patt[i]); + } + _filt_total = 0; +} + +// PARSE USER'S FILTER SPEC +// Parses user specified filter ('in'), +// breaks out into _filt_patt[], _filt_names, and _filt_total. +// +// Handles: +// IN: OUT:_filt_names OUT: _filt_patt +// ------------------------------------ ------------------ --------------- +// "*.{ma,mb}" "*.{ma,mb} Files" "*.{ma,mb}" +// "*.[abc]" "*.[abc] Files" "*.[abc]" +// "*.txt" "*.txt Files" "*.c" +// "C Files\t*.[ch]" "C Files" "*.[ch]" +// "C Files\t*.[ch]\nText Files\t*.cxx" "C Files" "*.[ch]" +// +// Parsing Mode: +// IN:"C Files\t*.{cxx,h}" +// ||||||| ||||||||| +// mode: nnnnnnn wwwwwwwww +// \_____/ \_______/ +// Name Wildcard +// +void Fl_Native_File_Chooser::parse_filter(const char *in) { + clear_filters(); + if ( ! in ) return; + int has_name = strchr(in, '\t') ? 1 : 0; + + char mode = has_name ? 'n' : 'w'; // parse mode: n=title, w=wildcard + char wildcard[1024] = ""; // parsed wildcard + char name[1024] = ""; + + // Parse filter user specified + for ( ; 1; in++ ) { + + //// DEBUG + //// printf("WORKING ON '%c': mode=<%c> name=<%s> wildcard=<%s>\n", + //// *in, mode, name, wildcard); + + switch (*in) { + // FINISHED PARSING NAME? + case '\t': + if ( mode != 'n' ) goto regchar; + mode = 'w'; + break; + + // ESCAPE NEXT CHAR + case '\\': + ++in; + goto regchar; + + // FINISHED PARSING ONE OF POSSIBLY SEVERAL FILTERS? + case '\r': + case '\n': + case '\0': + // TITLE + // If user didn't specify a name, make one + // + if ( name[0] == '\0' ) { + sprintf(name, "%.*s Files", (int)sizeof(name)-10, wildcard); + } + // APPEND NEW FILTER TO LIST + if ( wildcard[0] ) { + // Add to filtername list + // Tab delimit if more than one. We later break + // tab delimited string into CFArray with + // CFStringCreateArrayBySeparatingStrings() + // + if ( _filt_total ) { + _filt_names = strapp(_filt_names, "\t"); + } + _filt_names = strapp(_filt_names, name); + + // Add filter to the pattern array + _filt_patt[_filt_total++] = strnew(wildcard); + } + // RESET + wildcard[0] = name[0] = '\0'; + mode = strchr(in, '\t') ? 'n' : 'w'; + // DONE? + if ( *in == '\0' ) return; // done + else continue; // not done yet, more filters + + // Parse all other chars + default: // handle all non-special chars + regchar: // handle regular char + switch ( mode ) { + case 'n': chrcat(name, *in); continue; + case 'w': chrcat(wildcard, *in); continue; + } + break; + } + } + //NOTREACHED +} + +// SET PRESET FILE +// Value can be NULL for none. +// +void Fl_Native_File_Chooser::preset_file(const char* val) { + _preset_file = strfree(_preset_file); + _preset_file = strnew(val); +} + +// PRESET FILE +// Returned value can be NULL if none set. +// +const char* Fl_Native_File_Chooser::preset_file() { + return(_preset_file); +} + +#import +#define UNLIKELYPREFIX "___fl_very_unlikely_prefix_" +#ifndef MAC_OS_X_VERSION_10_6 +#define MAC_OS_X_VERSION_10_6 1060 +#endif + +int Fl_Native_File_Chooser::get_saveas_basename(void) { + char *q = strdup( [[(NSSavePanel*)_panel filename] fileSystemRepresentation] ); + id delegate = [(NSSavePanel*)_panel delegate]; + if (delegate != nil) { + const char *d = [[(NSSavePanel*)_panel directory] fileSystemRepresentation]; + int l = strlen(d) + 1; + int lu = strlen(UNLIKELYPREFIX); + // Remove UNLIKELYPREFIX between directory and filename parts + memmove(q + l, q + l + lu, strlen(q + l + lu) + 1); + } + set_single_pathname( q ); + free(q); + return 0; +} + +// SET THE TYPE OF BROWSER +void Fl_Native_File_Chooser::type(int val) { + _btype = val; + switch (_btype) { + case BROWSE_FILE: + case BROWSE_MULTI_FILE: + case BROWSE_DIRECTORY: + case BROWSE_MULTI_DIRECTORY: + _panel = [NSOpenPanel openPanel]; + break; + case BROWSE_SAVE_DIRECTORY: + case BROWSE_SAVE_FILE: + _panel = [NSSavePanel savePanel]; + break; + } +} + +@interface FLopenDelegate : NSObject +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + +#endif +{ + NSPopUpButton *nspopup; + char **filter_pattern; +} +- (FLopenDelegate*)setPopup:(NSPopUpButton*)popup filter_pattern:(char**)pattern; +- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename; +@end +@implementation FLopenDelegate +- (FLopenDelegate*)setPopup:(NSPopUpButton*)popup filter_pattern:(char**)pattern +{ + nspopup = popup; + filter_pattern = pattern; + return self; +} +- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename +{ + if ( [nspopup indexOfSelectedItem] == [nspopup numberOfItems] - 1) return YES; + const char *pathname = [filename fileSystemRepresentation]; + if ( fl_filename_isdir(pathname) ) return YES; + if ( fl_filename_match(pathname, filter_pattern[ [nspopup indexOfSelectedItem] ]) ) return YES; + return NO; +} +@end + +@interface FLsaveDelegate : NSObject +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + +#endif +{ +} +- (NSString *)panel:(id)sender userEnteredFilename:(NSString *)filename confirmed:(BOOL)okFlag; +@end +@implementation FLsaveDelegate +- (NSString *)panel:(id)sender userEnteredFilename:(NSString *)filename confirmed:(BOOL)okFlag +{ + if (! okFlag) return filename; + // User has clicked save, and no overwrite confirmation should occur. + // To get the latter, we need to change the name we return (hence the prefix): + return [@ UNLIKELYPREFIX stringByAppendingString:filename]; +} +@end + +static NSPopUpButton *createPopupAccessory(NSSavePanel *panel, const char *filter, const char *title, int rank) +{ + NSPopUpButton *popup; + NSRect rectview = NSMakeRect(5, 5, 350, 30 ); + NSView *view = [[[NSView alloc] initWithFrame:rectview] autorelease]; + NSRect rectbox = NSMakeRect(0, 3, 50, 1 ); + NSBox *box = [[[NSBox alloc] initWithFrame:rectbox] autorelease]; + NSRect rectpop = NSMakeRect(60, 0, 250, 30 ); + popup = [[[NSPopUpButton alloc ] initWithFrame:rectpop pullsDown:NO] autorelease]; + [view addSubview:box]; + [view addSubview:popup]; + [box setBorderType:NSNoBorder]; + NSString *nstitle = [[NSString alloc] initWithUTF8String:title]; + [box setTitle:nstitle]; + [nstitle release]; + NSFont *font = [NSFont controlContentFontOfSize:NSRegularControlSize]; + [box setTitleFont:font]; + [box sizeToFit]; + CFStringRef tab = CFSTR("\n"); + CFStringRef tmp_cfs; + tmp_cfs = CFStringCreateWithCString(NULL, filter, kCFStringEncodingASCII); + CFArrayRef array = CFStringCreateArrayBySeparatingStrings(NULL, tmp_cfs, tab); + CFRelease(tmp_cfs); + CFRelease(tab); + [popup addItemsWithTitles:(NSArray*)array]; + NSMenuItem *item = [popup itemWithTitle:@""]; + if (item) [popup removeItemWithTitle:@""]; + CFRelease(array); + [popup selectItemAtIndex:rank]; + [panel setAccessoryView:view]; + return popup; +} + +// POST BROWSER +// Internal use only. +// Assumes '_opts' has been initialized. +// +// Returns: +// 0 - user picked a file +// 1 - user cancelled +// -1 - failed; errmsg() has reason +// +int Fl_Native_File_Chooser::post() { + // INITIALIZE BROWSER + if ( _filt_total == 0 ) { // Make sure they match + _filt_value = 0; // TBD: move to someplace more logical? + } + NSAutoreleasePool *localPool; + localPool = [[NSAutoreleasePool alloc] init]; + int retval; + NSString *nstitle = [NSString stringWithUTF8String: (_title ? _title : "No Title")]; + [(NSSavePanel*)_panel setTitle:nstitle]; + switch (_btype) { + case BROWSE_MULTI_FILE: + [(NSOpenPanel*)_panel setAllowsMultipleSelection:YES]; + break; + case BROWSE_MULTI_DIRECTORY: + [(NSOpenPanel*)_panel setAllowsMultipleSelection:YES]; + case BROWSE_DIRECTORY: + [(NSOpenPanel*)_panel setCanChooseDirectories:YES]; + break; + case BROWSE_SAVE_DIRECTORY: + [(NSSavePanel*)_panel setCanCreateDirectories:YES]; + break; + } + + // SHOW THE DIALOG + if ( [(NSSavePanel*)_panel isKindOfClass:[NSOpenPanel class]] ) { + NSPopUpButton *popup = nil; + if (_filt_total) { + char *p; p = _filter; + char *q; q = new char[strlen(p) + 1]; + char *r, *s, *t; + t = q; + do { // copy to t what is in _filter removing what is between \t and \n, if any + r = strchr(p, '\n'); + if (!r) r = p + strlen(p) - 1; + s = strchr(p, '\t'); + if (s && s < r) { memcpy(q, p, s - p); q += s - p; *(q++) = '\n'; } + else { memcpy(q, p, r - p + 1); q += r - p + 1; } + *q = 0; + p = r + 1; + } while(*p); + popup = createPopupAccessory((NSSavePanel*)_panel, t, "Enable:", 0); + delete t; + [[popup menu] addItem:[NSMenuItem separatorItem]]; + [popup addItemWithTitle:@"All Documents"]; + [popup setAction:@selector(validateVisibleColumns)]; + [popup setTarget:(NSObject*)_panel]; + static FLopenDelegate *openDelegate = nil; + if (openDelegate == nil) { + // not to be ever freed + openDelegate = [[FLopenDelegate alloc] init]; + } + [openDelegate setPopup:popup filter_pattern:_filt_patt]; + [(NSOpenPanel*)_panel setDelegate:openDelegate]; + } + NSString *dir = nil; + NSString *fname = nil; + NSString *preset = nil; + if (_preset_file) { + preset = [[NSString alloc] initWithUTF8String:_preset_file]; + if (strchr(_preset_file, '/') != NULL) + dir = [[NSString alloc] initWithString:[preset stringByDeletingLastPathComponent]]; + fname = [preset lastPathComponent]; + } + if (_directory && !dir) dir = [[NSString alloc] initWithUTF8String:_directory]; + retval = [(NSOpenPanel*)_panel runModalForDirectory:dir file:fname types:nil]; + [dir release]; + [preset release]; + if (_filt_total) { + _filt_value = [popup indexOfSelectedItem]; + } + if ( retval == NSOKButton ) { + clear_pathnames(); + NSArray *array = [(NSOpenPanel*)_panel filenames]; + _tpathnames = [array count]; + _pathnames = new char*[_tpathnames]; + for(int i = 0; i < _tpathnames; i++) { + _pathnames[i] = strnew([(NSString*)[array objectAtIndex:i] fileSystemRepresentation]); + } + } + } + else { + NSString *dir = nil; + NSString *fname = nil; + NSString *preset = nil; + NSPopUpButton *popup = nil; + if ( !(_options & SAVEAS_CONFIRM) ) { + static FLsaveDelegate *saveDelegate = nil; + if (saveDelegate == nil)saveDelegate = [[FLsaveDelegate alloc] init]; // not to be ever freed + [(NSSavePanel*)_panel setDelegate:saveDelegate]; + } + if (_preset_file) { + preset = [[NSString alloc] initWithUTF8String:_preset_file]; + if (strchr(_preset_file, '/') != NULL) { + dir = [[NSString alloc] initWithString:[preset stringByDeletingLastPathComponent]]; + } + fname = [preset lastPathComponent]; + } + if (_directory && !dir) dir = [[NSString alloc] initWithUTF8String:_directory]; + if (_filt_total) { + popup = createPopupAccessory((NSSavePanel*)_panel, _filter, "Format:", _filt_value); + } + retval = [(NSSavePanel*)_panel runModalForDirectory:dir file:fname]; + if (_filt_total) { + _filt_value = [popup indexOfSelectedItem]; + } + [dir release]; + [preset release]; + if ( retval == NSOKButton ) get_saveas_basename(); + } + [localPool release]; + return (retval == NSOKButton ? 0 : 1); +} + +#endif /*!FL_DOXYGEN*/ + +// +// End of "$Id: Fl_Native_File_Chooser_MAC.cxx 7354 2010-03-29 11:07:29Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Native_File_Chooser_WIN32.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Native_File_Chooser_WIN32.cxx new file mode 100644 index 000000000..542f0c07b --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Native_File_Chooser_WIN32.cxx @@ -0,0 +1,851 @@ +// "$Id: Fl_Native_File_Chooser_WIN32.cxx 7312 2010-03-21 22:55:18Z fabien $" +// +// FLTK native OS file chooser widget +// +// Copyright 1998-2005 by Bill Spitzak and others. +// Copyright 2004 Greg Ercolano. +// API changes + filter improvements by Nathan Vander Wilt 2005 +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +// Any application to multi-folder implementation: +// http://www.codeproject.com/dialog/selectfolder.asp +// + +#ifndef FL_DOXYGEN // PREVENT DOXYGEN'S USE OF THIS FILE + +#include // debugging +#include //MG +#include "Fl_Native_File_Chooser_common.cxx" // strnew/strfree/strapp/chrcat +typedef const wchar_t *LPCWSTR; //MG +LPCWSTR utf8towchar(const char *in); //MG +char *wchartoutf8(LPCWSTR in); //MG + +#include + +#define LCURLY_CHR '{' +#define RCURLY_CHR '}' +#define LBRACKET_CHR '[' +#define RBRACKET_CHR ']' +#define MAXFILTERS 80 + +// STATIC: PRINT WINDOWS 'DOUBLE NULL' STRING (DEBUG) +static void dnullprint(char *wp) { + if ( ! wp ) return; + for ( int t=0; true; t++ ) { + if ( wp[t] == '\0' && wp[t+1] == '\0' ) { + printf("\\0\\0"); + fflush(stdout); + return; + } else if ( wp[t] == '\0' ) { + printf("\\0"); + } else { + printf("%c",wp[t]); + } + } +} + +// RETURN LENGTH OF DOUBLENULL STRING +// Includes single nulls in count, excludes trailing doublenull. +// +// 1234 567 +// |||/\||| +// IN: "one\0two\0\0" +// OUT: 7 +// +static int dnulllen(const char *wp) { + int len = 0; + while ( ! ( *(wp+0) == 0 && *(wp+1) == 0 ) ) { + ++wp; + ++len; + } + return(len); +} + +// STATIC: Append a string to another, leaving terminated with DOUBLE NULL. +// Automatically handles extending length of string. +// wp can be NULL (a new wp will be allocated and initialized). +// string must be NULL terminated. +// The pointer wp may be modified on return. +// +static void dnullcat(char*&wp, const char *string, int n = -1 ) { + //DEBUG printf("DEBUG: dnullcat IN: <"); dnullprint(wp); printf(">\n"); + int inlen = ( n < 0 ) ? strlen(string) : n; + if ( ! wp ) { + wp = new char[inlen + 4]; + *(wp+0) = '\0'; + *(wp+1) = '\0'; + } else { + int wplen = dnulllen(wp); + // Make copy of wp into larger buffer + char *tmp = new char[wplen + inlen + 4]; + memcpy(tmp, wp, wplen+2); // copy of wp plus doublenull + delete [] wp; // delete old wp + wp = tmp; // use new copy + //DEBUG printf("DEBUG: dnullcat COPY: <"); dnullprint(wp); printf("> (wplen=%d)\n", wplen); + } + + // Find end of double null string + // *wp2 is left pointing at second null. + // + char *wp2 = wp; + if ( *(wp2+0) != '\0' && *(wp2+1) != '\0' ) { + for ( ; 1; wp2++ ) { + if ( *(wp2+0) == '\0' && *(wp2+1) == '\0' ) { + wp2++; + break; + } + } + } + + if ( n == -1 ) n = strlen(string); + strncpy(wp2, string, n); + + // Leave string double-null terminated + *(wp2+n+0) = '\0'; + *(wp2+n+1) = '\0'; + //DEBUG printf("DEBUG: dnullcat OUT: <"); dnullprint(wp); printf(">\n\n"); +} + +// CTOR +Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) { + _btype = val; + _options = NO_OPTIONS; + memset((void*)&_ofn, 0, sizeof(OPENFILENAMEW)); + _ofn.lStructSize = sizeof(OPENFILENAMEW); + _ofn.hwndOwner = NULL; + memset((void*)&_binf, 0, sizeof(BROWSEINFO)); + _pathnames = NULL; + _tpathnames = 0; + _directory = NULL; + _title = NULL; + _filter = NULL; + _parsedfilt = NULL; + _nfilters = 0; + _preset_file = NULL; + _errmsg = NULL; +} + +// DTOR +Fl_Native_File_Chooser::~Fl_Native_File_Chooser() { + //_pathnames // managed by clear_pathnames() + //_tpathnames // managed by clear_pathnames() + _directory = strfree(_directory); + _title = strfree(_title); + _filter = strfree(_filter); + //_parsedfilt // managed by clear_filters() + //_nfilters // managed by clear_filters() + _preset_file = strfree(_preset_file); + _errmsg = strfree(_errmsg); + clear_filters(); + clear_pathnames(); + ClearOFN(); + ClearBINF(); +} + +// SET TYPE OF BROWSER +void Fl_Native_File_Chooser::type(int val) { + _btype = val; +} + +// GET TYPE OF BROWSER +int Fl_Native_File_Chooser::type() const { + return( _btype ); +} + +// SET OPTIONS +void Fl_Native_File_Chooser::options(int val) { + _options = val; +} + +// GET OPTIONS +int Fl_Native_File_Chooser::options() const { + return(_options); +} + +// PRIVATE: SET ERROR MESSAGE +void Fl_Native_File_Chooser::errmsg(const char *val) { + _errmsg = strfree(_errmsg); + _errmsg = strnew(val); +} + +// FREE PATHNAMES ARRAY, IF IT HAS ANY CONTENTS +void Fl_Native_File_Chooser::clear_pathnames() { + if ( _pathnames ) { + while ( --_tpathnames >= 0 ) { + _pathnames[_tpathnames] = strfree(_pathnames[_tpathnames]); + } + delete [] _pathnames; + _pathnames = NULL; + } + _tpathnames = 0; +} + +// SET A SINGLE PATHNAME +void Fl_Native_File_Chooser::set_single_pathname(const char *s) { + clear_pathnames(); + _pathnames = new char*[1]; + _pathnames[0] = strnew(s); + _tpathnames = 1; +} + +// ADD PATHNAME TO EXISTING ARRAY +void Fl_Native_File_Chooser::add_pathname(const char *s) { + if ( ! _pathnames ) { + // Create first element in array + ++_tpathnames; + _pathnames = new char*[_tpathnames]; + } else { + // Grow array by 1 + char **tmp = new char*[_tpathnames+1]; // create new buffer + memcpy((void*)tmp, (void*)_pathnames, + sizeof(char*)*_tpathnames); // copy old + delete [] _pathnames; // delete old + _pathnames = tmp; // use new + ++_tpathnames; + } + _pathnames[_tpathnames-1] = strnew(s); +} + +// FREE A PIDL (Pointer to IDentity List) +void Fl_Native_File_Chooser::FreePIDL(ITEMIDLIST *pidl) { + IMalloc *imalloc = NULL; + if ( SUCCEEDED(SHGetMalloc(&imalloc)) ) { + imalloc->Free(pidl); + imalloc->Release(); + imalloc = NULL; + } +} + +// CLEAR MICROSOFT OFN (OPEN FILE NAME) CLASS +void Fl_Native_File_Chooser::ClearOFN() { + // Free any previously allocated lpstrFile before zeroing out _ofn + if ( _ofn.lpstrFile ) { + delete [] _ofn.lpstrFile; + _ofn.lpstrFile = NULL; + } + if ( _ofn.lpstrInitialDir ) { + delete [] (TCHAR*) _ofn.lpstrInitialDir; //msvc6 compilation fix + _ofn.lpstrInitialDir = NULL; + } + _ofn.lpstrFilter = NULL; // (deleted elsewhere) + int temp = _ofn.nFilterIndex; // keep the filter_value + memset((void*)&_ofn, 0, sizeof(_ofn)); + _ofn.lStructSize = sizeof(OPENFILENAMEW); + _ofn.nFilterIndex = temp; +} + +// CLEAR MICROSOFT BINF (BROWSER INFO) CLASS +void Fl_Native_File_Chooser::ClearBINF() { + if ( _binf.pidlRoot ) { + FreePIDL((ITEMIDLIST*)_binf.pidlRoot); + _binf.pidlRoot = NULL; + } + memset((void*)&_binf, 0, sizeof(_binf)); +} + +// CONVERT WINDOWS BACKSLASHES TO UNIX FRONTSLASHES +void Fl_Native_File_Chooser::Win2Unix(char *s) { + for ( ; *s; s++ ) + if ( *s == '\\' ) *s = '/'; +} + +// CONVERT UNIX FRONTSLASHES TO WINDOWS BACKSLASHES +void Fl_Native_File_Chooser::Unix2Win(char *s) { + for ( ; *s; s++ ) + if ( *s == '/' ) *s = '\\'; +} + +// SHOW FILE BROWSER +int Fl_Native_File_Chooser::showfile() { + ClearOFN(); + clear_pathnames(); + size_t fsize = MAX_PATH; + _ofn.Flags |= OFN_NOVALIDATE; // prevent disabling of front slashes + _ofn.Flags |= OFN_HIDEREADONLY; // hide goofy readonly flag + // USE NEW BROWSER + _ofn.Flags |= OFN_EXPLORER; // use newer explorer windows + _ofn.Flags |= OFN_ENABLESIZING; // allow window to be resized (hey, why not?) + + // XXX: The docs for OFN_NOCHANGEDIR says the flag is 'ineffective' on XP/2K/NT! + // But let's set it anyway.. + // + _ofn.Flags |= OFN_NOCHANGEDIR; // prevent dialog for messing up the cwd + + switch ( _btype ) { + case BROWSE_DIRECTORY: + case BROWSE_MULTI_DIRECTORY: + case BROWSE_SAVE_DIRECTORY: + abort(); // never happens: handled by showdir() + case BROWSE_FILE: + fsize = 65536; // XXX: there must be a better way + break; + case BROWSE_MULTI_FILE: + _ofn.Flags |= OFN_ALLOWMULTISELECT; + fsize = 65536; // XXX: there must be a better way + break; + case BROWSE_SAVE_FILE: + if ( options() & SAVEAS_CONFIRM && type() == BROWSE_SAVE_FILE ) { + _ofn.Flags |= OFN_OVERWRITEPROMPT; + } + break; + } + // SPACE FOR RETURNED FILENAME + _ofn.lpstrFile = new WCHAR[fsize]; + _ofn.nMaxFile = fsize-1; + _ofn.lpstrFile[0] = 0; + _ofn.lpstrFile[1] = 0; // dnull + // PARENT WINDOW + _ofn.hwndOwner = GetForegroundWindow(); + // DIALOG TITLE + if (_title) { + static WCHAR wtitle[200]; + wcscpy(wtitle, utf8towchar(_title)); + _ofn.lpstrTitle = wtitle; + } else { + _ofn.lpstrTitle = NULL; + } + // FILTER + if (_parsedfilt != NULL) { // to convert a null-containing char string into a widechar string + static WCHAR wpattern[MAX_PATH]; + const char *p = _parsedfilt; + while(*(p + strlen(p) + 1) != 0) p += strlen(p) + 1; + p += strlen(p) + 2; + MultiByteToWideChar(CP_UTF8, 0, _parsedfilt, p - _parsedfilt, wpattern, MAX_PATH); + _ofn.lpstrFilter = wpattern; + } else { + _ofn.lpstrFilter = NULL; + } + // PRESET FILE + // If set, supercedes _directory. See KB Q86920 for details + // + if ( _preset_file ) { + size_t len = strlen(_preset_file); + if ( len >= _ofn.nMaxFile ) { + char msg[80]; + sprintf(msg, "preset_file() filename is too long: %ld is >=%ld", (long)len, (long)fsize); + return(-1); + } + wcscpy(_ofn.lpstrFile, utf8towchar(_preset_file)); +// Unix2Win(_ofn.lpstrFile); + len = wcslen(_ofn.lpstrFile); + _ofn.lpstrFile[len+0] = 0; // multiselect needs dnull + _ofn.lpstrFile[len+1] = 0; + } + if ( _directory ) { + // PRESET DIR + // XXX: See KB Q86920 for doc bug: + // http://support.microsoft.com/default.aspx?scid=kb;en-us;86920 + // + _ofn.lpstrInitialDir = new WCHAR[MAX_PATH]; + wcscpy((WCHAR *)_ofn.lpstrInitialDir, utf8towchar(_directory)); + // Unix2Win((char*)_ofn.lpstrInitialDir); + } + // SAVE THE CURRENT DIRECTORY + // XXX: Save the cwd because GetOpenFileName() is probably going to + // change it, in spite of the OFN_NOCHANGEDIR flag, due to its docs + // saying the flag is 'ineffective'. %^( + // + char oldcwd[MAX_PATH]; + GetCurrentDirectory(MAX_PATH, oldcwd); + oldcwd[MAX_PATH-1] = '\0'; + // OPEN THE DIALOG WINDOW + int err; + if ( _btype == BROWSE_SAVE_FILE ) { + err = GetSaveFileNameW(&_ofn); + } else { + err = GetOpenFileNameW(&_ofn); + } + if ( err == 0 ) { + // EXTENDED ERROR CHECK + int err = CommDlgExtendedError(); + // CANCEL? + if ( err == 0 ) return(1); // user hit 'cancel' + // AN ERROR OCCURRED + char msg[80]; + sprintf(msg, "CommDlgExtendedError() code=%d", err); + errmsg(msg); + // XXX: RESTORE CWD + if ( oldcwd[0] ) SetCurrentDirectory(oldcwd); + return(-1); + } + // XXX: RESTORE CWD + if ( oldcwd[0] ) { + SetCurrentDirectory(oldcwd); + } + // PREPARE PATHNAMES FOR RETURN + switch ( _btype ) { + case BROWSE_FILE: + case BROWSE_SAVE_FILE: + set_single_pathname(wchartoutf8(_ofn.lpstrFile)); + // Win2Unix(_pathnames[_tpathnames-1]); + break; + case BROWSE_MULTI_FILE: { + // EXTRACT MULTIPLE FILENAMES + const WCHAR *dirname = _ofn.lpstrFile; + int dirlen = wcslen(dirname); + if ( dirlen > 0 ) { + // WALK STRING SEARCHING FOR 'DOUBLE-NULL' + // eg. "/dir/name\0foo1\0foo2\0foo3\0\0" + // + char pathname[MAX_PATH]; + for ( const WCHAR *s = dirname + dirlen + 1; + *s; s+= (wcslen(s)+1)) { + strcpy(pathname, wchartoutf8(dirname)); + strcat(pathname, "\\"); + strcat(pathname, wchartoutf8(s)); + add_pathname(pathname); + } + } + // XXX + // Work around problem where pasted forward-slash pathname + // into the file browser causes new "Explorer" interface + // not to grok forward slashes, passing back as a 'filename'..! + // + if ( _tpathnames == 0 ) { + add_pathname(wchartoutf8(dirname)); + // Win2Unix(_pathnames[_tpathnames-1]); + } + break; + } + case BROWSE_DIRECTORY: + case BROWSE_MULTI_DIRECTORY: + case BROWSE_SAVE_DIRECTORY: + abort(); // never happens: handled by showdir() + } + return(0); +} + +// Used by SHBrowseForFolder(), sets initial selected dir. +// Ref: Usenet: microsoft.public.vc.mfc, Dec 8 2000, 1:38p David Lowndes +// Subject: How to specify to select an initial folder .." +// +int CALLBACK Fl_Native_File_Chooser::Dir_CB(HWND win, UINT msg, LPARAM param, LPARAM data) { + switch (msg) { + case BFFM_INITIALIZED: + if (data) ::SendMessage(win, BFFM_SETSELECTION, TRUE, data); + break; + case BFFM_SELCHANGED: + TCHAR path[MAX_PATH]; + if ( SHGetPathFromIDList((ITEMIDLIST*)param, path) ) { + ::SendMessage(win, BFFM_ENABLEOK, 0, 1); + } else { + // disable ok button if not a path + ::SendMessage(win, BFFM_ENABLEOK, 0, 0); + } + break; + case BFFM_VALIDATEFAILED: + // we could pop up an annoying message here. + // also needs set ulFlags |= BIF_VALIDATE + break; + default: + break; + } + return(0); +} + +// SHOW DIRECTORY BROWSER +int Fl_Native_File_Chooser::showdir() { + OleInitialize(NULL); // init needed by BIF_USENEWUI + ClearBINF(); + clear_pathnames(); + // PARENT WINDOW + _binf.hwndOwner = GetForegroundWindow(); + // DIALOG TITLE + _binf.lpszTitle = _title ? _title : NULL; + // FLAGS + _binf.ulFlags = 0; // initialize + + // TBD: make sure matches to runtime system, if need be. + //(what if _WIN32_IE doesn't match system? does the program not run?) + // + // TBD: match all 3 types of directories + // + // NOTE: *Don't* use BIF_SHAREABLE. It /disables/ mapped network shares + // from being visible in BROWSE_DIRECTORY mode. + // See Walter Garm's comments in ./TODO. + +#if defined(BIF_NONEWFOLDERBUTTON) // Version 6.0 + if ( _btype == BROWSE_DIRECTORY ) _binf.ulFlags |= BIF_NONEWFOLDERBUTTON; + _binf.ulFlags |= BIF_USENEWUI | BIF_RETURNONLYFSDIRS; +#elif defined(BIF_USENEWUI) // Version 5.0 + if ( _btype == BROWSE_DIRECTORY ) _binf.ulFlags |= BIF_EDITBOX; + else if ( _btype == BROWSE_SAVE_DIRECTORY ) _binf.ulFlags |= BIF_USENEWUI; + _binf.ulFlags |= BIF_RETURNONLYFSDIRS; +#elif defined(BIF_EDITBOX) // Version 4.71 + _binf.ulFlags |= BIF_RETURNONLYFSDIRS | BIF_EDITBOX; +#else // Version Old + _binf.ulFlags |= BIF_RETURNONLYFSDIRS; +#endif + + // BUFFER + char displayname[MAX_PATH]; + _binf.pszDisplayName = displayname; + // PRESET DIR + char presetname[MAX_PATH]; + if ( _directory ) { + strcpy(presetname, _directory); + // Unix2Win(presetname); + _binf.lParam = (LPARAM)presetname; + } + else _binf.lParam = 0; + _binf.lpfn = Dir_CB; + // OPEN BROWSER + ITEMIDLIST *pidl = SHBrowseForFolder(&_binf); + // CANCEL? + if ( pidl == NULL ) return(1); + + // GET THE PATHNAME(S) THE USER SELECTED + // TBD: expand NetHood shortcuts from this PIDL?? + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/functions/shbrowseforfolder.asp + + TCHAR path[MAX_PATH]; + if ( SHGetPathFromIDList(pidl, path) ) { + // Win2Unix(path); + add_pathname(path); + } + FreePIDL(pidl); + if ( !strlen(path) ) return(1); // don't return empty pathnames + return(0); +} + +// RETURNS: +// 0 - user picked a file +// 1 - user cancelled +// -1 - failed; errmsg() has reason +// +int Fl_Native_File_Chooser::show() { + if ( _btype == BROWSE_DIRECTORY || + _btype == BROWSE_MULTI_DIRECTORY || + _btype == BROWSE_SAVE_DIRECTORY ) { + return(showdir()); + } else { + return(showfile()); + } +} + +// RETURN ERROR MESSAGE +const char *Fl_Native_File_Chooser::errmsg() const { + return(_errmsg ? _errmsg : "No error"); +} + +// GET FILENAME +const char* Fl_Native_File_Chooser::filename() const { + if ( _pathnames && _tpathnames > 0 ) return(_pathnames[0]); + return(""); +} + +// GET FILENAME FROM LIST OF FILENAMES +const char* Fl_Native_File_Chooser::filename(int i) const { + if ( _pathnames && i < _tpathnames ) return(_pathnames[i]); + return(""); +} + +// GET TOTAL FILENAMES CHOSEN +int Fl_Native_File_Chooser::count() const { + return(_tpathnames); +} + +// PRESET PATHNAME +// Can be NULL if no preset is desired. +// +void Fl_Native_File_Chooser::directory(const char *val) { + _directory = strfree(_directory); + _directory = strnew(val); +} + +// GET PRESET PATHNAME +// Can return NULL if none set. +// +const char *Fl_Native_File_Chooser::directory() const { + return(_directory); +} + +// SET TITLE +// Can be NULL if no title desired. +// +void Fl_Native_File_Chooser::title(const char *val) { + _title = strfree(_title); + _title = strnew(val); +} + +// GET TITLE +// Can return NULL if none set. +// +const char *Fl_Native_File_Chooser::title() const { + return(_title); +} + +// SET FILTER +// Can be NULL if no filter needed +// +void Fl_Native_File_Chooser::filter(const char *val) { + _filter = strfree(_filter); + clear_filters(); + if ( val ) { + _filter = strnew(val); + parse_filter(_filter); + } + add_filter("All Files", "*.*"); // always include 'all files' option + +#ifdef DEBUG + nullprint(_parsedfilt); +#endif /*DEBUG*/ +} + +// GET FILTER +// Can return NULL if none set. +// +const char *Fl_Native_File_Chooser::filter() const { + return(_filter); +} + +// CLEAR FILTERS +void Fl_Native_File_Chooser::clear_filters() { + _nfilters = 0; + _parsedfilt = strfree(_parsedfilt); +} + +// ADD A FILTER +void Fl_Native_File_Chooser::add_filter(const char *name_in, // name of filter (optional: can be null) + const char *winfilter) { // windows style filter (eg. "*.cxx;*.h") + // No name? Make one.. + char name[1024]; + if ( !name_in || name_in[0] == '\0' ) { + sprintf(name, "%.*s Files", sizeof(name)-10, winfilter); + } else { + sprintf(name, "%.*s", sizeof(name)-10, name_in); + } + dnullcat(_parsedfilt, name); + dnullcat(_parsedfilt, winfilter); + _nfilters++; + //DEBUG printf("DEBUG: ADD FILTER name=<%s> winfilter=<%s>\n", name, winfilter); +} + +// CONVERT FLTK STYLE PATTERN MATCHES TO WINDOWS 'DOUBLENULL' PATTERN +// Handles: +// IN OUT +// ----------- ----------------------------- +// *.{ma,mb} "*.{ma,mb} Files\0*.ma;*.mb\0\0" +// *.[abc] "*.[abc] Files\0*.a;*.b;*.c\0\0" +// *.txt "*.txt Files\0*.txt\0\0" +// C Files\t*.[ch] "C Files\0*.c;*.h\0\0" +// +// Example: +// IN: "*.{ma,mb}" +// OUT: "*.ma;*.mb Files\0*.ma;*.mb\0All Files\0*.*\0\0" +// --------------- --------- --------- --- +// | | | | +// Title Wildcards Title Wildcards +// +// Parsing Mode: +// IN:"C Files\t*.{cxx,h}" +// ||||||| ||||||||| +// mode: nnnnnnn ww{{{{{{{ +// \_____/ \_______/ +// Name Wildcard +// +void Fl_Native_File_Chooser::parse_filter(const char *in) { + clear_filters(); + if ( ! in ) return; + + int has_name = strchr(in, '\t') ? 1 : 0; + + char mode = has_name ? 'n' : 'w'; // parse mode: n=name, w=wildcard + int nwildcards = 0; + char wildcards[MAXFILTERS][1024]; // parsed wildcards (can be several) + char wildprefix[512] = ""; + char name[512] = ""; + + // Init + int t; + for ( t=0; t name=<%s> wildprefix=<%s> nwildcards=%d wildcards[n]=<%s>\n", + //// *in, mode, name, wildprefix, nwildcards, wildcards[nwildcards]); + + switch (*in) { + case ',': + case '|': + if ( mode == LCURLY_CHR ) { + // create new wildcard, copy in prefix + strcat(wildcards[nwildcards++], wildprefix); + continue; + } else { + goto regchar; + } + continue; + + // FINISHED PARSING A NAME? + case '\t': + if ( mode != 'n' ) goto regchar; + // finish parsing name? switch to wildcard mode + mode = 'w'; + break; + + // ESCAPE NEXT CHAR + case '\\': + ++in; + goto regchar; + + // FINISHED PARSING ONE OF POSSIBLY SEVERAL FILTERS? + case '\r': + case '\n': + case '\0': + { + if ( mode == 'w' ) { // finished parsing wildcard? + if ( nwildcards == 0 ) { + strcpy(wildcards[nwildcards++], wildprefix); + } + // Append wildcards in Microsoft's "*.one;*.two" format + char comp[4096] = ""; + for ( t=0; t 0 ) { + chrcat(wildcards[nwildcards-1], *in); + } + continue; + + case 'n': + chrcat(name, *in); + continue; + + case 'w': + chrcat(wildprefix, *in); + for ( t=0; t lchar) { + lchar = utf8len; + out = (char *)realloc(out, lchar * sizeof(char)); + } + WideCharToMultiByte(CP_UTF8, 0, in, -1, out, utf8len, NULL, NULL); + return out; +} + +LPCWSTR utf8towchar(const char *in) +{ + static WCHAR *wout = NULL; + static int lwout = 0; + if (in == NULL)return NULL; + int wlen = MultiByteToWideChar(CP_UTF8, 0, in, -1, NULL, 0); + if (wlen > lwout) { + lwout = wlen; + wout = (WCHAR *)realloc(wout, lwout * sizeof(WCHAR)); + } + MultiByteToWideChar(CP_UTF8, 0, in, -1, wout, wlen); + return wout; +} + +#endif /*!FL_DOXYGEN*/ + +// +// End of "$Id: Fl_Native_File_Chooser_WIN32.cxx 7312 2010-03-21 22:55:18Z fabien $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Native_File_Chooser_common.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Native_File_Chooser_common.cxx new file mode 100644 index 000000000..209c9c725 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Native_File_Chooser_common.cxx @@ -0,0 +1,83 @@ +// "$Id: Fl_Native_File_Chooser_common.cxx 7001 2010-01-14 19:38:23Z ianmacarthur $" +// +// FLTK native OS file chooser widget +// +// Copyright 1998-2005 by Bill Spitzak and others. +// Copyright 2004 Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +#include +#include + +// COPY A STRING WITH 'new' +// Value can be NULL +// +static char *strnew(const char *val) { + if ( val == NULL ) return(NULL); + char *s = new char[strlen(val)+1]; + strcpy(s, val); + return(s); +} + +// FREE STRING CREATED WITH strnew(), NULLS OUT STRING +// Value can be NULL +// +static char *strfree(char *val) { + if ( val ) delete [] val; + return(NULL); +} + +// 'DYNAMICALLY' APPEND ONE STRING TO ANOTHER +// Returns newly allocated string, or NULL +// if s && val == NULL. +// 's' can be NULL; returns a strnew(val). +// 'val' can be NULL; s is returned unmodified. +// +// Usage: +// char *s = strnew("foo"); // s = "foo" +// s = strapp(s, "bar"); // s = "foobar" +// +static char *strapp(char *s, const char *val) { + if ( ! val ) { + return(s); // Nothing to append? return s + } + if ( ! s ) { + return(strnew(val)); // New string? return copy of val + } + char *news = new char[strlen(s)+strlen(val)+1]; + strcpy(news, s); + strcat(news, val); + delete [] s; // delete old string + return(news); // return new copy +} + +// APPEND A CHARACTER TO A STRING +// This does NOT allocate space for the new character. +// +static void chrcat(char *s, char c) { + char tmp[2] = { c, '\0' }; + strcat(s, tmp); +} + +// +// End of "$Id: Fl_Native_File_Chooser_common.cxx 7001 2010-01-14 19:38:23Z ianmacarthur $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Overlay_Window.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Overlay_Window.cxx index af6090ee8..8eec995eb 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Overlay_Window.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Overlay_Window.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Overlay_Window.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_Overlay_Window.cxx 7636 2010-06-09 08:36:25Z AlbrechtS $" // // Overlay window code for the Fast Light Tool Kit (FLTK). // @@ -61,7 +61,7 @@ void Fl_Overlay_Window::flush() { return; } #endif - int erase_overlay = (damage()&FL_DAMAGE_OVERLAY); + int erase_overlay = (damage()&FL_DAMAGE_OVERLAY) | (overlay_ == this); clear_damage((uchar)(damage()&~FL_DAMAGE_OVERLAY)); Fl_Double_Window::flush(erase_overlay); if (overlay_ == this) draw_overlay(); @@ -172,5 +172,5 @@ void Fl_Overlay_Window::redraw_overlay() { #endif // -// End of "$Id: Fl_Overlay_Window.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_Overlay_Window.cxx 7636 2010-06-09 08:36:25Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Paged_Device.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Paged_Device.cxx new file mode 100644 index 000000000..faa436983 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Paged_Device.cxx @@ -0,0 +1,291 @@ +// +// "$Id: Fl_Paged_Device.cxx 7623 2010-05-27 17:52:27Z manolo $" +// +// implementation of Fl_Paged_Device class for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// +/** \file Fl_Paged_Device.cxx + \brief implementation of class Fl_Paged_Device. + */ + +#include +#include + +const char *Fl_Paged_Device::device_type = "Fl_Paged_Device"; + + +/** + @brief Draws the widget on the printed page. + * + The widget's position on the printed page is determined by the last call to origin() + and by the optional delta_x and delta_y arguments. + Its dimensions are in points unless there was a previous call to scale(). + @param[in] widget Any FLTK widget (e.g., standard, custom, window). + @param[in] delta_x Optional horizontal offset for positioning the widget relatively + to the current origin of graphics functions. + @param[in] delta_y Same as above, vertically. + */ +void Fl_Paged_Device::print_widget(Fl_Widget* widget, int delta_x, int delta_y) +{ + int old_x, old_y, new_x, new_y, is_window; + if ( ! widget->visible() ) return; + is_window = (widget->as_window() != NULL); + widget->damage(FL_DAMAGE_ALL); + // set origin to the desired top-left position of the widget + origin(&old_x, &old_y); + new_x = old_x + delta_x; + new_y = old_y + delta_y; + if (!is_window) { + new_x -= widget->x(); + new_y -= widget->y(); + } + if (new_x != old_x || new_y != old_y) { + translate(new_x - old_x, new_y - old_y ); + } + // if widget is a window, clip all drawings to the window area + if (is_window) fl_push_clip(0, 0, widget->w(), widget->h() ); + // we do some trickery to recognize OpenGL windows and draw them via a plugin + int drawn_by_plugin = 0; + if (widget->as_gl_window()) { + Fl_Plugin_Manager pm("fltk:device"); + Fl_Device_Plugin *pi = (Fl_Device_Plugin*)pm.plugin("opengl.device.fltk.org"); + if (pi) { + int width, height; + this->printable_rect(&width, &height); + drawn_by_plugin = pi->print(widget, 0, 0, height); + } + } + if (!drawn_by_plugin) { + widget->draw(); + } + if (is_window) fl_pop_clip(); + // find subwindows of widget and print them + traverse(widget); + // reset origin to where it was + if (new_x != old_x || new_y != old_y) { + untranslate(); + } +} + + +void Fl_Paged_Device::traverse(Fl_Widget *widget) +{ + Fl_Group *g = widget->as_group(); + if (!g) return; + int n = g->children(); + for (int i = 0; i < n; i++) { + Fl_Widget *c = g->child(i); + if ( !c->visible() ) continue; + if ( c->as_window() ) { + print_widget(c, c->x(), c->y()); + } + else traverse(c); + } +} + +/** + @brief Computes the page coordinates of the current origin of graphics functions. + * + @param[out] x If non-null, *x is set to the horizontal page offset of graphics origin. + @param[out] y Same as above, vertically. + */ +void Fl_Paged_Device::origin(int *x, int *y) +{ + if (x) *x = x_offset; + if (y) *y = y_offset; +} + +/** + @brief Prints a rectangular part of an on-screen window. + * + @param win The window from where to capture. + @param x The rectangle left + @param y The rectangle top + @param w The rectangle width + @param h The rectangle height + @param delta_x Optional horizontal offset from current graphics origin where to print the captured rectangle. + @param delta_y As above, vertically. + */ +void Fl_Paged_Device::print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x, int delta_y) +{ + int slice, width, offset, count = 0; + Fl_Surface_Device *current = Fl_Surface_Device::surface(); + Fl_Display_Device::display_device()->set_current(); + Fl_Window *save_front = Fl::first_window(); + win->show(); + fl_gc = NULL; + Fl::check(); + win->make_current(); + uchar *image_data[20]; +#ifdef WIN32 // because of bug in StretchDIBits, vertically cut image in pieces of width slice + slice = 500; +#else + slice = w; +#endif + for ( offset = 0; offset < w; offset += slice) { + width = slice; + if (offset + width > w) width = w - offset; + image_data[count++] = fl_read_image(NULL, x + offset, y, width, h); + } + save_front->show(); + current->set_current(); + for ( int i = 0, offset = 0; i < count; i++, offset += slice) { + width = slice; + if (offset + width > w) width = w - offset; + fl_draw_image(image_data[i], delta_x + offset, delta_y, width, h, 3); +#ifdef __APPLE__ + add_image(NULL, image_data[i]); +#else + delete image_data[i]; +#endif + } +} + +#ifdef __APPLE__ +void Fl_Paged_Device::add_image(Fl_Image *image, const uchar *data) +{ + struct chain_elt *elt = (struct chain_elt *)calloc(sizeof(struct chain_elt), 1); + elt->image = image; + elt->data = data; + if (image_list_) { elt->next = image_list_; } + image_list_ = elt; +} + +void Fl_Paged_Device::delete_image_list() +{ + while(image_list_) { + struct chain_elt *next = image_list_->next; + if(image_list_->image) delete image_list_->image; + if (image_list_->data) delete (uchar*) image_list_->data; // msvc6 compilation fix + free(image_list_); + image_list_ = next; + } +} +#endif + + +/** + @brief Starts a print job. + * + @param[in] pagecount the total number of pages of the job + @param[out] frompage if non-null, *frompage is set to the first page the user wants printed + @param[out] topage if non-null, *topage is set to the last page the user wants printed + @return 0 iff OK + */ +int Fl_Paged_Device::start_job(int pagecount, int *frompage, int *topage) {return 1;} + +/** + @brief Starts a new printed page + * + The page coordinates are initially in points, i.e., 1/72 inch, + and with origin at the top left of the printable page area. + @return 0 iff OK + */ +int Fl_Paged_Device::start_page (void) {return 1;} + +/** + @brief Computes the width and height of the printable area of the page. + * + Values are in the same unit as that used by FLTK drawing functions, + are unchanged by calls to origin(), but are changed by scale() calls. + Values account for the user-selected paper type and print orientation. + @return 0 iff OK. + */ +int Fl_Paged_Device::printable_rect(int *w, int *h) {return 1;} + +/** + @brief Computes the dimensions of margins that lie between the printable page area and + the full page. + * + Values are in the same unit as that used by FLTK drawing functions. They are changed + by scale() calls. + @param[out] left If non-null, *left is set to the left margin size. + @param[out] top If non-null, *top is set to the top margin size. + @param[out] right If non-null, *right is set to the right margin size. + @param[out] bottom If non-null, *bottom is set to the bottom margin size. + */ +void Fl_Paged_Device::margins(int *left, int *top, int *right, int *bottom) {} + +/** + @brief Sets the position in page coordinates of the origin of graphics functions. + * + Arguments should be expressed relatively to the result of a previous printable_rect() call. + That is, printable_rect(&w, &h); origin(w/2, 0); sets the graphics origin at the + top center of the page printable area. + Origin() calls are not affected by rotate() calls. + Successive origin() calls don't combine their effects. + @param[in] x Horizontal position in page coordinates of the desired origin of graphics functions. + @param[in] y Same as above, vertically. + */ +void Fl_Paged_Device::origin(int x, int y) {} + +/** + @brief Changes the scaling of page coordinates. + * + This function also resets the origin of graphics functions at top left of printable page area. + After a scale() call, do a printable_rect() call to get the new dimensions of the printable page area. + Successive scale() calls don't combine their effects. + @param scale_x Horizontal dimensions of plot are multiplied by this quantity. + @param scale_y Same as above, vertically. + */ +void Fl_Paged_Device::scale (float scale_x, float scale_y) {} + +/** + @brief Rotates the graphics operations relatively to paper. + * + The rotation is centered on the current graphics origin. + Successive rotate() calls don't combine their effects. + @param angle Rotation angle in counterclockwise degrees. + */ +void Fl_Paged_Device::rotate(float angle) {} + +/** + @brief To be called at the end of each page. + * + @return 0 iff OK. + */ +int Fl_Paged_Device::end_page (void) {return 1;} + +/** + @brief To be called at the end of a print job. + */ +void Fl_Paged_Device::end_job (void) {} + +/** + @brief Translates the current graphics origin accounting for the current rotation. + * + This function is only useful after a rotate() call. + Each translate() call must be matched by an untranslate() call. + Successive translate() calls add up their effects. + */ +void Fl_Paged_Device::translate(int x, int y) {} + +/** + @brief Undoes the effect of a previous translate() call. + */ +void Fl_Paged_Device::untranslate(void) {} + +// +// End of "$Id: Fl_Paged_Device.cxx 7623 2010-05-27 17:52:27Z manolo $". +// + diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Pixmap.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Pixmap.cxx index 3093f6059..3130e1786 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Pixmap.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Pixmap.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Pixmap.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_Pixmap.cxx 7659 2010-07-01 13:21:32Z manolo $" // // Pixmap drawing code for the Fast Light Tool Kit (FLTK). // @@ -47,6 +47,7 @@ #include #include #include +#include #include #include "flstring.h" @@ -74,90 +75,164 @@ void Fl_Pixmap::measure() { } void Fl_Pixmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) { + fl_graphics_driver->draw(this, XP, YP, WP, HP, cx, cy); +} + +static int start(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int w, int h, int &cx, int &cy, + int &X, int &Y, int &W, int &H) +{ // ignore empty or bad pixmap data: - if (!data()) { - draw_empty(XP, YP); - return; + if (!pxm->data()) { + return 2; } - if (w()<0) measure(); - if (WP==-1) { - WP = w(); - HP = h(); + if (WP == -1) { + WP = w; + HP = h; } - if (!w()) { - draw_empty(XP, YP); - return; + if (!w) { + return 2; } // account for current clip region (faster on Irix): - int X,Y,W,H; fl_clip_box(XP,YP,WP,HP,X,Y,W,H); + fl_clip_box(XP,YP,WP,HP,X,Y,W,H); cx += X-XP; cy += Y-YP; // clip the box down to the size of image, quit if empty: if (cx < 0) {W += cx; X -= cx; cx = 0;} - if (cx+W > w()) W = w()-cx; - if (W <= 0) return; + if (cx+W > w) W = w-cx; + if (W <= 0) return 1; if (cy < 0) {H += cy; Y -= cy; cy = 0;} - if (cy+H > h()) H = h()-cy; - if (H <= 0) return; - if (!id) { -#ifdef __APPLE_QUARTZ__ - id = fl_create_offscreen_with_alpha(w(), h()); - fl_begin_offscreen((Fl_Offscreen)id); - fl_draw_pixmap(data(), 0, 0, FL_GREEN); + if (cy+H > h) H = h-cy; + if (H <= 0) return 1; + return 0; +} + +#ifdef __APPLE__ +void Fl_Quartz_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + if (pxm->w() < 0) pxm->measure(); + int code = start(pxm, XP, YP, WP, HP, pxm->w(), pxm->h(), cx, cy, X, Y, W, H); + if (code) { + if (code == 2) pxm->draw_empty(XP, YP); + return; + } + if (!pxm->id_) { + pxm->id_ = fl_create_offscreen_with_alpha(pxm->w(), pxm->h()); + fl_begin_offscreen((Fl_Offscreen)pxm->id_); + fl_draw_pixmap(pxm->data(), 0, 0, FL_GREEN); fl_end_offscreen(); -#else - id = fl_create_offscreen(w(), h()); - fl_begin_offscreen((Fl_Offscreen)id); + } + fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)pxm->id_, cx, cy); +} + +#elif defined(WIN32) +void Fl_GDI_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + if (pxm->w() < 0) pxm->measure(); + int code = start(pxm, XP, YP, WP, HP, pxm->w(), pxm->h(), cx, cy, X, Y, W, H); + if (code) { + if (code == 2) pxm->draw_empty(XP, YP); + return; + } + if (!pxm->id_) { + pxm->id_ = fl_create_offscreen(pxm->w(), pxm->h()); + fl_begin_offscreen((Fl_Offscreen)pxm->id_); uchar *bitmap = 0; fl_mask_bitmap = &bitmap; - fl_draw_pixmap(data(), 0, 0, FL_BLACK); + fl_draw_pixmap(pxm->data(), 0, 0, FL_BLACK); fl_mask_bitmap = 0; if (bitmap) { - mask = fl_create_bitmask(w(), h(), bitmap); + pxm->mask_ = fl_create_bitmask(pxm->w(), pxm->h(), bitmap); delete[] bitmap; } fl_end_offscreen(); -#endif } + if (fl_surface->type() == Fl_Printer::device_type) { + typedef BOOL (WINAPI* fl_transp_func) (HDC,int,int,int,int,HDC,int,int,int,int,UINT); + static HMODULE hMod = NULL; + static fl_transp_func fl_TransparentBlt = NULL; + if (!hMod) { + hMod = LoadLibrary("MSIMG32.DLL"); + if(hMod) fl_TransparentBlt = (fl_transp_func)GetProcAddress(hMod, "TransparentBlt"); + } + if (hMod) { + Fl_Offscreen tmp_id = fl_create_offscreen(pxm->w(), pxm->h()); + fl_begin_offscreen(tmp_id); + uchar *bitmap = 0; + fl_mask_bitmap = &bitmap; + // draw pixmap to offscreen + fl_draw_pixmap(pxm->data(), 0, 0); + fl_end_offscreen(); + HDC new_gc = CreateCompatibleDC(fl_gc); + int save = SaveDC(new_gc); + SelectObject(new_gc, (void*)tmp_id); + // print all of offscreen but its parts in background color + extern UINT win_pixmap_bg_color; // computed by fl_draw_pixmap() + fl_TransparentBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, pxm->w(), pxm->h(), win_pixmap_bg_color ); + RestoreDC(new_gc,save); + DeleteDC(new_gc); + fl_delete_offscreen(tmp_id); + } + else { + fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)pxm->id_, cx, cy); + } + } + else if (pxm->mask_) { + HDC new_gc = CreateCompatibleDC(fl_gc); + int save = SaveDC(new_gc); + SelectObject(new_gc, (void*)pxm->mask_); + BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND); + SelectObject(new_gc, (void*)pxm->id_); + BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT); + RestoreDC(new_gc,save); + DeleteDC(new_gc); + } else { + fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)pxm->id_, cx, cy); + } +} -#if defined(USE_X11) - if (mask) { +#else // Xlib +void Fl_Xlib_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + if (pxm->w() < 0) pxm->measure(); + int code = start(pxm, XP, YP, WP, HP, pxm->w(), pxm->h(), cx, cy, X, Y, W, H); + if (code) { + if (code == 2) pxm->draw_empty(XP, YP); + return; + } + if (!pxm->id_) { + pxm->id_ = fl_create_offscreen(pxm->w(), pxm->h()); + fl_begin_offscreen((Fl_Offscreen)pxm->id_); + uchar *bitmap = 0; + fl_mask_bitmap = &bitmap; + fl_draw_pixmap(pxm->data(), 0, 0, FL_BLACK); + fl_mask_bitmap = 0; + if (bitmap) { + pxm->mask_ = fl_create_bitmask(pxm->w(), pxm->h(), bitmap); + delete[] bitmap; + } + fl_end_offscreen(); + } + if (pxm->mask_) { // I can't figure out how to combine a mask with existing region, // so cut the image down to a clipped rectangle: int nx, ny; fl_clip_box(X,Y,W,H,nx,ny,W,H); cx += nx-X; X = nx; cy += ny-Y; Y = ny; // make X use the bitmap as a mask: - XSetClipMask(fl_display, fl_gc, mask); - int ox = X-cx; if (ox < 0) ox += w(); - int oy = Y-cy; if (oy < 0) oy += h(); + XSetClipMask(fl_display, fl_gc, pxm->mask_); + int ox = X-cx; if (ox < 0) ox += pxm->w(); + int oy = Y-cy; if (oy < 0) oy += pxm->h(); XSetClipOrigin(fl_display, fl_gc, X-cx, Y-cy); } - fl_copy_offscreen(X, Y, W, H, id, cx, cy); - if (mask) { + fl_copy_offscreen(X, Y, W, H, pxm->id_, cx, cy); + if (pxm->mask_) { // put the old clip region back XSetClipOrigin(fl_display, fl_gc, 0, 0); fl_restore_clip(); } -#elif defined(WIN32) - if (mask) { - HDC new_gc = CreateCompatibleDC(fl_gc); - int save = SaveDC(new_gc); - SelectObject(new_gc, (void*)mask); - BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND); - SelectObject(new_gc, (void*)id); - BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT); - RestoreDC(new_gc,save); - DeleteDC(new_gc); - } else { - fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy); - } -#elif defined(__APPLE_QUARTZ__) - fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy); -#else -# error unsupported platform -#endif } +#endif + /** The destructor free all memory and server resources that are used by the pixmap. @@ -168,14 +243,14 @@ Fl_Pixmap::~Fl_Pixmap() { } void Fl_Pixmap::uncache() { - if (id) { - fl_delete_offscreen((Fl_Offscreen)id); - id = 0; + if (id_) { + fl_delete_offscreen((Fl_Offscreen)id_); + id_ = 0; } - if (mask) { - fl_delete_bitmask((Fl_Bitmask)mask); - mask = 0; + if (mask_) { + fl_delete_bitmask((Fl_Bitmask)mask_); + mask_ = 0; } } @@ -484,5 +559,5 @@ void Fl_Pixmap::desaturate() { } // -// End of "$Id: Fl_Pixmap.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_Pixmap.cxx 7659 2010-07-01 13:21:32Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_PostScript.cxx b/plugins/zynaddsubfx/fltk/src/Fl_PostScript.cxx new file mode 100644 index 000000000..1f55badff --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_PostScript.cxx @@ -0,0 +1,1412 @@ +// +// "$Id: Fl_PostScript.cxx 7653 2010-06-24 08:55:04Z manolo $" +// +// PostScript device support for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include +#include + +const char *Fl_PostScript_Graphics_Driver::device_type = "Fl_PostScript_Graphics_Driver"; +const char *Fl_PostScript_File_Device::device_type = "Fl_PostScript_File_Device"; +/** \brief Label of the PostScript file chooser window */ +const char *Fl_PostScript_File_Device::file_chooser_title = "Select a .ps file"; + +/** + @brief The constructor. + */ +Fl_PostScript_Graphics_Driver::Fl_PostScript_Graphics_Driver(void) +{ + close_cmd_ = 0; + //lang_level_ = 3; + lang_level_ = 2; + mask = 0; + ps_filename_ = NULL; + type_ = device_type; + scale_x = scale_y = 1.; + bg_r = bg_g = bg_b = 255; +} + +/** \brief The destructor. */ +Fl_PostScript_Graphics_Driver::~Fl_PostScript_Graphics_Driver() { + if(ps_filename_) free(ps_filename_); +} + +/** + @brief The constructor. + */ +Fl_PostScript_File_Device::Fl_PostScript_File_Device(void) +{ + type_ = device_type; +#ifdef __APPLE__ + gc = fl_gc; // the display context is used by fl_text_extents() +#endif + Fl_Surface_Device::driver( new Fl_PostScript_Graphics_Driver() ); +} + +/** + \brief Returns the PostScript driver of this drawing surface. + */ +Fl_PostScript_Graphics_Driver *Fl_PostScript_File_Device::driver() +{ + return (Fl_PostScript_Graphics_Driver*)Fl_Surface_Device::driver(); +} + + +/** + @brief Begins the session where all graphics requests will go to a local PostScript file. + * + Opens a file dialog entitled with Fl_PostScript_File_Device::file_chooser_title to select an output PostScript file. + @param pagecount The total number of pages to be created. + @param format Desired page format. + @param layout Desired page layout. + @return 0 iff OK, 1 if user cancelled the file dialog, 2 if fopen failed on user-selected output file. + */ +int Fl_PostScript_File_Device::start_job (int pagecount, enum Fl_PostScript_Graphics_Driver::Page_Format format, enum Fl_PostScript_Graphics_Driver::Page_Layout layout) +{ + Fl_Native_File_Chooser fnfc; + fnfc.title(Fl_PostScript_File_Device::file_chooser_title); + fnfc.type(Fl_Native_File_Chooser::BROWSE_SAVE_FILE); + fnfc.options(Fl_Native_File_Chooser::SAVEAS_CONFIRM); + fnfc.filter("PostScript\t*.ps\n"); + // Show native chooser + if ( fnfc.show() ) return 1; + Fl_PostScript_Graphics_Driver *ps = driver(); + ps->output = fopen(fnfc.filename(), "w"); + if(ps->output == NULL) return 2; + ps->ps_filename_ = strdup(fnfc.filename()); + ps->start_postscript(pagecount, format, layout); + this->set_current(); + return 0; +} + +/** + @brief Begins the session where all graphics requests will go to FILE pointer. + * + @param ps_output A writable FILE pointer that will receive PostScript output and that will be closed + when end_job() will be called. + @param pagecount The total number of pages to be created. + @param format Desired page format. + @param layout Desired page layout. + @return always 0. + */ +int Fl_PostScript_File_Device::start_job (FILE *ps_output, int pagecount, enum Fl_PostScript_Graphics_Driver::Page_Format format, enum Fl_PostScript_Graphics_Driver::Page_Layout layout) +{ + Fl_PostScript_Graphics_Driver *ps = driver(); + ps->output = ps_output; + ps->ps_filename_ = NULL; + ps->start_postscript(pagecount, format, layout); + this->set_current(); + return 0; +} + +/** + @brief The destructor. + */ +Fl_PostScript_File_Device::~Fl_PostScript_File_Device() { + Fl_PostScript_Graphics_Driver *ps = driver(); + if (ps) delete ps; +} + +#ifndef FL_DOXYGEN + +#if ! (defined(__APPLE__) || defined(WIN32) ) + #include "print_panel.cxx" +#endif + +const Fl_PostScript_Graphics_Driver::page_format Fl_PostScript_Graphics_Driver::page_formats[NO_PAGE_FORMATS] = { // order of enum Page_Format +// comes from appendix B of 5003.PPD_Spec_v4.3.pdf + + // A* // index(Ai) = i + {2384, 3370, "A0"}, + {1684, 2384, "A1"}, + {1191, 1684, "A2"}, + { 842, 1191, "A3"}, + { 595, 842, "A4"}, + { 420, 595, "A5"}, + { 297, 420, "A6"}, + { 210, 297, "A7"}, + { 148, 210, "A8"}, + { 105, 148, "A9"}, + + // B* // index(Bi) = i+10 + {2920, 4127, "B0"}, + {2064, 2920, "B1"}, + {1460, 2064, "B2"}, + {1032, 1460, "B3"}, + { 729, 1032, "B4"}, + { 516, 729, "B5"}, + { 363, 516, "B6"}, + { 258, 363, "B7"}, + { 181, 258, "B8"}, + { 127, 181, "B9"}, + { 91, 127, "B10"}, + + // others + { 459, 649, "EnvC5"}, // envelope + { 312, 624, "EnvDL"}, // envelope + { 522, 756, "Executive"}, + { 595, 935, "Folio"}, + {1224, 792, "Ledger"}, // landscape + { 612, 1008, "Legal"}, + { 612, 792, "Letter"}, + { 792, 1224, "Tabloid"}, + { 297, 684, "Env10"} // envelope +}; + +// Prolog string + +static const char * prolog = +"%%BeginProlog\n" +"/L { /y2 exch def\n" +"/x2 exch def\n" +"/y1 exch def\n" +"/x1 exch def\n" +"newpath x1 y1 moveto x2 y2 lineto\n" +"stroke}\n" +"bind def\n" + + +"/R { /dy exch def\n" +"/dx exch def\n" +"/y exch def\n" +"/x exch def\n" +"newpath\n" +"x y moveto\n" +"dx 0 rlineto\n" +"0 dy rlineto\n" +"dx neg 0 rlineto\n" +"closepath stroke\n" +"} bind def\n" + +"/CL {\n" +"/dy exch def\n" +"/dx exch def\n" +"/y exch def\n" +"/x exch def\n" +"newpath\n" +"x y moveto\n" +"dx 0 rlineto\n" +"0 dy rlineto\n" +"dx neg 0 rlineto\n" +"closepath\n" +"clip\n" +"} bind def\n" + +"/FR { /dy exch def\n" +"/dx exch def\n" +"/y exch def\n" +"/x exch def\n" +"currentlinewidth 0 setlinewidth newpath\n" +"x y moveto\n" +"dx 0 rlineto\n" +"0 dy rlineto\n" +"dx neg 0 rlineto\n" +"closepath fill setlinewidth\n" +"} bind def\n" + +"/GS { gsave } bind def\n" +"/GR { grestore } bind def\n" + +"/SP { showpage } bind def\n" +"/LW { setlinewidth } bind def\n" +"/CF /Courier def\n" +"/SF { /CF exch def } bind def\n" +"/fsize 12 def\n" +"/FS { /fsize exch def fsize CF findfont exch scalefont setfont }def \n" + + +"/GL { setgray } bind def\n" +"/SRGB { setrgbcolor } bind def\n" + +// color images + +"/CI { GS /py exch def /px exch def /sy exch def /sx exch def\n" +"translate \n" +"sx sy scale px py 8 \n" +"[ px 0 0 py neg 0 py ]\n" +"currentfile /ASCIIHexDecode filter\n false 3" +" colorimage GR\n" +"} bind def\n" + +// gray images + +"/GI { GS /py exch def /px exch def /sy exch def /sx exch def \n" +"translate \n" +"sx sy scale px py 8 \n" + + +"[ px 0 0 py neg 0 py ]\n" +"currentfile /ASCIIHexDecode filter\n" +"image GR\n" +"} bind def\n" + +// single-color bitmask + +"/MI { GS /py exch def /px exch def /sy exch def /sx exch def \n" +"translate \n" +"sx sy scale px py false \n" +"[ px 0 0 py neg 0 py ]\n" +"currentfile /ASCIIHexDecode filter\n" +"imagemask GR\n" +"} bind def\n" + + +// path + +"/BFP { newpath moveto } def\n" +"/BP { newpath } bind def \n" +"/PL { lineto } bind def \n" +"/PM { moveto } bind def \n" +"/MT { moveto } bind def \n" +"/LT { lineto } bind def \n" +"/EFP { closepath fill } bind def\n" //was:stroke +"/ELP { stroke } bind def\n" +"/ECP { closepath stroke } bind def\n" // Closed (loop) +"/LW { setlinewidth } bind def\n" + +// ////////////////////////// misc //////////////// +"/TR { translate } bind def\n" +"/CT { concat } bind def\n" +"/RCT { matrix invertmatrix concat} bind def\n" +"/SC { scale } bind def\n" +//"/GPD { currentpagedevice /PageSize get} def\n" + +// show at position with desired width +// usage: +// width (string) x y show_pos_width +"/show_pos_width {GS moveto dup dup stringwidth pop exch length exch 3 index exch sub exch " +"div 0 2 index 1 -1 scale ashow pop pop GR} bind def\n" // spacing altered to match desired width +//"/show_pos_width {GS moveto dup stringwidth pop 3 2 roll exch div -1 matrix scale concat " +//"show GR } bind def\n" // horizontally scaled text to match desired width + +; + + +static const char * prolog_2 = // prolog relevant only if lang_level >1 + +// color image dictionaries +"/CII {GS /inter exch def /py exch def /px exch def /sy exch def /sx exch def \n" +"translate \n" +"sx sy scale\n" +"/DeviceRGB setcolorspace\n" +"/IDD 8 dict def\n" +"IDD begin\n" +"/ImageType 1 def\n" +"/Width px def\n" +"/Height py def\n" +"/BitsPerComponent 8 def\n" +"/Interpolate inter def\n" +"/DataSource currentfile /ASCIIHexDecode filter def\n" +"/MultipleDataSources false def\n" +"/ImageMatrix [ px 0 0 py neg 0 py ] def\n" +"/Decode [ 0 1 0 1 0 1 ] def\n" +"end\n" +"IDD image GR} bind def\n" + +// gray image dict + + +"/GII {GS /inter exch def /py exch def /px exch def /sy exch def /sx exch def \n" +"translate \n" +"sx sy scale\n" +"/DeviceGray setcolorspace\n" +"/IDD 8 dict def\n" +"IDD begin\n" +"/ImageType 1 def\n" +"/Width px def\n" +"/Height py def\n" +"/BitsPerComponent 8 def\n" + +"/Interpolate inter def\n" +"/DataSource currentfile /ASCIIHexDecode filter def\n" +"/MultipleDataSources false def\n" +"/ImageMatrix [ px 0 0 py neg 0 py ] def\n" +"/Decode [ 0 1 ] def\n" +"end\n" +"IDD image GR} bind def\n" + +// procedure to modify a font to use ISOLatin1 encoding (iso-8859-1) +// and to keep its name unchanged +"/ToLatin1 { dup findfont dup length dict " +"begin {def} forall /Encoding ISOLatin1Encoding def currentdict end definefont pop } def\n" +// modify all fonts to use ISOLatin1 encoding +"/Helvetica ToLatin1 " +"/Helvetica-Bold ToLatin1 " +"/Helvetica-Oblique ToLatin1 " +"/Helvetica-BoldOblique ToLatin1 \n" +"/Courier ToLatin1 " +"/Courier-Bold ToLatin1 " +"/Courier-Oblique ToLatin1 " +"/Courier-BoldOblique ToLatin1 \n" +"/Times ToLatin1 " +"/Times-Bold ToLatin1 " +"/Times-Italic ToLatin1 " +"/Times-BoldItalic ToLatin1 \n" +; + +static const char * prolog_2_pixmap = // prolog relevant only if lang_level == 2 for pixmaps +"/pixmap_size { /pixmap_sy exch def /pixmap_sx exch def } bind def\n" + +"/pixmap_mat {[ pixmap_sx 0 0 pixmap_sy neg 0 pixmap_sy ]} bind def\n" + +"/pixmap_dict {" +"<< /PatternType 1 " +"/PaintType 1 " +"/TilingType 2 " +"/BBox [0 0 pixmap_sx pixmap_sy] " +"/XStep pixmap_sx " +"/YStep pixmap_sy\n" +"/PaintProc " +"{ begin " +"pixmap_sx pixmap_sy scale " +"pixmap_sx pixmap_sy 8 " +"pixmap_mat " +"pixmap_data " +"false 3 " +"colorimage " +"end " +"} bind " +">>\n" +"} bind def\n" + +"/pixmap_plot {" +"GS " +"/pixmap_y exch def /pixmap_x exch def\n" +"pixmap_x pixmap_y translate\n" +"pixmap_dict matrix makepattern setpattern\n" +"pixmap_sx pixmap_sy scale\n" +"pixmap_sx pixmap_sy\n" +"true\n" +"pixmap_mat\n" +"pixmap_mask\n" +"imagemask\n" +"GR\n" +"} bind def\n" + +"/pixmap_loaddata { /pixmap_data currentfile pixmap_sx pixmap_sy 3 mul mul string readhexstring " +"} bind def\n" + +"/pixmap_loadmask { " +"/pixmap_mask currentfile pixmap_sx 8 div ceiling cvi pixmap_sy mul string readhexstring " +"} bind def\n" +; + + + +static const char * prolog_3 = // prolog relevant only if lang_level >2 + +// masked color images +"/CIM {GS /inter exch def /my exch def /mx exch def /py exch def /px exch def /sy exch def /sx exch def \n" +"translate \n" +"sx sy scale\n" +"/DeviceRGB setcolorspace\n" + +"/IDD 8 dict def\n" + +"IDD begin\n" +"/ImageType 1 def\n" +"/Width px def\n" +"/Height py def\n" +"/BitsPerComponent 8 def\n" +"/Interpolate inter def\n" +"/DataSource currentfile /ASCIIHexDecode filter def\n" +"/MultipleDataSources false def\n" +"/ImageMatrix [ px 0 0 py neg 0 py ] def\n" + +"/Decode [ 0 1 0 1 0 1 ] def\n" +"end\n" + +"/IMD 8 dict def\n" +"IMD begin\n" +"/ImageType 1 def\n" +"/Width mx def\n" +"/Height my def\n" +"/BitsPerComponent 1 def\n" +// "/Interpolate inter def\n" +"/ImageMatrix [ mx 0 0 my neg 0 my ] def\n" +"/Decode [ 1 0 ] def\n" +"end\n" + +"<<\n" +"/ImageType 3\n" +"/InterleaveType 2\n" +"/MaskDict IMD\n" +"/DataDict IDD\n" +">> image GR\n" +"} bind def\n" + + +// masked gray images +"/GIM {GS /inter exch def /my exch def /mx exch def /py exch def /px exch def /sy exch def /sx exch def \n" +"translate \n" +"sx sy scale\n" +"/DeviceGray setcolorspace\n" + +"/IDD 8 dict def\n" + +"IDD begin\n" +"/ImageType 1 def\n" +"/Width px def\n" +"/Height py def\n" +"/BitsPerComponent 8 def\n" +"/Interpolate inter def\n" +"/DataSource currentfile /ASCIIHexDecode filter def\n" +"/MultipleDataSources false def\n" +"/ImageMatrix [ px 0 0 py neg 0 py ] def\n" + +"/Decode [ 0 1 ] def\n" +"end\n" + +"/IMD 8 dict def\n" + +"IMD begin\n" +"/ImageType 1 def\n" +"/Width mx def\n" +"/Height my def\n" +"/BitsPerComponent 1 def\n" +"/ImageMatrix [ mx 0 0 my neg 0 my ] def\n" +"/Decode [ 1 0 ] def\n" +"end\n" + +"<<\n" +"/ImageType 3\n" +"/InterleaveType 2\n" +"/MaskDict IMD\n" +"/DataDict IDD\n" +">> image GR\n" +"} bind def\n" + + +"\n" +; + +// end prolog + +int Fl_PostScript_Graphics_Driver::start_postscript (int pagecount, enum Fl_PostScript_Graphics_Driver::Page_Format format, enum Fl_PostScript_Graphics_Driver::Page_Layout layout) +//returns 0 iff OK +{ + int w, h, x; + if (format == A4) { + left_margin = 18; + top_margin = 18; + } + else { + left_margin = 12; + top_margin = 12; + } + page_format_ = (enum Page_Format)(format | layout); + + fputs("%!PS-Adobe-3.0\n", output); + fputs("%%Creator: FLTK\n", output); + if (lang_level_>1) + fprintf(output, "%%%%LanguageLevel: %i\n" , lang_level_); + if ((pages_ = pagecount)) + fprintf(output, "%%%%Pages: %i\n", pagecount); + else + fputs("%%Pages: (atend)\n", output); + fprintf(output, "%%%%BeginFeature: *PageSize %s\n", page_formats[format].name ); + w = page_formats[format].width; + h = page_formats[format].height; + if (lang_level_ == 3 && (layout & LANDSCAPE) ) { x = w; w = h; h = x; } + fprintf(output, "<>setpagedevice\n", w, h ); + fputs("%%EndFeature\n", output); + fputs("%%EndComments\n", output); + fputs(prolog, output); + if (lang_level_ > 1) { + fputs(prolog_2, output); + } + if (lang_level_ == 2) { + fputs(prolog_2_pixmap, output); + } + if (lang_level_ > 2) + fputs(prolog_3, output); + if (lang_level_ >= 3) { + fputs("/CS { clipsave } bind def\n", output); + fputs("/CR { cliprestore } bind def\n", output); + } else { + fputs("/CS { GS } bind def\n", output); + fputs("/CR { GR } bind def\n", output); + } + page_policy_ = 1; + + + fputs("%%EndProlog\n",output); + if (lang_level_ >= 2) + fprintf(output,"<< /Policies << /Pagesize 1 >> >> setpagedevice\n"); + + reset(); + nPages=0; + return 0; +} + +void Fl_PostScript_Graphics_Driver::recover(){ + color(cr_,cg_,cb_); + line_style(linestyle_,linewidth_,linedash_); + font(font_,size_); +} + +void Fl_PostScript_Graphics_Driver::reset(){ + gap_=1; + clip_=0; + cr_=cg_=cb_=0; + font_=FL_HELVETICA; + size_=12; + linewidth_=0; + linestyle_=FL_SOLID; + strcpy(linedash_,""); + Clip *c=clip_; ////just not to have memory leaks for badly writen code (forgotten clip popping) + + while(c){ + clip_=clip_->prev; + delete c; + c=clip_; + } + +} + +void Fl_PostScript_Graphics_Driver::page_policy(int p){ + page_policy_ = p; + if(lang_level_>=2) + fprintf(output,"<< /Policies << /Pagesize %i >> >> setpagedevice\n", p); +} + +// //////////////////// paging ////////////////////////////////////////// + + + +void Fl_PostScript_Graphics_Driver::page(double pw, double ph, int media) { + + if (nPages){ + fprintf(output, "CR\nGR\nGR\nGR\nSP\nrestore\n"); + } + ++nPages; + fprintf(output, "%%%%Page: %i %i\n" , nPages , nPages); + if (pw>ph){ + fprintf(output, "%%%%PageOrientation: Landscape\n"); + }else{ + fprintf(output, "%%%%PageOrientation: Portrait\n"); + } + + fprintf(output, "%%%%BeginPageSetup\n"); + if((media & MEDIA) &&(lang_level_>1)){ + int r = media & REVERSED; + if(r) r = 2; + fprintf(output, "<< /PageSize [%i %i] /Orientation %i>> setpagedevice\n", (int)(pw+.5), (int)(ph+.5), r); + } + fprintf(output, "%%%%EndPageSetup\n"); + + pw_ = pw; + ph_ = ph; + reset(); + + fprintf(output, "save\n"); + fprintf(output, "GS\n"); + fprintf(output, "%g %g TR\n", (double)0 /*lm_*/ , ph_ /* - tm_*/); + fprintf(output, "1 -1 SC\n"); + line_style(0); + fprintf(output, "GS\n"); + + if (!((media & MEDIA) &&(lang_level_>1))){ + if (pw > ph) { + if(media & REVERSED) { + fprintf(output, "-90 rotate %i 0 translate\n", int(-pw)); + } + else { + fprintf(output, "90 rotate -%i -%i translate\n", (lang_level_ == 2 ? int(pw - ph) : 0), int(ph)); + } + } + else { + if(media & REVERSED) + fprintf(output, "180 rotate %i %i translate\n", int(-pw), int(-ph)); + } + } + fprintf(output, "GS\nCS\n"); +}; + +void Fl_PostScript_Graphics_Driver::page(int format){ + + + if(format & LANDSCAPE){ + ph_=Fl_PostScript_Graphics_Driver::page_formats[format & 0xFF].width; + pw_=Fl_PostScript_Graphics_Driver::page_formats[format & 0xFF].height; + }else{ + pw_=Fl_PostScript_Graphics_Driver::page_formats[format & 0xFF].width; + ph_=Fl_PostScript_Graphics_Driver::page_formats[format & 0xFF].height; + } + page(pw_,ph_,format & 0xFF00);//,orientation only; +}; + +void Fl_PostScript_Graphics_Driver::rect(int x, int y, int w, int h) { + // Commented code does not work, i can't find the bug ;-( + // fprintf(output, "GS\n"); + // fprintf(output, "%i, %i, %i, %i R\n", x , y , w, h); + // fprintf(output, "GR\n"); + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x , y); + fprintf(output, "%i %i LT\n", x+w-1 , y); + fprintf(output, "%i %i LT\n", x+w-1 , y+h-1); + fprintf(output, "%i %i LT\n", x , y+h-1); + fprintf(output, "ECP\n"); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::rectf(int x, int y, int w, int h) { + fprintf(output, "%g %g %i %i FR\n", x-0.5, y-0.5, w, h); +} + +void Fl_PostScript_Graphics_Driver::line(int x1, int y1, int x2, int y2) { + fprintf(output, "GS\n"); + fprintf(output, "%i %i %i %i L\n", x1 , y1, x2 ,y2); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::line(int x0, int y0, int x1, int y1, int x2, int y2) { + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x0 , y0); + fprintf(output, "%i %i LT\n", x1 , y1); + fprintf(output, "%i %i LT\n", x2 , y2); + fprintf(output, "ELP\n"); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3){ + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x , y ); + fprintf(output, "%i %i LT\n", x1 , y ); + fprintf(output, "%i %i LT\n", x1 , y2); + fprintf(output,"%i %i LT\n", x3 , y2); + fprintf(output, "ELP\n"); + fprintf(output, "GR\n"); +}; + + +void Fl_PostScript_Graphics_Driver::xyline(int x, int y, int x1, int y2){ + + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x , y); + fprintf(output,"%i %i LT\n", x1 , y); + fprintf(output, "%i %i LT\n", x1 , y2 ); + fprintf(output, "ELP\n"); + fprintf(output, "GR\n"); +}; + +void Fl_PostScript_Graphics_Driver::xyline(int x, int y, int x1){ + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x , y); + fprintf(output, "%i %i LT\n", x1 , y ); + fprintf(output, "ELP\n"); + + fprintf(output, "GR\n"); +}; + +void Fl_PostScript_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3){ + fprintf(output, "GS\n"); + + fprintf(output,"BP\n"); + fprintf(output,"%i %i MT\n", x , y); + fprintf(output, "%i %i LT\n", x , y1 ); + fprintf(output, "%i %i LT\n", x2 , y1 ); + fprintf(output , "%i %i LT\n", x2 , y3); + fprintf(output, "ELP\n"); + fprintf(output, "GR\n"); +}; + +void Fl_PostScript_Graphics_Driver::yxline(int x, int y, int y1, int x2){ + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x , y); + fprintf(output, "%i %i LT\n", x , y1); + fprintf(output, "%i %i LT\n", x2 , y1); + fprintf(output, "ELP\n"); + fprintf(output, "GR\n"); +}; + +void Fl_PostScript_Graphics_Driver::yxline(int x, int y, int y1){ + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x , y); + fprintf(output, "%i %i LT\n", x , y1); + fprintf(output, "ELP\n"); + fprintf(output, "GR\n"); +}; + +void Fl_PostScript_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2) { + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x0 , y0); + fprintf(output, "%i %i LT\n", x1 , y1); + fprintf(output, "%i %i LT\n", x2 , y2); + fprintf(output, "ECP\n"); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) { + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x0 , y0); + fprintf(output, "%i %i LT\n", x1 , y1); + fprintf(output, "%i %i LT\n", x2 , y2); + fprintf(output, "%i %i LT\n", x3 , y3); + fprintf(output, "ECP\n"); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2) { + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x0 , y0); + fprintf(output,"%i %i LT\n", x1 , y1); + fprintf(output, "%i %i LT\n", x2 , y2); + fprintf(output, "EFP\n"); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) { + fprintf(output, "GS\n"); + fprintf(output,"BP\n"); + fprintf(output, "%i %i MT\n", x0 , y0 ); + fprintf(output, "%i %i LT\n", x1 , y1 ); + fprintf(output, "%i %i LT\n", x2 , y2 ); + fprintf(output, "%i %i LT\n", x3 , y3 ); + + fprintf(output, "EFP\n"); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::point(int x, int y){ + rectf(x,y,1,1); +} + +static int dashes_flat[5][7]={ +{-1,0,0,0,0,0,0}, +{3,1,-1,0,0,0,0}, +{1,1,-1,0,0,0,0}, +{3,1,1,1,-1,0,0}, +{3,1,1,1,1,1,-1} +}; + + +//yeah, hack... +static double dashes_cap[5][7]={ +{-1,0,0,0,0,0,0}, +{2,2,-1,0,0,0,0}, +{0.01,1.99,-1,0,0,0,0}, +{2,2,0.01,1.99,-1,0,0}, +{2,2,0.01,1.99,0.01,1.99,-1} +}; + + +void Fl_PostScript_Graphics_Driver::line_style(int style, int width, char* dashes){ + //line_styled_=1; + + linewidth_=width; + linestyle_=style; + //dashes_= dashes; + if(dashes){ + if(dashes != linedash_) + strcpy(linedash_,dashes); + + }else + linedash_[0]=0; + char width0 = 0; + if(!width){ + width=1; //for screen drawing compatability + width0=1; + } + + fprintf(output, "%i setlinewidth\n", width); + + if(!style && (!dashes || !(*dashes)) && width0) //system lines + style = FL_CAP_SQUARE; + + int cap = (style &0xf00) >> 8; + if(cap) cap--; + fprintf(output,"%i setlinecap\n", cap); + + int join = (style & 0xf000) >> 12; + + if(join) join--; + fprintf(output,"%i setlinejoin\n", join); + + + fprintf(output, "["); + if(dashes && *dashes){ + while(*dashes){ + fprintf(output, "%i ", *dashes); + dashes++; + } + }else{ + int * ds; + if(style & 0x200){ // round and square caps, dash length need to be adjusted + double *dt = dashes_cap[style & 0xff]; + while (*dt >= 0){ + fprintf(output, "%g ",width * (*dt)); + dt++; + } + }else{ + + ds = dashes_flat[style & 0xff]; + while (*ds >= 0){ + fprintf(output, "%i ",width * (*ds)); + ds++; + } + } + } + fprintf(output, "] 0 setdash\n"); +}; + +static const char *_fontNames[] = { +"Helvetica", +"Helvetica-Bold", +"Helvetica-Oblique", +"Helvetica-BoldOblique", +"Courier", +"Courier-Bold", +"Courier-Oblique", +"Courier-BoldOblique", +"Times", +"Times-Bold", +"Times-Italic", +"Times-BoldItalic", +"Symbol", +"Courier", +"Courier-Bold", +"ZapfDingbats" +}; + +void Fl_PostScript_Graphics_Driver::font(int f, int s) { + if (f >= FL_FREE_FONT) + f = FL_COURIER; + fprintf(output, "/%s SF\n" , _fontNames[f]); + fprintf(output,"%i FS\n", s); + Fl_Display_Device::display_device()->driver()->font(f,s); // Use display fonts for font measurement + font_ = f; size_ = s; +}; + +void Fl_PostScript_Graphics_Driver::color(Fl_Color c) { + //colored_=1; + color_=c; + Fl::get_color(c, cr_, cg_, cb_); + if (cr_==cg_ && cg_==cb_) { + double gray = cr_/255.0; + fprintf(output, "%g GL\n", gray); + + } else { + double fr, fg, fb; + fr = cr_/255.0; + fg = cg_/255.0; + fb = cb_/255.0; + fprintf(output,"%g %g %g SRGB\n", fr , fg , fb); + } +} + +void Fl_PostScript_Graphics_Driver::color(unsigned char r, unsigned char g, unsigned char b) { + //colored_=1; + cr_=r;cg_=g;cb_=b; + if (r==g && g==b) { + double gray = r/255.0; + fprintf(output, "%g GL\n", gray); + } else { + double fr, fg, fb; + fr = r/255.0; + fg = g/255.0; + fb = b/255.0; + fprintf(output, "%g %g %g SRGB\n", fr , fg , fb); + } +} + +void Fl_PostScript_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) +{ + fprintf(output, "GS %d %d translate %d rotate\n", x, y, - angle); + this->transformed_draw(str, n, 0, 0); + fprintf(output, "GR\n"); +} + +// outputs in PostScript a UTF8 string replacing non-Latin1 characters by ? +// and using the same width in points as on display +void Fl_PostScript_Graphics_Driver::transformed_draw(const char* str, int n, double x, double y) { + int len; + if (!n || !str || !*str) return; + const char *last = str + n; + // compute display width of string + fprintf(output,"%g (", fl_width(str, n)); + while (str < last) { + // Extract each unicode character of string. + // Until 0xFF, UTF codes coincide with iso-Latin1 (iso-8859-1) + unsigned utf = fl_utf8decode(str, last, &len); + str += len; + if (utf > 0xFF) { + utf = '?'; // replace non Latin-1 unicodes by ? + } + else if (utf == '(' || utf == ')' || utf == '\\') { + putc('\\' , output); // these chars need be escaped + } + putc(utf, output); // output the latin character + } + fprintf(output, ") %g %g show_pos_width\n", x, y); +} + +struct matrix {double a, b, c, d, x, y;}; +extern matrix * fl_matrix; + +void Fl_PostScript_Graphics_Driver::concat(){ + fprintf(output,"[%g %g %g %g %g %g] CT\n", fl_matrix->a , fl_matrix->b , fl_matrix->c , fl_matrix->d , fl_matrix->x , fl_matrix->y); +} + +void Fl_PostScript_Graphics_Driver::reconcat(){ + fprintf(output, "[%g %g %g %g %g %g] RCT\n" , fl_matrix->a , fl_matrix->b , fl_matrix->c , fl_matrix->d , fl_matrix->x , fl_matrix->y); +} + +///////////////// transformed (double) drawings //////////////////////////////// + + +void Fl_PostScript_Graphics_Driver::begin_points(){ + fprintf(output, "GS\n"); + concat(); + + fprintf(output, "BP\n"); + gap_=1; + shape_=POINTS; +}; + +void Fl_PostScript_Graphics_Driver::begin_line(){ + fprintf(output, "GS\n"); + concat(); + fprintf(output, "BP\n"); + gap_=1; + shape_=LINE; +}; + +void Fl_PostScript_Graphics_Driver::begin_loop(){ + fprintf(output, "GS\n"); + concat(); + fprintf(output, "BP\n"); + gap_=1; + shape_=LOOP; +}; + +void Fl_PostScript_Graphics_Driver::begin_polygon(){ + fprintf(output, "GS\n"); + concat(); + fprintf(output, "BP\n"); + gap_=1; + shape_=POLYGON; +}; + +void Fl_PostScript_Graphics_Driver::vertex(double x, double y){ + if(shape_==POINTS){ + fprintf(output,"%g %g MT\n", x , y); + gap_=1; + return; + } + if(gap_){ + fprintf(output,"%g %g MT\n", x , y); + gap_=0; + }else + fprintf(output, "%g %g LT\n", x , y); +}; + +void Fl_PostScript_Graphics_Driver::curve(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3){ + if(shape_==NONE) return; + if(gap_) + fprintf(output,"%g %g MT\n", x , y); + else + fprintf(output, "%g %g LT\n", x , y); + gap_=0; + + fprintf(output, "%g %g %g %g %g %g curveto \n", x1 , y1 , x2 , y2 , x3 , y3); +}; + + +void Fl_PostScript_Graphics_Driver::circle(double x, double y, double r){ + if(shape_==NONE){ + fprintf(output, "GS\n"); + concat(); + // fprintf(output, "BP\n"); + fprintf(output,"%g %g %g 0 360 arc\n", x , y , r); + reconcat(); + // fprintf(output, "ELP\n"); + fprintf(output, "GR\n"); + }else + + fprintf(output, "%g %g %g 0 360 arc\n", x , y , r); + +}; + +void Fl_PostScript_Graphics_Driver::arc(double x, double y, double r, double start, double a){ + if(shape_==NONE) return; + gap_=0; + if(start>a) + fprintf(output, "%g %g %g %g %g arc\n", x , y , r , -start, -a); + else + fprintf(output, "%g %g %g %g %g arcn\n", x , y , r , -start, -a); + +}; + +void Fl_PostScript_Graphics_Driver::arc(int x, int y, int w, int h, double a1, double a2) { + fprintf(output, "GS\n"); + //fprintf(output, "BP\n"); + begin_line(); + fprintf(output, "%g %g TR\n", x + w/2.0 -0.5 , y + h/2.0 - 0.5); + fprintf(output, "%g %g SC\n", (w-1)/2.0 , (h-1)/2.0 ); + arc(0,0,1,a2,a1); + // fprintf(output, "0 0 1 %g %g arc\n" , -a1 , -a2); + fprintf(output, "%g %g SC\n", 2.0/(w-1) , 2.0/(h-1) ); + fprintf(output, "%g %g TR\n", -x - w/2.0 +0.5 , -y - h/2.0 +0.5); + end_line(); + + // fprintf(output, "%g setlinewidth\n", 2/sqrt(w*h)); + // fprintf(output, "ELP\n"); + // fprintf(output, 2.0/w , 2.0/w , " SC\n"; + // fprintf(output, (-x - w/2.0) , (-y - h/2) , " TR\n"; + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::pie(int x, int y, int w, int h, double a1, double a2) { + + fprintf(output, "GS\n"); + fprintf(output, "%g %g TR\n", x + w/2.0 -0.5 , y + h/2.0 - 0.5); + fprintf(output, "%g %g SC\n", (w-1)/2.0 , (h-1)/2.0 ); + begin_polygon(); + vertex(0,0); + arc(0.0,0.0, 1, a2, a1); + end_polygon(); + fprintf(output, "GR\n"); +} + +void Fl_PostScript_Graphics_Driver::end_points(){ + gap_=1; + reconcat(); + fprintf(output, "ELP\n"); //?? + fprintf(output, "GR\n"); + shape_=NONE; +} + +void Fl_PostScript_Graphics_Driver::end_line(){ + gap_=1; + reconcat(); + fprintf(output, "ELP\n"); + fprintf(output, "GR\n"); + shape_=NONE; +} +void Fl_PostScript_Graphics_Driver::end_loop(){ + gap_=1; + reconcat(); + fprintf(output, "ECP\n"); + fprintf(output, "GR\n"); + shape_=NONE; +} + +void Fl_PostScript_Graphics_Driver::end_polygon(){ + + gap_=1; + reconcat(); + fprintf(output, "EFP\n"); + fprintf(output, "GR\n"); + shape_=NONE; +} + +void Fl_PostScript_Graphics_Driver::transformed_vertex(double x, double y){ + reconcat(); + if(gap_){ + fprintf(output, "%g %g MT\n", x , y); + gap_=0; + }else + fprintf(output, "%g %g LT\n", x , y); + concat(); +}; + +///////////////////////////// Clipping ///////////////////////////////////////////// + +void Fl_PostScript_Graphics_Driver::push_clip(int x, int y, int w, int h) { + Clip * c=new Clip(); + clip_box(x,y,w,h,c->x,c->y,c->w,c->h); + c->prev=clip_; + clip_=c; + fprintf(output, "CR\nCS\n"); + if(lang_level_<3) + recover(); + fprintf(output, "%g %g %i %i CL\n", clip_->x-0.5 , clip_->y-0.5 , clip_->w , clip_->h); + +} + +void Fl_PostScript_Graphics_Driver::push_no_clip() { + Clip * c = new Clip(); + c->prev=clip_; + clip_=c; + clip_->x = clip_->y = clip_->w = clip_->h = -1; + fprintf(output, "CR\nCS\n"); + if(lang_level_<3) + recover(); +} + +void Fl_PostScript_Graphics_Driver::pop_clip() { + if(!clip_)return; + Clip * c=clip_; + clip_=clip_->prev; + delete c; + fprintf(output, "CR\nCS\n"); + if(clip_ && clip_->w >0) + fprintf(output, "%g %g %i %i CL\n", clip_->x - 0.5, clip_->y - 0.5, clip_->w , clip_->h); + // uh, -0.5 is to match screen clipping, for floats there should be something beter + if(lang_level_<3) + recover(); +} + +int Fl_PostScript_Graphics_Driver::clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H){ + if(!clip_){ + X=x;Y=y;W=w;H=h; + return 1; + } + if(clip_->w < 0){ + X=x;Y=y;W=w;H=h; + return 1; + } + int ret=0; + if (x > (X=clip_->x)) {X=x; ret=1;} + if (y > (Y=clip_->y)) {Y=y; ret=1;} + if ((x+w) < (clip_->x+clip_->w)) { + W=x+w-X; + + ret=1; + + }else + W = clip_->x + clip_->w - X; + if(W<0){ + W=0; + return 1; + } + if ((y+h) < (clip_->y+clip_->h)) { + H=y+h-Y; + ret=1; + }else + H = clip_->y + clip_->h - Y; + if(H<0){ + W=0; + H=0; + return 1; + } + return ret; +}; + +int Fl_PostScript_Graphics_Driver::not_clipped(int x, int y, int w, int h){ + if(!clip_) return 1; + if(clip_->w < 0) return 1; + int X, Y, W, H; + clip_box(x, y, w, h, X, Y, W, H); + if(W) return 1; + return 0; +}; + + +void Fl_PostScript_File_Device::margins(int *left, int *top, int *right, int *bottom) // to implement +{ + Fl_PostScript_Graphics_Driver *ps = driver(); + if(left) *left = (int)(ps->left_margin / ps->scale_x + .5); + if(right) *right = (int)(ps->left_margin / ps->scale_x + .5); + if(top) *top = (int)(ps->top_margin / ps->scale_y + .5); + if(bottom) *bottom = (int)(ps->top_margin / ps->scale_y + .5); +} + +int Fl_PostScript_File_Device::printable_rect(int *w, int *h) +//returns 0 iff OK +{ + Fl_PostScript_Graphics_Driver *ps = driver(); + if(w) *w = (int)((ps->pw_ - 2 * ps->left_margin) / ps->scale_x + .5); + if(h) *h = (int)((ps->ph_ - 2 * ps->top_margin) / ps->scale_y + .5); + return 0; +} + +void Fl_PostScript_File_Device::origin(int x, int y) +{ + x_offset = x; + y_offset = y; + Fl_PostScript_Graphics_Driver *ps = driver(); + fprintf(ps->output, "GR GR GS %d %d TR %f %f SC %d %d TR %f rotate GS\n", + ps->left_margin, ps->top_margin, ps->scale_x, ps->scale_y, x, y, ps->angle); +} + +void Fl_PostScript_File_Device::scale (float s_x, float s_y) +{ + Fl_PostScript_Graphics_Driver *ps = driver(); + ps->scale_x = s_x; + ps->scale_y = s_y; + fprintf(ps->output, "GR GR GS %d %d TR %f %f SC %f rotate GS\n", + ps->left_margin, ps->top_margin, ps->scale_x, ps->scale_y, ps->angle); +} + +void Fl_PostScript_File_Device::rotate (float rot_angle) +{ + Fl_PostScript_Graphics_Driver *ps = driver(); + ps->angle = - rot_angle; + fprintf(ps->output, "GR GR GS %d %d TR %f %f SC %d %d TR %f rotate GS\n", + ps->left_margin, ps->top_margin, ps->scale_x, ps->scale_y, x_offset, y_offset, ps->angle); +} + +void Fl_PostScript_File_Device::translate(int x, int y) +{ + fprintf(driver()->output, "GS %d %d translate GS\n", x, y); +} + +void Fl_PostScript_File_Device::untranslate(void) +{ + fprintf(driver()->output, "GR GR\n"); +} + +int Fl_PostScript_File_Device::start_page (void) +{ + Fl_PostScript_Graphics_Driver *ps = driver(); + ps->page(ps->page_format_); + x_offset = 0; + y_offset = 0; + ps->scale_x = ps->scale_y = 1.; + ps->angle = 0; + fprintf(ps->output, "GR GR GS %d %d translate GS\n", ps->left_margin, ps->top_margin); + return 0; +} + +int Fl_PostScript_File_Device::end_page (void) +{ + return 0; +} + +void Fl_PostScript_File_Device::end_job (void) +// finishes PostScript & closes file +{ + Fl_PostScript_Graphics_Driver *ps = driver(); + if (ps->nPages) { // for eps nPages is 0 so it is fine .... + fprintf(ps->output, "CR\nGR\nGR\nGR\nSP\n restore\n"); + if (!ps->pages_){ + fprintf(ps->output, "%%%%Trailer\n"); + fprintf(ps->output, "%%%%Pages: %i\n" , ps->nPages); + }; + } else + fprintf(ps->output, "GR\n restore\n"); + fputs("%%EOF",ps->output); + ps->reset(); + fflush(ps->output); + if(ferror(ps->output)) { + fl_alert ("Error during PostScript data output."); + } +#if ! (defined(__APPLE__) || defined(WIN32) ) + if (print_pipe) + pclose(ps->output); + else + fclose(ps->output); +#else + fclose(ps->output); +#endif + while (ps->clip_){ + Fl_PostScript_Graphics_Driver::Clip * c= ps->clip_; + ps->clip_= ps->clip_->prev; + delete c; + } + if (ps->close_cmd_) (*ps->close_cmd_)(ps->output); + Fl_Display_Device::display_device()->set_current(); +} + +#if ! (defined(__APPLE__) || defined(WIN32) ) +int Fl_Printer::start_job(int pages, int *firstpage, int *lastpage) { + enum Fl_PostScript_Graphics_Driver::Page_Format format; + enum Fl_PostScript_Graphics_Driver::Page_Layout layout; + + // first test version for print dialog + if (!print_panel) make_print_panel(); + print_load(); + print_selection->deactivate(); + print_all->setonly(); + print_all->do_callback(); + print_from->value("1"); + { char tmp[10]; snprintf(tmp, sizeof(tmp), "%d", pages); print_to->value(tmp); } + print_panel->show(); // this is modal + while (print_panel->shown()) Fl::wait(); + + if (!print_start) // user clicked cancel + return 1; + + // get options + + format = print_page_size->value() ? Fl_PostScript_Graphics_Driver::A4 : Fl_PostScript_Graphics_Driver::LETTER; + { // page range choice + int from = 1, to = pages; + if (print_pages->value()) { + sscanf(print_from->value(), "%d", &from); + sscanf(print_to->value(), "%d", &to); + } + if (from < 1) from = 1; + if (to > pages) to = pages; + if (to < from) to = from; + if (firstpage) *firstpage = from; + if (lastpage) *lastpage = to; + pages = to - from + 1; + } + + if (print_output_mode[0]->value()) layout = Fl_PostScript_Graphics_Driver::PORTRAIT; + else if (print_output_mode[1]->value()) layout = Fl_PostScript_Graphics_Driver::LANDSCAPE; + else if (print_output_mode[2]->value()) layout = Fl_PostScript_Graphics_Driver::PORTRAIT; + else layout = Fl_PostScript_Graphics_Driver::LANDSCAPE; + + print_pipe = print_choice->value(); // 0 = print to file, >0 = printer (pipe) + + const char *media = print_page_size->text(print_page_size->value()); + const char *printer = (const char *)print_choice->menu()[print_choice->value()].user_data(); + if (!print_pipe) printer = ""; + + if (!print_pipe) // fall back to file printing + return Fl_PostScript_File_Device::start_job (pages, format, layout); + + // Print: pipe the output into the lp command... + + char command[1024]; + snprintf(command, sizeof(command), "lp -s -d %s -n %d -t '%s' -o media=%s", + printer, print_collate_button->value() ? 1 : (int)(print_copies->value() + 0.5), + "FLTK", media); + + Fl_PostScript_Graphics_Driver *ps = driver(); + ps->output = popen(command, "w"); + if (!ps->output) { + fl_alert("could not run command: %s\n",command); + return 1; + } + this->set_current(); + return ps->start_postscript(pages, format, layout); // start printing +} + +#endif // ! (defined(__APPLE__) || defined(WIN32) ) + +#endif // FL_DOXYGEN + +// +// End of "$Id: Fl_PostScript.cxx 7653 2010-06-24 08:55:04Z manolo $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Preferences.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Preferences.cxx index e1ab87d3f..f01122478 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Preferences.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Preferences.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Preferences.cxx 6716 2009-03-24 01:40:44Z fabien $" +// "$Id: Fl_Preferences.cxx 7672 2010-07-10 09:44:45Z matt $" // // Preferences methods for the Fast Light Tool Kit (FLTK). // @@ -25,9 +25,10 @@ // http://www.fltk.org/str.php // - #include #include +#include +#include #include #include @@ -36,8 +37,10 @@ #include #include "flstring.h" #include +#include #if defined(WIN32) && !defined(__CYGWIN__) +# include # include # include // Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs @@ -47,15 +50,141 @@ #elif defined (__APPLE__) # include # include +# include #else # include +# include #endif #ifdef WIN32 -#include +# include +# include +// function pointer for the UuidCreate Function +// RPC_STATUS RPC_ENTRY UuidCreate(UUID __RPC_FAR *Uuid); +typedef RPC_STATUS (WINAPI* uuid_func)(UUID __RPC_FAR *Uuid); +#else +# include #endif // WIN32 +#ifdef __CYGWIN__ +# include +#endif + char Fl_Preferences::nameBuffer[128]; +char Fl_Preferences::uuidBuffer[40]; +Fl_Preferences *Fl_Preferences::runtimePrefs = 0; + +/** + * Returns a UUID as generated by the system. + * + * A UUID is a "universally unique identifier" which is commonly used in + * configuration files to create identities. A UUID in ASCII looks like this: + * 937C4900-51AA-4C11-8DD3-7AB59944F03E. It has always 36 bytes plus + * a trailing zero. + * + * \return a pointer to a static buffer containing the new UUID in ASCII format. + * The buffer is overwritten during every call to this function! + */ +const char *Fl_Preferences::newUUID() +{ +#ifdef __APPLE__ + CFUUIDRef theUUID = CFUUIDCreate(NULL); + CFUUIDBytes b = CFUUIDGetUUIDBytes(theUUID); + sprintf(uuidBuffer, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", + b.byte0, b.byte1, b.byte2, b.byte3, b.byte4, b.byte5, b.byte6, b.byte7, + b.byte8, b.byte9, b.byte10, b.byte11, b.byte12, b.byte13, b.byte14, b.byte15); + CFRelease(theUUID); +#elif defined (WIN32) + // First try and use the win API function UuidCreate(), but if that is not + // available, fall back to making something up from scratch. + // We do not want to link against the Rpcrt4.dll, as we will rarely use it, + // so we load the DLL dynamically, if it is available, and work from there. + static HMODULE hMod = NULL; + UUID ud; + UUID *pu = &ud; + int got_uuid = 0; + + if(!hMod){ // first time in? + hMod = LoadLibrary("Rpcrt4.dll"); + } + + if(hMod){ // do we have a usable handle to Rpcrt4.dll? + uuid_func uuid_crt = (uuid_func)GetProcAddress(hMod, "UuidCreate"); + if(uuid_crt != NULL) { + RPC_STATUS rpc_res = uuid_crt(pu); + if( // is the return status OK for our needs? + (rpc_res == RPC_S_OK) || // all is well + (rpc_res == RPC_S_UUID_LOCAL_ONLY) || // only unique to this machine + (rpc_res == RPC_S_UUID_NO_ADDRESS) // probably only locally unique + ) { + got_uuid = -1; + sprintf(uuidBuffer, "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + pu->Data1, pu->Data2, pu->Data3, pu->Data4[0], pu->Data4[1], + pu->Data4[2], pu->Data4[3], pu->Data4[4], + pu->Data4[5], pu->Data4[6], pu->Data4[7]); + } + } + } + if(got_uuid == 0) { // did not make a UUID - use fallback logic + unsigned char b[16]; + time_t t = time(0); // first 4 byte + b[0] = (unsigned char)t; + b[1] = (unsigned char)(t>>8); + b[2] = (unsigned char)(t>>16); + b[3] = (unsigned char)(t>>24); + int r = rand(); // four more bytes + b[4] = (unsigned char)r; + b[5] = (unsigned char)(r>>8); + b[6] = (unsigned char)(r>>16); + b[7] = (unsigned char)(r>>24); + unsigned int a = (unsigned int)&t; // four more bytes + b[8] = (unsigned char)a; + b[9] = (unsigned char)(a>>8); + b[10] = (unsigned char)(a>>16); + b[11] = (unsigned char)(a>>24); + TCHAR name[MAX_COMPUTERNAME_LENGTH + 1]; // only used to make last four bytes + DWORD nSize = MAX_COMPUTERNAME_LENGTH + 1; + // GetComputerName() does not depend on any extra libs, and returns something + // analogous to gethostname() + GetComputerName(name, &nSize); + // use the first 4 TCHAR's of the name to create the last 4 bytes of our UUID + for(int ii = 0; ii < 4; ii++){ + b[12 + ii] = (unsigned char)name[ii]; + } + sprintf(uuidBuffer, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", + b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], + b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]); + } +#else +#warning Unix implementation incomplete! + // #include + // void uuid_generate(uuid_t out); + unsigned char b[16]; + time_t t = time(0); // first 4 byte + b[0] = (unsigned char)t; + b[1] = (unsigned char)(t>>8); + b[2] = (unsigned char)(t>>16); + b[3] = (unsigned char)(t>>24); + int r = rand(); // four more bytes + b[4] = (unsigned char)r; + b[5] = (unsigned char)(r>>8); + b[6] = (unsigned char)(r>>16); + b[7] = (unsigned char)(r>>24); + unsigned long a = (unsigned long)&t; // four more bytes + b[8] = (unsigned char)a; + b[9] = (unsigned char)(a>>8); + b[10] = (unsigned char)(a>>16); + b[11] = (unsigned char)(a>>24); + char name[80]; // last four bytes + gethostname(name, 79); + memcpy(b+12, name, 4); + sprintf(uuidBuffer, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", + b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], + b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]); +#endif + + return uuidBuffer; +} /** @@ -63,7 +192,7 @@ char Fl_Preferences::nameBuffer[128]; child groups. Groups are ready for reading and writing at any time. The root argument is either Fl_Preferences::USER or Fl_Preferences::SYSTEM. - + This constructor creates the base instance for all following entries and reads existing databases into memory. The vendor argument is a unique text string identifying the @@ -74,8 +203,13 @@ char Fl_Preferences::nameBuffer[128]; name of your application. Both vendor and application must be valid relative UNIX pathnames and may contain '/'s to create deeper file structures. - - \param[in] root can be \c USER or \c SYSTEM for user specific or system wide preferences + + A set of Preferences marked "run-time" exists exactly one per application and + only as long as the application runs. It can be used as a database for + volatile information. FLTK uses it to register plugins at run-time. + + \param[in] root can be \c USER or \c SYSTEM for user specific or system wide + preferences \param[in] vendor unique text describing the company or author of this file \param[in] application unique text describing the application */ @@ -83,17 +217,18 @@ Fl_Preferences::Fl_Preferences( Root root, const char *vendor, const char *appli { node = new Node( "." ); rootNode = new RootNode( this, root, vendor, application ); + node->setRoot(rootNode); } /** \brief Use this constructor to create or read a preferences file at an - arbitrary position in the file system. + arbitrary position in the file system. The file name is generated in the form path/application.prefs. If \p application is \c NULL, \p path must contain the full file name. - + \param[in] path path to the directory that contains the preferences file \param[in] vendor unique text describing the company or author of this file \param[in] application unique text describing the application @@ -102,15 +237,16 @@ Fl_Preferences::Fl_Preferences( const char *path, const char *vendor, const char { node = new Node( "." ); rootNode = new RootNode( this, path, vendor, application ); + node->setRoot(rootNode); } /** - \brief Generate or read a new group of entries within another group. + \brief Generate or read a new group of entries within another group. Use the \p group argument to name the group that you would like to access. \p Group can also contain a path to a group further down the hierarchy by - separating group names with a forward slash '/'. + separating group names with a forward slash '/'. \param[in] parent reference object for the new group \param[in] group name of the group to access (may contain '/'s) @@ -123,15 +259,106 @@ Fl_Preferences::Fl_Preferences( Fl_Preferences &parent, const char *group ) /** + \brief Create or access a group of preferences using a name. + \param[in] parent the parameter parent is a pointer to the parent group. + \p Parent may be \p NULL. It then refers to an application internal + database which exists only once, and remains in RAM only until the + application quits. This database is used to manage plugins and other + data indexes by strings. + \param[in] group a group name that is used as a key into the database \see Fl_Preferences( Fl_Preferences&, const char *group ) */ Fl_Preferences::Fl_Preferences( Fl_Preferences *parent, const char *group ) { + if (parent==0) { + if (!runtimePrefs) { + runtimePrefs = new Fl_Preferences(); + runtimePrefs->node = new Node( "." ); + runtimePrefs->rootNode = new RootNode( runtimePrefs ); + runtimePrefs->node->setRoot(rootNode); + } + parent = runtimePrefs; + } rootNode = parent->rootNode; node = parent->node->addChild( group ); } +/** + \brief Open a child group using a given index. + + Use the \p groupIndex argument to find the group that you would like to access. + If the given index is invalid (negative or too high), a new group is created + with a UUID as a name. + + The index needs to be fixed. It is currently backward. Index 0 points + to the last member in the 'list' of preferences. + + \param[in] parent reference object for the new group + \param[in] groupIndex zero based index into child groups + */ +Fl_Preferences::Fl_Preferences( Fl_Preferences &parent, int groupIndex ) +{ + rootNode = parent.rootNode; + if (groupIndex<0 || groupIndex>=parent.groups()) { + node = parent.node->addChild( newUUID() ); + } else { + node = parent.node->childNode( groupIndex ); + } +} + + +/** + \see Fl_Preferences( Fl_Preferences&, int groupIndex ) + */ +Fl_Preferences::Fl_Preferences( Fl_Preferences *parent, int groupIndex ) +{ + rootNode = parent->rootNode; + if (groupIndex<0 || groupIndex>=parent->groups()) { + node = parent->node->addChild( newUUID() ); + } else { + node = parent->node->childNode( groupIndex ); + } +} + + +/** + Create a new dataset access point using a dataset ID. + + ID's are a great way to remember shortcuts to database entries that are deeply + nested in a preferences database, as long as the database root is not deleted. + An ID can be retrieved from any Fl_Preferences dataset, and can then be used + to create multiple new references to the same dataset. + + ID's can be put very helpful when put into the user_data() field of + widget callbacks. + */ +Fl_Preferences::Fl_Preferences( Fl_Preferences::ID id ) +{ + node = (Node*)id; + rootNode = node->findRoot(); +} + +/** + Create another reference to a Preferences group. + */ +Fl_Preferences::Fl_Preferences(const Fl_Preferences &rhs) +: node(rhs.node), + rootNode(rhs.rootNode) +{ } + +/** + Assign another reference to a Preference group. + */ +Fl_Preferences &Fl_Preferences::operator=(const Fl_Preferences &rhs) { + if (&rhs != this) { + node = rhs.node; + rootNode = rhs.rootNode; + } + return *this; +} + + /** The destructor removes allocated resources. When used on the \em base preferences group, the destructor flushes all @@ -154,7 +381,7 @@ Fl_Preferences::~Fl_Preferences() /** Returns the number of groups that are contained within a group. - + \return 0 for no groups at all */ int Fl_Preferences::groups() @@ -167,7 +394,7 @@ int Fl_Preferences::groups() Returns the name of the Nth (\p num_group) group. There is no guaranteed order of group names. The index must be within the range given by groups(). - + \param[in] num_group number indexing the requested group \return 'C' string pointer to the group name */ @@ -182,7 +409,7 @@ const char *Fl_Preferences::group( int num_group ) Group names are relative to the Preferences node and can contain a path. "." describes the current node, "./" describes the topmost node. By preceding a groupname with a "./", its path becomes relative to the topmost node. - + \param[in] key name of group that is searched for \return 0 if no group by that name was found */ @@ -197,7 +424,7 @@ char Fl_Preferences::groupExists( const char *key ) Removes a group and all keys and groups within that group from the database. - + \param[in] group name of the group to delete \return 0 if call failed */ @@ -208,15 +435,23 @@ char Fl_Preferences::deleteGroup( const char *group ) return 0; } +/** + Delete all groups. + */ +char Fl_Preferences::deleteAllGroups() +{ + node->deleteAllChildren(); + return 1; +} /** Returns the number of entries (name/value pairs) in a group. - + \return number of entries */ int Fl_Preferences::entries() { - return node->nEntry; + return node->nEntry(); } @@ -224,19 +459,19 @@ int Fl_Preferences::entries() Returns the name of an entry. There is no guaranteed order of entry names. The index must be within the range given by entries(). - + \param[in] index number indexing the requested entry \return pointer to value cstring */ const char *Fl_Preferences::entry( int index ) { - return node->entry[index].name; + return node->entry(index).name; } /** Returns non-zero if an entry with this name exists. - + \param[in] key name of entry that is searched for \return 0 if entry was not found */ @@ -248,9 +483,9 @@ char Fl_Preferences::entryExists( const char *key ) /** Deletes a single name/value pair. - + This function removes the entry \p key from the database. - + \param[in] key name of entry to delete \return 0 if deleting the entry failed */ @@ -259,16 +494,34 @@ char Fl_Preferences::deleteEntry( const char *key ) return node->deleteEntry( key ); } +/** + Delete all entries. + */ +char Fl_Preferences::deleteAllEntries() +{ + node->deleteAllEntries(); + return 1; +} + +/** + Delete all groups and all entries. + */ +char Fl_Preferences::clear() +{ + char ret1 = deleteAllGroups(); + char ret2 = deleteAllEntries(); + return ret1 & ret2; +} /** Reads an entry from the group. A default value must be supplied. The return value indicates if the value was available (non-zero) or the default was used (0). - + \param[in] key name of entry \param[out] value returned from preferences or default value if none was set \param[in] defaultValue default value to be used if no preference was set - \return 0 if the default value was used + \return 0 if the default value was used */ char Fl_Preferences::get( const char *key, int &value, int defaultValue ) { @@ -278,12 +531,12 @@ char Fl_Preferences::get( const char *key, int &value, int defaultValue ) } -/** +/** Sets an entry (name/value pair). The return value indicates if there was a problem storing the data in memory. However it does not reflect if the value was actually stored in the preferences file. - + \param[in] key name of entry \param[in] value set this entry to \p value \return 0 if setting the value failed @@ -299,12 +552,12 @@ char Fl_Preferences::set( const char *key, int value ) /** Reads an entry from the group. A default value must be supplied. The return value indicates if the value was available - (non-zero) or the default was used (0). - + (non-zero) or the default was used (0). + \param[in] key name of entry \param[out] value returned from preferences or default value if none was set \param[in] defaultValue default value to be used if no preference was set - \return 0 if the default value was used + \return 0 if the default value was used */ char Fl_Preferences::get( const char *key, float &value, float defaultValue ) { @@ -314,12 +567,12 @@ char Fl_Preferences::get( const char *key, float &value, float defaultValue ) } -/** +/** Sets an entry (name/value pair). The return value indicates if there was a problem storing the data in memory. However it does not reflect if the value was actually stored in the preferences file. - + \param[in] key name of entry \param[in] value set this entry to \p value \return 0 if setting the value failed @@ -332,12 +585,12 @@ char Fl_Preferences::set( const char *key, float value ) } -/** +/** Sets an entry (name/value pair). The return value indicates if there was a problem storing the data in memory. However it does not reflect if the value was actually stored in the preferences file. - + \param[in] key name of entry \param[in] value set this entry to \p value \param[in] precision number of decimal digits to represent value @@ -354,12 +607,12 @@ char Fl_Preferences::set( const char *key, float value, int precision ) /** Reads an entry from the group. A default value must be supplied. The return value indicates if the value was available - (non-zero) or the default was used (0). - + (non-zero) or the default was used (0). + \param[in] key name of entry \param[out] value returned from preferences or default value if none was set \param[in] defaultValue default value to be used if no preference was set - \return 0 if the default value was used + \return 0 if the default value was used */ char Fl_Preferences::get( const char *key, double &value, double defaultValue ) { @@ -369,12 +622,12 @@ char Fl_Preferences::get( const char *key, double &value, double defaultValue ) } -/** +/** Sets an entry (name/value pair). The return value indicates if there was a problem storing the data in memory. However it does not reflect if the value was actually stored in the preferences file. - + \param[in] key name of entry \param[in] value set this entry to \p value \return 0 if setting the value failed @@ -387,12 +640,12 @@ char Fl_Preferences::set( const char *key, double value ) } -/** +/** Sets an entry (name/value pair). The return value indicates if there was a problem storing the data in memory. However it does not reflect if the value was actually stored in the preferences file. - + \param[in] key name of entry \param[in] value set this entry to \p value \param[in] precision number of decimal digits to represent value @@ -439,15 +692,15 @@ static char *decodeText( const char *src ) /** Reads an entry from the group. A default value must be supplied. The return value indicates if the value was available - (non-zero) or the default was used (0). - 'maxSize' is the maximum length of text that will be read. + (non-zero) or the default was used (0). + 'maxSize' is the maximum length of text that will be read. The text buffer must allow for one additional byte for a trailling zero. - + \param[in] key name of entry \param[out] text returned from preferences or default value if none was set \param[in] defaultValue default value to be used if no preference was set \param[in] maxSize maximum length of value plus one byte for a trailing zero - \return 0 if the default value was used + \return 0 if the default value was used */ char Fl_Preferences::get( const char *key, char *text, const char *defaultValue, int maxSize ) { @@ -469,13 +722,13 @@ char Fl_Preferences::get( const char *key, char *text, const char *defaultValue, Reads an entry from the group. A default value must be supplied. The return value indicates if the value was available (non-zero) or the default was used (0). get() allocates memory of - sufficient size to hold the value. The buffer must be free'd by - the developer using 'free(value)'. - + sufficient size to hold the value. The buffer must be free'd by + the developer using 'free(value)'. + \param[in] key name of entry \param[out] text returned from preferences or default value if none was set \param[in] defaultValue default value to be used if no preference was set - \return 0 if the default value was used + \return 0 if the default value was used */ char Fl_Preferences::get( const char *key, char *&text, const char *defaultValue ) { @@ -484,7 +737,7 @@ char Fl_Preferences::get( const char *key, char *&text, const char *defaultValue { text = decodeText( v ); return 1; - } + } if ( !v ) v = defaultValue; if ( v ) text = strdup( v ); @@ -495,12 +748,12 @@ char Fl_Preferences::get( const char *key, char *&text, const char *defaultValue -/** +/** Sets an entry (name/value pair). The return value indicates if there was a problem storing the data in memory. However it does not reflect if the value was actually stored in the preferences file. - + \param[in] key name of entry \param[in] text set this entry to \p value \return 0 if setting the value failed @@ -513,13 +766,13 @@ char Fl_Preferences::set( const char *key, const char *text ) if ( ns ) { char *buffer = (char*)malloc( n+ns+1 ), *d = buffer; - for ( s=text; *s; ) - { + for ( s=text; *s; ) + { char c = *s; if ( c=='\\' ) { *d++ = '\\'; *d++ = '\\'; s++; } else if ( c=='\n' ) { *d++ = '\\'; *d++ = 'n'; s++; } else if ( c=='\r' ) { *d++ = '\\'; *d++ = 'r'; s++; } - else if ( c<32 || c==0x7f ) + else if ( c<32 || c==0x7f ) { *d++ = '\\'; *d++ = '0'+((c>>6)&3); *d++ = '0'+((c>>3)&7); *d++ = '0'+(c&7); s++; } else *d++ = *s++; } @@ -559,16 +812,16 @@ static void *decodeHex( const char *src, int &size ) /** Reads an entry from the group. A default value must be supplied. The return value indicates if the value was available - (non-zero) or the default was used (0). - 'maxSize' is the maximum length of text that will be read. - + (non-zero) or the default was used (0). + 'maxSize' is the maximum length of text that will be read. + \param[in] key name of entry \param[out] data value returned from preferences or default value if none was set \param[in] defaultValue default value to be used if no preference was set \param[in] defaultSize size of default value array \param[in] maxSize maximum length of value - \return 0 if the default value was used - + \return 0 if the default value was used + \todo maxSize should receive the number of bytes that were read. */ char Fl_Preferences::get( const char *key, void *data, const void *defaultValue, int defaultSize, int maxSize ) @@ -581,7 +834,7 @@ char Fl_Preferences::get( const char *key, void *data, const void *defaultValue, memmove( data, w, dsize>maxSize?maxSize:dsize ); free( w ); return 1; - } + } if ( defaultValue ) memmove( data, defaultValue, defaultSize>maxSize?maxSize:defaultSize ); return 0; @@ -592,14 +845,14 @@ char Fl_Preferences::get( const char *key, void *data, const void *defaultValue, Reads an entry from the group. A default value must be supplied. The return value indicates if the value was available (non-zero) or the default was used (0). get() allocates memory of - sufficient size to hold the value. The buffer must be free'd by - the developer using 'free(value)'. - + sufficient size to hold the value. The buffer must be free'd by + the developer using 'free(value)'. + \param[in] key name of entry \param[out] data returned from preferences or default value if none was set \param[in] defaultValue default value to be used if no preference was set \param[in] defaultSize size of default value array - \return 0 if the default value was used + \return 0 if the default value was used */ char Fl_Preferences::get( const char *key, void *&data, const void *defaultValue, int defaultSize ) { @@ -609,7 +862,7 @@ char Fl_Preferences::get( const char *key, void *&data, const void *defaultValue int dsize; data = decodeHex( v, dsize ); return 1; - } + } if ( defaultValue ) { data = (void*)malloc( defaultSize ); @@ -621,12 +874,12 @@ char Fl_Preferences::get( const char *key, void *&data, const void *defaultValue } -/** +/** Sets an entry (name/value pair). The return value indicates if there was a problem storing the data in memory. However it does not reflect if the value was actually stored in the preferences file. - + \param[in] key name of entry \param[in] data set this entry to \p value \param[in] dsize size of data array @@ -652,7 +905,7 @@ char Fl_Preferences::set( const char *key, const void *data, int dsize ) /** Returns the size of the value part of an entry. - + \param[in] key name of entry \return size of value */ @@ -666,11 +919,11 @@ int Fl_Preferences::size( const char *key ) /** \brief Creates a path that is related to the preferences file and that is usable for additional application data. - + This function creates a directory that is named after the preferences database without the \c .prefs extension and located in the same directory. It then fills the given buffer with the complete path name. - + Exmaple: \code Fl_Preferences prefs( USER, "matthiasm.com", "test" ); @@ -685,7 +938,7 @@ int Fl_Preferences::size( const char *key ) \code c:/Documents and Settings/matt/Application Data/matthiasm.com/test/ \endcode - + \param[out] path buffer for user data path \param[in] pathlen size of path buffer (should be at least \c FL_PATH_MAX) \return 0 if path was not created or pathname can't fit into buffer @@ -714,9 +967,9 @@ void Fl_Preferences::flush() /** Creates a group name or entry name on the fly. - + This version creates a simple unsigned integer as an entry name. - + \code int n, i; Fl_Preferences prev( appPrefs, "PreviousFiles" ); @@ -733,9 +986,9 @@ Fl_Preferences::Name::Name( unsigned int n ) /** Creates a group name or entry name on the fly. - + This version creates entry names as in 'printf'. - + \code int n, i; Fl_Preferences prefs( USER, "matthiasm.com", "test" ); @@ -806,6 +1059,10 @@ static void makePathForFile( const char *path ) // create the root node // - construct the name of the file that will hold our preferences Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs, Root root, const char *vendor, const char *application ) +: prefs_(prefs), + filename_(0L), + vendor_(0L), + application_(0L) { char filename[ FL_PATH_MAX ]; filename[0] = 0; #ifdef WIN32 @@ -853,38 +1110,38 @@ Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs, Root root, const char } -#ifndef __CYGWIN__ - if (!filename[1] && !filename[0]) { + if (!filename[1] && !filename[0]) { strcpy(filename, "C:\\FLTK"); - } else { - xchar *b = (xchar*)_wcsdup((xchar*)filename); -// filename[fl_unicode2utf(b, wcslen((xchar*)b), filename)] = 0; - unsigned len = fl_utf8fromwc(filename, (FL_PATH_MAX-1), b, wcslen((xchar*)b)); - filename[len] = 0; - free(b); - } + } else { +#if 0 + xchar *b = (xchar*)_wcsdup((xchar *)filename); #else - if (!filename[0]) strcpy(filename, "C:\\FLTK"); + // cygwin does not come with _wcsdup. Use malloc + wcscpy. + // For implementation of wcsdup functionality See + // - http://linenum.info/p/glibc/2.7/wcsmbs/wcsdup.c + xchar *b = (xchar*) malloc((wcslen((xchar *) filename) + 1) * sizeof(xchar)); + wcscpy(b, (xchar *) filename); #endif + // filename[fl_unicode2utf(b, wcslen((xchar*)b), filename)] = 0; + unsigned len = fl_utf8fromwc(filename, (FL_PATH_MAX-1), b, wcslen(b)); + filename[len] = 0; + free(b); + } snprintf(filename + strlen(filename), sizeof(filename) - strlen(filename), "/%s/%s.prefs", vendor, application); for (char *s = filename; *s; s++) if (*s == '\\') *s = '/'; #elif defined ( __APPLE__ ) - FSSpec spec = { 0 }; - FSRef ref; - OSErr err = fnfErr; + // TODO: verify that this is the Apple sanctioned way of finding these folders + // (On MSWindows, this frequently leads to issues with internationalized systems) + // Carbon: err = FindFolder( kLocalDomain, kPreferencesFolderType, 1, &spec.vRefNum, &spec.parID ); switch (root) { case SYSTEM: - err = FindFolder( kLocalDomain, kPreferencesFolderType, - 1, &spec.vRefNum, &spec.parID ); + strcpy(filename, "/Library/Preferences"); break; case USER: - err = FindFolder( kUserDomain, kPreferencesFolderType, - 1, &spec.vRefNum, &spec.parID ); + sprintf(filename, "%s/Library/Preferences", fl_getenv("HOME")); break; } - FSpMakeFSRef( &spec, &ref ); - FSRefMakePath( &ref, (UInt8*)filename, FL_PATH_MAX ); snprintf(filename + strlen(filename), sizeof(filename) - strlen(filename), "/%s/%s.prefs", vendor, application ); #else @@ -911,7 +1168,6 @@ Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs, Root root, const char "%s/%s.prefs", vendor, application); #endif - prefs_ = prefs; filename_ = strdup(filename); vendor_ = strdup(vendor); application_ = strdup(application); @@ -922,6 +1178,10 @@ Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs, Root root, const char // create the root node // - construct the name of the file that will hold our preferences Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs, const char *path, const char *vendor, const char *application ) +: prefs_(prefs), + filename_(0L), + vendor_(0L), + application_(0L) { if (!vendor) vendor = "unknown"; @@ -933,19 +1193,28 @@ Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs, const char *path, con snprintf(filename, sizeof(filename), "%s/%s.prefs", path, application); filename_ = strdup(filename); } - prefs_ = prefs; vendor_ = strdup(vendor); application_ = strdup(application); read(); } +// create a root node that exists only on RAM and can not be read or written to +// a file +Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs ) +: prefs_(prefs), + filename_(0L), + vendor_(0L), + application_(0L) +{ +} + // destroy the root node and all depending nodes Fl_Preferences::RootNode::~RootNode() { if ( prefs_->node->dirty() ) write(); - if ( filename_ ) { + if ( filename_ ) { free( filename_ ); filename_ = 0L; } @@ -964,9 +1233,14 @@ Fl_Preferences::RootNode::~RootNode() // read a preferences file and construct the group tree and with all entry leafs int Fl_Preferences::RootNode::read() { + if (!filename_) // RUNTIME preferences + return -1; + char buf[1024]; FILE *f = fl_fopen( filename_, "rb" ); - if ( !f ) return 0; + if ( !f ) + return -1; + fgets( buf, 1024, f ); fgets( buf, 1024, f ); fgets( buf, 1024, f ); @@ -980,7 +1254,7 @@ int Fl_Preferences::RootNode::read() buf[ end+1 ] = 0; nd = prefs_->node->find( buf+1 ); } - else if ( buf[0]=='+' ) // + else if ( buf[0]=='+' ) // { // value of previous name/value pair spans multiple lines int end = strcspn( buf+1, "\n\r" ); if ( end != 0 ) // if entry is not empty @@ -1006,9 +1280,14 @@ int Fl_Preferences::RootNode::read() // write the group tree and all entry leafs int Fl_Preferences::RootNode::write() { + if (!filename_) // RUNTIME preferences + return -1; + fl_make_path_for_file(filename_); FILE *f = fl_fopen( filename_, "wb" ); - if ( !f ) return 1; + if ( !f ) + return -1; + fprintf( f, "; FLTK preferences file format 1.0\n" ); fprintf( f, "; vendor: %s\n", vendor_ ); fprintf( f, "; application: %s\n", application_ ); @@ -1020,6 +1299,9 @@ int Fl_Preferences::RootNode::write() // get the path to the preferences directory char Fl_Preferences::RootNode::getPath( char *path, int pathlen ) { + if (!filename_) // RUNTIME preferences + return -1; + strlcpy( path, filename_, pathlen); char *s; @@ -1038,13 +1320,16 @@ Fl_Preferences::Node::Node( const char *path ) { if ( path ) path_ = strdup( path ); else path_ = 0; child_ = 0; next_ = 0; parent_ = 0; - entry = 0; - nEntry = NEntry = 0; + entry_ = 0; + nEntry_ = NEntry_ = 0; dirty_ = 0; + top_ = 0; + indexed_ = 0; + index_ = 0; + nIndex_ = NIndex_ = 0; } -// delete this and all depending nodes -Fl_Preferences::Node::~Node() +void Fl_Preferences::Node::deleteAllChildren() { Node *nx; for ( Node *nd = child_; nd; nd = nx ) @@ -1053,23 +1338,39 @@ Fl_Preferences::Node::~Node() delete nd; } child_ = 0L; - if ( entry ) + dirty_ = 1; + updateIndex(); +} + +void Fl_Preferences::Node::deleteAllEntries() +{ + if ( entry_ ) { - for ( int i = 0; i < nEntry; i++ ) + for ( int i = 0; i < nEntry_; i++ ) { - if ( entry[i].name ) { - free( entry[i].name ); - entry[i].name = 0L; + if ( entry_[i].name ) { + free( entry_[i].name ); + entry_[i].name = 0L; } - if ( entry[i].value ) { - free( entry[i].value ); - entry[i].value = 0L; + if ( entry_[i].value ) { + free( entry_[i].value ); + entry_[i].value = 0L; } } - free( entry ); - entry = 0L; - nEntry = 0; + free( entry_ ); + entry_ = 0L; + nEntry_ = 0; + NEntry_ = 0; } + dirty_ = 1; +} + +// delete this and all depending nodes +Fl_Preferences::Node::~Node() +{ + deleteAllChildren(); + deleteAllEntries(); + deleteIndex(); if ( path_ ) { free( path_ ); path_ = 0L; @@ -1094,12 +1395,12 @@ int Fl_Preferences::Node::write( FILE *f ) { if ( next_ ) next_->write( f ); fprintf( f, "\n[%s]\n\n", path_ ); - for ( int i = 0; i < nEntry; i++ ) + for ( int i = 0; i < nEntry_; i++ ) { - char *src = entry[i].value; + char *src = entry_[i].value; if ( src ) { // hack it into smaller pieces if needed - fprintf( f, "%s:", entry[i].name ); + fprintf( f, "%s:", entry_[i].name ); int cnt; for ( cnt = 0; cnt < 60; cnt++ ) if ( src[cnt]==0 ) break; @@ -1117,7 +1418,7 @@ int Fl_Preferences::Node::write( FILE *f ) } } else - fprintf( f, "%s\n", entry[i].name ); + fprintf( f, "%s\n", entry_[i].name ); } if ( child_ ) child_->write( f ); dirty_ = 0; @@ -1135,6 +1436,19 @@ void Fl_Preferences::Node::setParent( Node *pn ) path_ = strdup( nameBuffer ); } +// find the corresponding root node +Fl_Preferences::RootNode *Fl_Preferences::Node::findRoot() +{ + Node *n = this; + do { + if (n->top_) + return n->root_; + n = n->parent(); + + } while (n); + return 0L; +} + // add a child to this node and set its path (try to find it first...) Fl_Preferences::Node *Fl_Preferences::Node::addChild( const char *path ) { @@ -1143,37 +1457,38 @@ Fl_Preferences::Node *Fl_Preferences::Node::addChild( const char *path ) Node *nd = find( name ); free( name ); dirty_ = 1; + updateIndex(); return nd; } // create and set, or change an entry within this node void Fl_Preferences::Node::set( const char *name, const char *value ) { - for ( int i=0; i=nEntry ) return; - char *&dst = entry[ lastEntrySet ].value; + if ( lastEntrySet<0 || lastEntrySet>=nEntry_ ) return; + char *&dst = entry_[ lastEntrySet ].value; int a = strlen( dst ); int b = strlen( line ); dst = (char*)realloc( dst, a+b+1 ); @@ -1220,15 +1535,15 @@ void Fl_Preferences::Node::add( const char *line ) const char *Fl_Preferences::Node::get( const char *name ) { int i = getEntry( name ); - return i>=0 ? entry[i].value : 0 ; + return i>=0 ? entry_[i].value : 0 ; } // find the index of an entry, returns -1 if no such entry int Fl_Preferences::Node::getEntry( const char *name ) { - for ( int i=0; iparent_ ) nn = nn->parent_; + while ( nn->parent() ) nn = nn->parent(); if ( path[2]==0 ) { // user is searching for root ( "./" ) return nn; @@ -1307,7 +1622,7 @@ Fl_Preferences::Node *Fl_Preferences::Node::search( const char *path, int offset } offset = strlen( path_ ) + 1; } - + int len = strlen( path_ ); if ( len < offset-1 ) return 0; len -= offset; @@ -1331,53 +1646,301 @@ Fl_Preferences::Node *Fl_Preferences::Node::search( const char *path, int offset // return the number of child nodes (groups) int Fl_Preferences::Node::nChildren() { - int cnt = 0; - for ( Node *nd = child_; nd; nd = nd->next_ ) - cnt++; - return cnt; + if (indexed_) { + return nIndex_; + } else { + int cnt = 0; + for ( Node *nd = child_; nd; nd = nd->next_ ) + cnt++; + return cnt; + } +} + +// return the node name +const char *Fl_Preferences::Node::name() +{ + if ( path_ ) + { + char *r = strrchr( path_, '/' ); + return r ? r+1 : path_ ; + } else { + return 0L ; + } +} + +// return the n'th child node's name +const char *Fl_Preferences::Node::child( int ix ) +{ + Node *nd = childNode( ix ); + if ( nd ) + return nd->name(); + else + return 0L ; } // return the n'th child node -const char *Fl_Preferences::Node::child( int ix ) +Fl_Preferences::Node *Fl_Preferences::Node::childNode( int ix ) { - Node *nd; - for ( nd = child_; nd; nd = nd->next_ ) - { - if ( !ix-- ) break; + createIndex(); + if (indexed_) { + // usually faster access in correct order, but needing more memory + return index_[ix]; + } else { + // slow access and reverse order + int n = nChildren(); + ix = n - ix -1; + Node *nd; + for ( nd = child_; nd; nd = nd->next_ ) + { + if ( !ix-- ) break; + if ( !nd ) break; + } + return nd; } - if ( nd && nd->path_ ) - { - char *r = strrchr( nd->path_, '/' ); - return r ? r+1 : nd->path_ ; - } - return 0L ; } // remove myself from the list and delete me (and all children) char Fl_Preferences::Node::remove() { Node *nd = 0, *np; - if ( parent_ ) + if ( parent() ) { - nd = parent_->child_; np = 0L; + nd = parent()->child_; np = 0L; for ( ; nd; np = nd, nd = nd->next_ ) { if ( nd == this ) { - if ( np ) - np->next_ = nd->next_; - else - parent_->child_ = nd->next_; + if ( np ) + np->next_ = nd->next_; + else + parent()->child_ = nd->next_; break; } } - parent_->dirty_ = 1; + parent()->dirty_ = 1; + parent()->updateIndex(); } delete this; return ( nd != 0 ); } +void Fl_Preferences::Node::createIndex() { + if (indexed_) return; + int n = nChildren(); + if (n>NIndex_) { + NIndex_ = n + 16; + index_ = (Node**)realloc(index_, NIndex_*sizeof(Node**)); + } + Node *nd; + int i = 0; + for (nd = child_; nd; nd = nd->next_, i++) { + index_[n-i-1] = nd; + } + nIndex_ = n; + indexed_ = 1; +} + +void Fl_Preferences::Node::updateIndex() { + indexed_ = 0; +} + +void Fl_Preferences::Node::deleteIndex() { + if (index_) free(index_); + NIndex_ = nIndex_ = 0; + index_ = 0; + indexed_ = 0; +} + +/** + * \brief Create a plugin. + * + * \param[in] klass plugins are grouped in classes + * \param[in] name every plugin should have a unique name + */ +Fl_Plugin::Fl_Plugin(const char *klass, const char *name) +: id(0) +{ +#ifdef FL_PLUGIN_VERBOSE + printf("Fl_Plugin: creating a plugin, class \"%s\", name \"%s\"\n", + klass, name); +#endif + Fl_Plugin_Manager pm(klass); + id = pm.addPlugin(name, this); +} + +/** + * \brief Clear the plugin and remove it from the database. + */ +Fl_Plugin::~Fl_Plugin() +{ +#ifdef FL_PLUGIN_VERBOSE + printf("Fl_Plugin: deleting a plugin\n"); +#endif + if (id) + Fl_Plugin_Manager::remove(id); +} + + +/** + * \brief Manage all plugins belonging to one class. + */ +Fl_Plugin_Manager::Fl_Plugin_Manager(const char *klass) +: Fl_Preferences(0, Fl_Preferences::Name("%s/%s", "plugins", klass)) +{ +#ifdef FL_PLUGIN_VERBOSE + printf("Fl_Plugin: creating a plugin manager for class \"%s\"\n", klass); +#endif +} + +/** + * \brief Remove the plugin manager. + * + * Calling this does not remove the database itself or any plugins. It just + * removes the reference to the database. + */ +Fl_Plugin_Manager::~Fl_Plugin_Manager() +{ +#ifdef FL_PLUGIN_VERBOSE + printf("Fl_Plugin: deleting a plugin manager\n"); +#endif +} + +static unsigned char x2i(char hi, char lo) { + return ((hi-'A')<<4) | (lo-'A'); +} + +static void i2x(unsigned char v, char *d) { + d[0] = ((v>>4)&0x0f)+'A'; d[1] = (v&0x0f)+'A'; +} + +static void *a2p(const char *s) { + union { void *ret; unsigned char d[sizeof(void*)]; } v; + v.ret = 0L; + int i=0, n=sizeof(void*); + for (i=0; id_name, pattern)) { + load(Fl_Preferences::Name("%s%s", filepath, e->d_name)); + } + free(e); + } + free(dir); + return 0; +} + // -// End of "$Id: Fl_Preferences.cxx 6716 2009-03-24 01:40:44Z fabien $". +// End of "$Id: Fl_Preferences.cxx 7672 2010-07-10 09:44:45Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Printer.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Printer.cxx new file mode 100644 index 000000000..e4f2e84fa --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Printer.cxx @@ -0,0 +1,93 @@ +// +// "$Id: Fl_Printer.cxx 7617 2010-05-27 17:20:18Z manolo $" +// +// Encompasses platform-specific printing-support code and +// PostScript output code for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to: +// +// http://www.fltk.org/str.php +// + +#include + +#ifdef __APPLE__ +#include +#elif defined(WIN32) +#include +#endif + +#include + +// print dialog customization strings +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_title = "Print"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_printer = "Printer:"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_range = "Print Range"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_copies = "Copies"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_all = "All"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_pages = "Pages"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_from = "From:"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_to = "To:"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_properties = "Properties..."; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_copyNo = "# Copies:"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_print_button = "Print"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_cancel_button = "Cancel"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::dialog_print_to_file = "Print To File"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::property_title = "Printer Properties"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::property_pagesize = "Page Size:"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::property_mode = "Output Mode:"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::property_use = "Use"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::property_save = "Save"; +/** [this text may be customized at run-time] */ +const char *Fl_Printer::property_cancel = "Cancel"; + +const char *Fl_Printer::device_type = "Fl_Printer"; + +void Fl_Printer::set_current() +{ +#ifdef __APPLE__ + fl_gc = (CGContextRef)gc; +#elif defined(WIN32) + fl_gc = (HDC)gc; +#endif + this->Fl_Surface_Device::set_current(); +} + +// +// End of "$Id: Fl_Printer.cxx 7617 2010-05-27 17:20:18Z manolo $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Scroll.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Scroll.cxx index f9a03027a..4ac025ca6 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Scroll.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Scroll.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Scroll.cxx 6828 2009-07-12 00:15:06Z greg.ercolano $" +// "$Id: Fl_Scroll.cxx 7039 2010-02-07 21:14:35Z AlbrechtS $" // // Scroll widget for the Fast Light Tool Kit (FLTK). // @@ -413,5 +413,5 @@ int Fl_Scroll::handle(int event) { } // -// End of "$Id: Fl_Scroll.cxx 6828 2009-07-12 00:15:06Z greg.ercolano $". +// End of "$Id: Fl_Scroll.cxx 7039 2010-02-07 21:14:35Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Scrollbar.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Scrollbar.cxx index 6b6cd2260..40c298c9b 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Scrollbar.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Scrollbar.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Scrollbar.cxx 6683 2009-03-14 11:46:43Z engelsman $" +// "$Id: Fl_Scrollbar.cxx 7161 2010-02-26 20:44:35Z matt $" // // Scroll bar widget for the Fast Light Tool Kit (FLTK). // @@ -36,23 +36,32 @@ #define REPEAT .05 void Fl_Scrollbar::increment_cb() { - int ls = maximum()>=minimum() ? linesize_ : -linesize_; + char inv = maximum() -ls) i = -ls; - break; - case 6: - i = int((maximum()-minimum())*slider_size()/(1.0-slider_size())) - ls; - if (i < ls) i = ls; - break; + case 1: // clicked on arrow left + i = -ls; + break; + default: // clicked on arrow right + i = ls; + break; + case 5: // clicked into the box next to the slider on the left + i = -(int((maximum()-minimum())*slider_size()/(1.0-slider_size()))); + if (inv) { + if (i<-ls) i = -ls; + } else { + if (i>-ls) i = -ls; // err + } + break; + case 6: // clicked into the box next to the slider on the right + i = (int((maximum()-minimum())*slider_size()/(1.0-slider_size()))); + if (inv) { + if (i>ls) i = ls; + } else { + if (i=minimum() ? linesize_ : -linesize_; + handle_drag(clamp(value() + ls * Fl::e_dx)); return 1; } else { if (Fl::e_dy==0) return 0; - handle_drag(clamp(value() + linesize_ * Fl::e_dy)); + int ls = maximum()>=minimum() ? linesize_ : -linesize_; + handle_drag(clamp(value() + ls * Fl::e_dy)); return 1; } case FL_SHORTCUT: @@ -277,5 +288,5 @@ Fl_Scrollbar::~Fl_Scrollbar() { // -// End of "$Id: Fl_Scrollbar.cxx 6683 2009-03-14 11:46:43Z engelsman $". +// End of "$Id: Fl_Scrollbar.cxx 7161 2010-02-26 20:44:35Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Slider.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Slider.cxx index 1a0f8e7e1..59474df07 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Slider.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Slider.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Slider.cxx 6683 2009-03-14 11:46:43Z engelsman $" +// "$Id: Fl_Slider.cxx 7115 2010-02-20 17:40:07Z AlbrechtS $" // // Slider widget for the Fast Light Tool Kit (FLTK). // @@ -222,10 +222,14 @@ void Fl_Slider::draw() { } int Fl_Slider::handle(int event, int X, int Y, int W, int H) { + // Fl_Widget_Tracker wp(this); switch (event) { - case FL_PUSH: + case FL_PUSH: { + Fl_Widget_Tracker wp(this); if (!Fl::event_inside(X, Y, W, H)) return 0; handle_push(); + if (wp.deleted()) return 1; } + // fall through ... case FL_DRAG: { double val; @@ -293,34 +297,44 @@ int Fl_Slider::handle(int event, int X, int Y, int W, int H) { case FL_RELEASE: handle_release(); return 1; - case FL_KEYBOARD : - switch (Fl::event_key()) { - case FL_Up: - if (horizontal()) return 0; - handle_push(); - handle_drag(clamp(increment(value(),-1))); - handle_release(); - return 1; - case FL_Down: - if (horizontal()) return 0; - handle_push(); - handle_drag(clamp(increment(value(),1))); - handle_release(); - return 1; - case FL_Left: - if (!horizontal()) return 0; - handle_push(); - handle_drag(clamp(increment(value(),-1))); - handle_release(); - return 1; - case FL_Right: - if (!horizontal()) return 0; - handle_push(); - handle_drag(clamp(increment(value(),1))); - handle_release(); - return 1; - default: - return 0; + case FL_KEYBOARD: + { Fl_Widget_Tracker wp(this); + switch (Fl::event_key()) { + case FL_Up: + if (horizontal()) return 0; + handle_push(); + if (wp.deleted()) return 1; + handle_drag(clamp(increment(value(),-1))); + if (wp.deleted()) return 1; + handle_release(); + return 1; + case FL_Down: + if (horizontal()) return 0; + handle_push(); + if (wp.deleted()) return 1; + handle_drag(clamp(increment(value(),1))); + if (wp.deleted()) return 1; + handle_release(); + return 1; + case FL_Left: + if (!horizontal()) return 0; + handle_push(); + if (wp.deleted()) return 1; + handle_drag(clamp(increment(value(),-1))); + if (wp.deleted()) return 1; + handle_release(); + return 1; + case FL_Right: + if (!horizontal()) return 0; + handle_push(); + if (wp.deleted()) return 1; + handle_drag(clamp(increment(value(),1))); + if (wp.deleted()) return 1; + handle_release(); + return 1; + default: + return 0; + } } // break not required because of switch... case FL_FOCUS : @@ -351,5 +365,5 @@ int Fl_Slider::handle(int event) { } // -// End of "$Id: Fl_Slider.cxx 6683 2009-03-14 11:46:43Z engelsman $". +// End of "$Id: Fl_Slider.cxx 7115 2010-02-20 17:40:07Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Sys_Menu_Bar.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Sys_Menu_Bar.cxx index 8fe6a2249..69b47c345 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Sys_Menu_Bar.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Sys_Menu_Bar.cxx @@ -1,9 +1,9 @@ // -// "$Id: Fl_Sys_Menu_Bar.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_Sys_Menu_Bar.cxx 7518 2010-04-16 19:27:28Z manolo $" // // MacOS system menu bar widget for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2009 by Bill Spitzak and others. +// Copyright 1998-2010 by Bill Spitzak and others. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public @@ -36,13 +36,13 @@ * FLTK features not supported by the Mac System menu * * - no invisible menu items - * - no sybolic labels + * - no symbolic labels * - embossed labels will be underlined instead * - no font sizes * - Shortcut Characters should be English alphanumeric only, no modifiers yet * - no disable main menus * - changes to menubar in run-time don't update! - * (disable, etc. - toggle and readio button do!) + * (disable, etc. - toggle and radio button do!) * * No care was taken to clean up the menu bar after destruction! * ::menu(bar) should only be called once! @@ -52,7 +52,7 @@ * a bundle for the System Menu Bar (and maybe other features) to work! */ -#if defined(__APPLE__) +#if defined(__APPLE__) || defined(FL_DOXYGEN) #include #include @@ -61,67 +61,15 @@ #include "flstring.h" #include #include +#include + +#define MenuHandle void * typedef const Fl_Menu_Item *pFl_Menu_Item; + -/** - * copy the text of a menuitem into a buffer. - * Skip all '&' which would mark the shortcut in FLTK - * Skip all Mac control characters ('(', '<', ';', '^', '!' ) - */ -static void catMenuText( const char *src, char *dst ) -{ - char c; - while ( *dst ) - dst++; - if ( *src == '-' ) - src++; - while ( ( c = *src++ ) ) - { - if ( !strchr( "&(<;^!", c ) ) - *dst++ = c; - } - *dst = 0; -} - -/** - * append a marker to identify the menu font style - * labeltype_ && !m->labelfont_ ) - return; - while ( *dst ) - dst++; - - if ( m->labelfont_ & FL_BOLD ) - strcat( dst, "labelfont_ & FL_ITALIC ) - strcat( dst, "labelfont_ & FL_UNDERLINE ) - // strcat( dst, "labeltype_ == FL_EMBOSSED_LABEL ) - strcat( dst, "labeltype_ == FL_ENGRAVED_LABEL ) - strcat( dst, "labeltype_ == FL_SHADOW_LABEL ) - strcat( dst, "labeltype_ == FL_SYMBOL_LABEL ) - ; // not supported -} - -/** - * append a marker to identify the menu shortcut - * shortcut_ & FL_META ) macMod = kMenuNoModifiers; - if ( m->shortcut_ & FL_SHIFT || isupper(key) ) macMod |= kMenuShiftModifier; - if ( m->shortcut_ & FL_ALT ) macMod |= kMenuOptionModifier; - if ( m->shortcut_ & FL_CTRL ) macMod |= kMenuControlModifier; - - //SetMenuItemKeyGlyph( mh, miCnt, key ); - SetItemCmd( mh, miCnt, toupper(key) ); - SetMenuItemModifiers( mh, miCnt, macMod ); + void *menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, miCnt); + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setKeyEquivalent, menuItem, m->shortcut_ & 0xff ); + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setKeyEquivalentModifierMask, menuItem, m->shortcut_ ); } -#if 0 -// this function needs to be verified before we compile it back in. -static void catMenuShortcut( const Fl_Menu_Item *m, char *dst ) -{ - if ( !m->shortcut_ ) - return; - char c = m->shortcut_ & 0xff; - if ( !isalnum( c & 0xff ) ) - return; - while ( *dst ) - dst++; - if ( m->shortcut_ & FL_CTRL ) - { - sprintf( dst, "/%c", toupper( c ) ); - } - //if ( isalnum( mm->shortcut_ ) && !( mm->flags & FL_SUBMENU ) ) - //sprintf( buf+strlen(buf), "/%c", mm->shortcut_ ); -} -#endif +/* + * Set the Toggle and Radio flag based on FLTK flags + */ static void setMenuFlags( MenuHandle mh, int miCnt, const Fl_Menu_Item *m ) { if ( m->flags & FL_MENU_TOGGLE ) { - SetItemMark( mh, miCnt, ( m->flags & FL_MENU_VALUE ) ? 0x12 : 0 ); + void *menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, miCnt); + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setState, menuItem, m->flags & FL_MENU_VALUE ); + } + else if ( m->flags & FL_MENU_RADIO ) { + void *menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, miCnt); + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setState, menuItem, m->flags & FL_MENU_VALUE ); } - else if ( m->flags & FL_MENU_RADIO ) - SetItemMark( mh, miCnt, ( m->flags & FL_MENU_VALUE ) ? 0x13 : 0 ); } -static void catMenuFlags( const Fl_Menu_Item *m, char *dst ) -{ - if ( !m->flags ) - return; - if ( m->flags & FL_MENU_INACTIVE ) - strcat( dst, "(" ); -} -/** +/* * create a sub menu for a specific menu handle */ -static void createSubMenu( MenuHandle mh, int &cnt, pFl_Menu_Item &mm ) +static void createSubMenu( void * mh, pFl_Menu_Item &mm ) { - char buf[255]; - int miCnt = 1; + void *submenu; + int miCnt, flags; + + void *menuItem; + submenu = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::initWithTitle, mm->text); + int cnt; + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::numberOfItems, mh, &cnt); + cnt--; + menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, cnt); + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setSubmenu, menuItem, submenu); + if ( mm->flags & FL_MENU_INACTIVE ) { + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setEnabled, menuItem, 0); + } + mm++; + while ( mm->text ) { - MenuHandle smh = 0; - buf[1] = 0; - catMenuFont( mm, buf+1 ); - //catMenuShortcut( mm, buf+1 ); - catMenuText( mm->text, buf+1 ); - catMenuFlags( mm, buf+1 ); - if ( mm->flags & (FL_SUBMENU | FL_SUBMENU_POINTER) ) - { - cnt++; - smh = NewMenu( cnt, (unsigned char*)"\001 " ); - sprintf( buf+1+strlen(buf+1), "/\033!%c", cnt ); + int flRank = mm - fl_sys_menu_bar->Fl_Menu_::menu(); + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addNewItem, submenu, flRank, &miCnt); + setMenuFlags( submenu, miCnt, mm ); + setMenuShortcut( submenu, miCnt, mm ); + if ( mm->flags & FL_MENU_INACTIVE ) { + void *item = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, submenu, miCnt); + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setEnabled, item, 0); } - if ( mm->flags & FL_MENU_DIVIDER ) - strcat( buf+1, ";-" ); - buf[0] = strlen( buf+1 ); - AppendMenu( mh, (unsigned char*)buf ); - // insert Appearanc manager functions here! - setMenuFlags( mh, miCnt, mm ); - setMenuShortcut( mh, miCnt, mm ); - SetMenuItemRefCon( mh, miCnt, (UInt32)mm ); - miCnt++; - if ( mm->flags & FL_MENU_DIVIDER ) - miCnt++; + flags = mm->flags; if ( mm->flags & FL_SUBMENU ) { - createSubMenu( smh, cnt, ++mm ); + createSubMenu( submenu, mm ); } else if ( mm->flags & FL_SUBMENU_POINTER ) { const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; - createSubMenu( mh, cnt, smm ); + createSubMenu( submenu, smm ); } + if ( flags & FL_MENU_DIVIDER ) { + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addSeparatorItem, submenu); + } mm++; } - InsertMenu( mh, -1 ); } +/* + * convert a complete Fl_Menu_Item array into a series of menus in the top menu bar + * ALL PREVIOUS SYSTEM MENUS, EXCEPT APPLICATION MENU, ARE REPLACED BY THE NEW DATA + */ +static void convertToMenuBar(const Fl_Menu_Item *mm) +{ + int count;//first, delete all existing system menus + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::numberOfItems, fl_system_menu, &count); + for(int i = count - 1; i > 0; i--) { + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::removeItem, fl_system_menu, i); + } + //now convert FLTK stuff into MacOS menus + for (;;) + { + if ( !mm || !mm->text ) + break; + char visible = mm->visible() ? 1 : 0; + int flRank = mm - fl_sys_menu_bar->Fl_Menu_::menu(); + Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addNewItem, fl_system_menu, flRank, NULL); + + if ( mm->flags & FL_SUBMENU ) + createSubMenu( fl_system_menu, mm ); + else if ( mm->flags & FL_SUBMENU_POINTER ) { + const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; + createSubMenu( fl_system_menu, smm ); + } + if ( visible ) { + // InsertMenu( mh, 0 ); + } + mm++; + } +} + + /** - * create a system menu bar using the given list of menu structs + * @brief create a system menu bar using the given list of menu structs * * \author Matthias Melcher * @@ -242,93 +199,90 @@ void Fl_Sys_Menu_Bar::menu(const Fl_Menu_Item *m) { fl_open_display(); Fl_Menu_Bar::menu( m ); - fl_sys_menu_bar = this; - - char buf[255]; - - int cnt = 1; // first menu is no 2. no 1 is the Apple Menu - const Fl_Menu_Item *mm = m; - for (;;) - { - if ( !mm || !mm->text ) - break; - char visible = mm->visible() ? 1 : 0; - buf[1] = 0; - catMenuText( mm->text, buf+1 ); - buf[0] = strlen( buf+1 ); - MenuHandle mh = NewMenu( ++cnt, (unsigned char*)buf ); - if ( mm->flags & FL_MENU_INACTIVE ) { - ChangeMenuAttributes(mh, kMenuAttrAutoDisable, 0); - DisableAllMenuItems(mh); - DisableMenuItem(mh, 0); - } - if ( mm->flags & FL_SUBMENU ) - createSubMenu( mh, cnt, ++mm ); - else if ( mm->flags & FL_SUBMENU_POINTER ) { - const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; - createSubMenu( mh, cnt, smm ); - } - if ( visible ) { - InsertMenu( mh, 0 ); - } - mm++; - } - DrawMenuBar(); + convertToMenuBar(m); } + +/** + * @brief add to the system menu bar a new menu item + * + * add to the system menu bar a new menu item, with a title string, shortcut int, + * callback, argument to the callback, and flags. + * + * @see Fl_Menu_::add(const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) + */ +int Fl_Sys_Menu_Bar::add(const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) +{ + fl_open_display(); + int rank = Fl_Menu_::add(label, shortcut, cb, user_data, flags); + convertToMenuBar(Fl_Menu_::menu()); + return rank; +} + +/** + * @brief insert in the system menu bar a new menu item + * + * insert in the system menu bar a new menu item, with a title string, shortcut int, + * callback, argument to the callback, and flags. + * + * @see Fl_Menu_::insert(int index, const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) + */ +int Fl_Sys_Menu_Bar::insert(int index, const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) +{ + fl_open_display(); + int rank = Fl_Menu_::insert(index, label, shortcut, cb, user_data, flags); + convertToMenuBar(Fl_Menu_::menu()); + return rank; +} + +void Fl_Sys_Menu_Bar::clear() +{ + Fl_Menu_::clear(); + convertToMenuBar(NULL); +} + +int Fl_Sys_Menu_Bar::clear_submenu(int index) +{ + int retval = Fl_Menu_::clear_submenu(index); + if (retval != -1) convertToMenuBar(Fl_Menu_::menu()); + return retval; +} + +/** + * @brief remove an item from the system menu bar + * + * @param rank the rank of the item to remove + */ +void Fl_Sys_Menu_Bar::remove(int rank) +{ + Fl_Menu_::remove(rank); + convertToMenuBar(Fl_Menu_::menu()); +} + + +/** + * @brief rename an item from the system menu bar + * + * @param rank the rank of the item to rename + * @param name the new item name as a UTF8 string + */ +void Fl_Sys_Menu_Bar::replace(int rank, const char *name) +{ + doMenuOrItemOperation(renameItem, rank, name); + fl_sys_menu_bar->Fl_Menu_::replace(rank, name); +} + + /* -const Fl_Menu_Item* Fl_Sys_Menu_Bar::picked(const Fl_Menu_Item* v) { - Fl_menu_Item *ret = Fl_Menu_Bar::picked( v ); - - if ( m->flags & FL_MENU_TOGGLE ) - { - SetItemMark( mh, miCnt, ( m->flags & FL_MENU_VALUE ) ? 0x12 : 0 ); - } - - return ret; -} -*/ - + * Draw the menu bar. + * Nothing here because the OS does this for us. + */ void Fl_Sys_Menu_Bar::draw() { -/* -- nothing to do, system should take care of this - draw_box(); - if (!menu() || !menu()->text) return; - const Fl_Menu_Item* m; - int X = x()+6; - for (m=menu(); m->text; m = m->next()) { - int W = m->measure(0,this) + 16; - m->draw(X, y(), W, h(), this); - X += W; - } - */ } -/* -int Fl_Menu_Bar::handle(int event) { - const Fl_Menu_Item* v; - if (menu() && menu()->text) switch (event) { - case FL_ENTER: - case FL_LEAVE: - return 1; - case FL_PUSH: - v = 0; - J1: - v = menu()->pulldown(x(), y(), w(), h(), v, this, 0, 1); - picked(v); - return 1; - case FL_SHORTCUT: - if (visible_r()) { - v = menu()->find_shortcut(); - if (v && v->submenu()) goto J1; - } - return test_shortcut() != 0; - } - return 0; -} -*/ #endif /* __APPLE__ */ // -// End of "$Id: Fl_Sys_Menu_Bar.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_Sys_Menu_Bar.cxx 7518 2010-04-16 19:27:28Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Table.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Table.cxx new file mode 100644 index 000000000..8f743d178 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Table.cxx @@ -0,0 +1,1224 @@ +// +// "$Id: Fl_Table.cxx 7117 2010-02-20 21:14:47Z matt $" +// +// Fl_Table -- A table widget +// +// Copyright 2002 by Greg Ercolano. +// Copyright (c) 2004 O'ksi'D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +#include // fprintf +#include +#include + +#if defined(USE_UTF8) && ( defined(MICROSOFT) || defined(LINUX) ) +#include // currently only Windows and Linux +#endif + +#define SCROLLBAR_SIZE 16 + +// Scroll display so 'row' is at top +void Fl_Table::row_position(int row) { + if ( _row_position == row ) return; // OPTIMIZATION: no change? avoid redraw + if ( row < 0 ) row = 0; + else if ( row >= rows() ) row = rows() - 1; + if ( table_h <= tih ) return; // don't scroll if table smaller than window + double newtop = row_scroll_position(row); + if ( newtop > vscrollbar->maximum() ) { + newtop = vscrollbar->maximum(); + } + vscrollbar->Fl_Slider::value(newtop); + table_scrolled(); + redraw(); + _row_position = row; // HACK: override what table_scrolled() came up with +} + +// Scroll display so 'col' is at left +void Fl_Table::col_position(int col) { + if ( _col_position == col ) return; // OPTIMIZATION: no change? avoid redraw + if ( col < 0 ) col = 0; + else if ( col >= cols() ) col = cols() - 1; + if ( table_w <= tiw ) return; // don't scroll if table smaller than window + double newleft = col_scroll_position(col); + if ( newleft > hscrollbar->maximum() ) { + newleft = hscrollbar->maximum(); + } + hscrollbar->Fl_Slider::value(newleft); + table_scrolled(); + redraw(); + _col_position = col; // HACK: override what table_scrolled() came up with +} + +// Find scroll position of a row (in pixels) +long Fl_Table::row_scroll_position(int row) { + int startrow = 0; + long scroll = 0; + // OPTIMIZATION: + // Attempt to use precomputed row scroll position + // + if ( toprow_scrollpos != -1 && row >= toprow ) { + scroll = toprow_scrollpos; + startrow = toprow; + } + for ( int t=startrow; t= leftcol ) { + scroll = leftcol_scrollpos; + startcol = leftcol; + } + for ( int t=startcol; ttype(FL_VERTICAL); + vscrollbar->callback(scroll_cb, (void*)this); + + hscrollbar = new Fl_Scrollbar(x(), y()+h()-SCROLLBAR_SIZE, + w(), SCROLLBAR_SIZE); + hscrollbar->type(FL_HORIZONTAL); + hscrollbar->callback(scroll_cb, (void*)this); + + table = new Fl_Scroll(x(), y(), w(), h()); + table->box(FL_NO_BOX); + table->type(0); // don't show Fl_Scroll's scrollbars -- use our own + table->hide(); // hide unless children are present + table->end(); + + table_resized(); + redraw(); + + Fl_Group::end(); // end the group's begin() + + table->begin(); // leave with fltk children getting added to the scroll +} + +// Dtor +Fl_Table::~Fl_Table() { + // The parent Fl_Group takes care of destroying scrollbars +} + +// Set height of a row +void Fl_Table::row_height(int row, int height) { + if ( row < 0 ) return; + if ( row < (int)_rowheights.size() && _rowheights[row] == height ) { + return; // OPTIMIZATION: no change? avoid redraw + } + // Add row heights, even if none yet + int now_size = (int)_rowheights.size(); + if ( row >= now_size ) { + _rowheights.size(row); + while (now_size < row) + _rowheights[now_size++] = height; + } + _rowheights[row] = height; + table_resized(); + if ( row <= botrow ) { // OPTIMIZATION: only redraw if onscreen or above screen + redraw(); + } + // ROW RESIZE CALLBACK + if ( Fl_Widget::callback() && when() & FL_WHEN_CHANGED ) { + do_callback(CONTEXT_RC_RESIZE, row, 0); + } +} + +// Set width of a column +void Fl_Table::col_width(int col, int width) +{ + if ( col < 0 ) return; + if ( col < (int)_colwidths.size() && _colwidths[col] == width ) { + return; // OPTIMIZATION: no change? avoid redraw + } + // Add column widths, even if none yet + int now_size = (int)_colwidths.size(); + if ( col >= now_size ) { + _colwidths.size(col); + while (now_size < col) { + _colwidths[now_size++] = width; + } + } + _colwidths[col] = width; + table_resized(); + if ( col <= rightcol ) { // OPTIMIZATION: only redraw if onscreen or to the left + redraw(); + } + // COLUMN RESIZE CALLBACK + if ( Fl_Widget::callback() && when() & FL_WHEN_CHANGED ) { + do_callback(CONTEXT_RC_RESIZE, 0, col); + } +} + +// Return row/col clamped to reality +int Fl_Table::row_col_clamp(TableContext context, int &R, int &C) { + int clamped = 0; + if ( R < 0 ) { R = 0; clamped = 1; } + if ( C < 0 ) { C = 0; clamped = 1; } + switch ( context ) { + case CONTEXT_COL_HEADER: + // Allow col headers to draw even if no rows + if ( R >= _rows && R != 0 ) { R = _rows - 1; clamped = 1; } + break; + + case CONTEXT_ROW_HEADER: + // Allow row headers to draw even if no columns + if ( C >= _cols && C != 0 ) { C = _cols - 1; clamped = 1; } + break; + + case CONTEXT_CELL: + default: + // CLAMP R/C TO _rows/_cols + if ( R >= _rows ) { R = _rows - 1; clamped = 1; } + if ( C >= _cols ) { C = _cols - 1; clamped = 1; } + break; + } + return(clamped); +} + +// Return bounding region for given context +void Fl_Table::get_bounds(TableContext context, int &X, int &Y, int &W, int &H) { + switch ( context ) { + case CONTEXT_COL_HEADER: + // Column header clipping. + X = tox; + Y = wiy; + W = tow; + H = col_header_height(); + return; + + case CONTEXT_ROW_HEADER: + // Row header clipping. + X = wix; + Y = toy; + W = row_header_width(); + H = toh; + return; + + case CONTEXT_TABLE: + // Table inner dimensions + X = tix; Y = tiy; W = tiw; H = tih; + return; + + // TODO: Add other contexts.. + default: + fprintf(stderr, "Fl_Table::get_bounds(): context %d unimplemented\n", (int)context); + return; + } + //NOTREACHED +} + +// Find row/col beneath cursor +// +// Returns R/C and context. +// Also returns resizeflag, if mouse is hovered over a resize boundary. +// +Fl_Table::TableContext Fl_Table::cursor2rowcol(int &R, int &C, ResizeFlag &resizeflag) { + // return values + R = C = 0; + resizeflag = RESIZE_NONE; + // Row header? + int X, Y, W, H; + if ( row_header() ) { + // Inside a row heading? + get_bounds(CONTEXT_ROW_HEADER, X, Y, W, H); + if ( Fl::event_inside(X, Y, W, H) ) { + // Scan visible rows until found + for ( R = toprow; R <= botrow; R++ ) { + find_cell(CONTEXT_ROW_HEADER, R, 0, X, Y, W, H); + if ( Fl::event_y() >= Y && Fl::event_y() < (Y+H) ) { + // Found row? + // If cursor over resize boundary, and resize enabled, + // enable the appropriate resize flag. + // + if ( row_resize() ) { + if ( Fl::event_y() <= (Y+3-0) ) { resizeflag = RESIZE_ROW_ABOVE; } + if ( Fl::event_y() >= (Y+H-3) ) { resizeflag = RESIZE_ROW_BELOW; } + } + return(CONTEXT_ROW_HEADER); + } + } + // Must be in row header dead zone + return(CONTEXT_NONE); + } + } + // Column header? + if ( col_header() ) { + // Inside a column heading? + get_bounds(CONTEXT_COL_HEADER, X, Y, W, H); + if ( Fl::event_inside(X, Y, W, H) ) { + // Scan visible columns until found + for ( C = leftcol; C <= rightcol; C++ ) { + find_cell(CONTEXT_COL_HEADER, 0, C, X, Y, W, H); + if ( Fl::event_x() >= X && Fl::event_x() < (X+W) ) { + // Found column? + // If cursor over resize boundary, and resize enabled, + // enable the appropriate resize flag. + // + if ( col_resize() ) { + if ( Fl::event_x() <= (X+3-0) ) { resizeflag = RESIZE_COL_LEFT; } + if ( Fl::event_x() >= (X+W-3) ) { resizeflag = RESIZE_COL_RIGHT; } + } + return(CONTEXT_COL_HEADER); + } + } + // Must be in column header dead zone + return(CONTEXT_NONE); + } + } + // Mouse somewhere in table? + // Scan visible r/c's until we find it. + // + if ( Fl::event_inside(tox, toy, tow, toh) ) { + for ( R = toprow; R <= botrow; R++ ) { + find_cell(CONTEXT_CELL, R, C, X, Y, W, H); + if ( Fl::event_y() < Y ) break; // OPT: thanks lars + if ( Fl::event_y() >= (Y+H) ) continue; // OPT: " " + for ( C = leftcol; C <= rightcol; C++ ) { + find_cell(CONTEXT_CELL, R, C, X, Y, W, H); + if ( Fl::event_inside(X, Y, W, H) ) { + return(CONTEXT_CELL); // found it + } + } + } + // Must be in a dead zone of the table + R = C = 0; + return(CONTEXT_TABLE); + } + // Somewhere else + return(CONTEXT_NONE); +} + +// Find X/Y/W/H for cell at R/C +// If R or C are out of range, returns -1 +// with X/Y/W/H set to zero. +// +int Fl_Table::find_cell(TableContext context, int R, int C, int &X, int &Y, int &W, int &H) { + if ( row_col_clamp(context, R, C) ) { // row or col out of range? error + X=Y=W=H=0; + return(-1); + } + X = col_scroll_position(C) - hscrollbar->value() + tix; + Y = row_scroll_position(R) - vscrollbar->value() + tiy; + W = col_width(C); + H = row_height(R); + + switch ( context ) { + case CONTEXT_COL_HEADER: + Y = wiy; + H = col_header_height(); + return(0); + + case CONTEXT_ROW_HEADER: + X = wix; + W = row_header_width(); + return(0); + + case CONTEXT_CELL: + return(0); + + case CONTEXT_TABLE: + return(0); + + // TODO -- HANDLE OTHER CONTEXTS + default: + fprintf(stderr, "Fl_Table::find_cell: unknown context %d\n", (int)context); + return(-1); + } + //NOTREACHED +} + +// Enable automatic scroll-selection +void Fl_Table::_start_auto_drag() { + if (_auto_drag) return; + _auto_drag = 1; + Fl::add_timeout(0.3, _auto_drag_cb2, this); +} + +// Disable automatic scroll-selection +void Fl_Table::_stop_auto_drag() { + if (!_auto_drag) return; + Fl::remove_timeout(_auto_drag_cb2, this); + _auto_drag = 0; +} + +void Fl_Table::_auto_drag_cb2(void *d) { + ((Fl_Table*)d)->_auto_drag_cb(); +} + +// Handle automatic scroll-selection if mouse selection dragged off table edge +void Fl_Table::_auto_drag_cb() { + int lx = Fl::e_x; + int ly = Fl::e_y; + if (_selecting == CONTEXT_COL_HEADER) + { ly = y() + col_header_height(); } + else if (_selecting == CONTEXT_ROW_HEADER) + { lx = x() + row_header_width(); } + if (lx > x() + w() - 20) { + Fl::e_x = x() + w() - 20; + if (hscrollbar->visible()) + ((Fl_Slider*)hscrollbar)->value( + hscrollbar->clamp(hscrollbar->value() + 30)); + hscrollbar->do_callback(); + _dragging_x = Fl::e_x - 30; + } + else if (lx < (x() + row_header_width())) { + Fl::e_x = x() + row_header_width() + 1; + if (hscrollbar->visible()) { + ((Fl_Slider*)hscrollbar)->value(hscrollbar->clamp(hscrollbar->value() - 30)); + } + hscrollbar->do_callback(); + _dragging_x = Fl::e_x + 30; + } + if (ly > y() + h() - 20) { + Fl::e_y = y() + h() - 20; + if (vscrollbar->visible()) { + ((Fl_Slider*)vscrollbar)->value(vscrollbar->clamp(vscrollbar->value() + 30)); + } + vscrollbar->do_callback(); + _dragging_y = Fl::e_y - 30; + } + else if (ly < (y() + col_header_height())) { + Fl::e_y = y() + col_header_height() + 1; + if (vscrollbar->visible()) { + ((Fl_Slider*)vscrollbar)->value(vscrollbar->clamp(vscrollbar->value() - 30)); + } + vscrollbar->do_callback(); + _dragging_y = Fl::e_y + 30; + } + _auto_drag = 2; + handle(FL_DRAG); + _auto_drag = 1; + Fl::e_x = lx; + Fl::e_y = ly; + Fl::check(); + Fl::flush(); + if (Fl::event_buttons() && _auto_drag) { + Fl::add_timeout(0.05, _auto_drag_cb2, this); + } +} + +// Recalculate the window dimensions +void Fl_Table::recalc_dimensions() { + // Recalc to* (Table Outer), ti* (Table Inner), wi* ( Widget Inner) + wix = ( x() + Fl::box_dx(box())); tox = wix; tix = tox + Fl::box_dx(table->box()); + wiy = ( y() + Fl::box_dy(box())); toy = wiy; tiy = toy + Fl::box_dy(table->box()); + wiw = ( w() - Fl::box_dw(box())); tow = wiw; tiw = tow - Fl::box_dw(table->box()); + wih = ( h() - Fl::box_dh(box())); toh = wih; tih = toh - Fl::box_dh(table->box()); + // Trim window if headers enabled + if ( col_header() ) { + tiy += col_header_height(); toy += col_header_height(); + tih -= col_header_height(); toh -= col_header_height(); + } + if ( row_header() ) { + tix += row_header_width(); tox += row_header_width(); + tiw -= row_header_width(); tow -= row_header_width(); + } + // Make scroll bars disappear if window large enough + { + // First pass: can hide via window size? + int hidev = (table_h <= tih); + int hideh = (table_w <= tiw); + // Second pass: Check for interference + if ( !hideh & hidev ) { hidev = (( table_h - tih + SCROLLBAR_SIZE ) <= 0 ); } + if ( !hidev & hideh ) { hideh = (( table_w - tiw + SCROLLBAR_SIZE ) <= 0 ); } + // Determine scrollbar visibility, trim ti[xywh]/to[xywh] + if ( hidev ) { vscrollbar->hide(); } + else { vscrollbar->show(); tiw -= SCROLLBAR_SIZE; tow -= SCROLLBAR_SIZE; } + if ( hideh ) { hscrollbar->hide(); } + else { hscrollbar->show(); tih -= SCROLLBAR_SIZE; toh -= SCROLLBAR_SIZE; } + } + // Resize the child table + table->resize(tox, toy, tow, toh); + table->init_sizes(); +} + +// Recalculate internals after a scroll. +// +// Call this if table has been scrolled or resized. +// Does not handle redraw(). +// TODO: Assumes ti[xywh] has already been recalculated. +// +void Fl_Table::table_scrolled() { + // Find top row + int y, row, voff = vscrollbar->value(); + for ( row=y=0; row < _rows; row++ ) { + y += row_height(row); + if ( y > voff ) { y -= row_height(row); break; } + } + _row_position = toprow = ( row >= _rows ) ? (row - 1) : row; + toprow_scrollpos = y; // OPTIMIZATION: save for later use + // Find bottom row + voff = vscrollbar->value() + tih; + for ( ; row < _rows; row++ ) { + y += row_height(row); + if ( y >= voff ) { break; } + } + botrow = ( row >= _rows ) ? (row - 1) : row; + // Left column + int x, col, hoff = hscrollbar->value(); + for ( col=x=0; col < _cols; col++ ) { + x += col_width(col); + if ( x > hoff ) { x -= col_width(col); break; } + } + _col_position = leftcol = ( col >= _cols ) ? (col - 1) : col; + leftcol_scrollpos = x; // OPTIMIZATION: save for later use + // Right column + // Work with data left over from leftcol calculation + // + hoff = hscrollbar->value() + tiw; + for ( ; col < _cols; col++ ) { + x += col_width(col); + if ( x >= hoff ) { break; } + } + rightcol = ( col >= _cols ) ? (col - 1) : col; + // First tell children to scroll + draw_cell(CONTEXT_RC_RESIZE, 0,0,0,0,0,0); +} + +// Table resized: recalc internal data +// Call this whenever the window is resized. +// Recalculates the scrollbar sizes. +// Makes no assumptions about any pre-initialized data. +// +void Fl_Table::table_resized() { + table_h = row_scroll_position(rows()); + table_w = col_scroll_position(cols()); + recalc_dimensions(); + // Recalc scrollbar sizes + // Clamp scrollbar value() after a resize. + // Resize scrollbars to enforce a constant trough width after a window resize. + // + { + // Vertical scrollbar + float vscrolltab = ( table_h == 0 || tih > table_h ) ? 1 : (float)tih / table_h; + float hscrolltab = ( table_w == 0 || tiw > table_w ) ? 1 : (float)tiw / table_w; + vscrollbar->bounds(0, table_h-tih); + vscrollbar->precision(10); + vscrollbar->slider_size(vscrolltab); + vscrollbar->resize(wix+wiw-SCROLLBAR_SIZE, wiy, + SCROLLBAR_SIZE, + wih - ((hscrollbar->visible())?SCROLLBAR_SIZE:0)); + vscrollbar->Fl_Valuator::value(vscrollbar->clamp(vscrollbar->value())); + // Horizontal scrollbar + hscrollbar->bounds(0, table_w-tiw); + hscrollbar->precision(10); + hscrollbar->slider_size(hscrolltab); + hscrollbar->resize(wix, wiy+wih-SCROLLBAR_SIZE, + wiw - ((vscrollbar->visible())?SCROLLBAR_SIZE:0), + SCROLLBAR_SIZE); + hscrollbar->Fl_Valuator::value(hscrollbar->clamp(hscrollbar->value())); + } + + // Tell FLTK child widgets were resized + Fl_Group::init_sizes(); + + // Recalc top/bot/left/right + table_scrolled(); + + // DO *NOT* REDRAW -- LEAVE THIS UP TO THE CALLER + // redraw(); +} + +// Someone moved a scrollbar +void Fl_Table::scroll_cb(Fl_Widget*w, void *data) { + Fl_Table *o = (Fl_Table*)data; + o->recalc_dimensions(); // recalc tix, tiy, etc. + o->table_scrolled(); + o->redraw(); +} + +// Set number of rows +void Fl_Table::rows(int val) { + int oldrows = _rows; + _rows = val; + { + int default_h = ( _rowheights.size() > 0 ) ? _rowheights.back() : 25; + int now_size = _rowheights.size(); + _rowheights.size(val); // enlarge or shrink as needed + while ( now_size < val ) { + _rowheights[now_size++] = default_h; // fill new + } + } + table_resized(); + + // OPTIMIZATION: redraw only if change is visible. + if ( val >= oldrows && oldrows > botrow ) { + // NO REDRAW + } else { + redraw(); + } +} + +// Set number of cols +void Fl_Table::cols(int val) { + _cols = val; + { + int default_w = ( _colwidths.size() > 0 ) ? _colwidths[_colwidths.size()-1] : 80; + int now_size = _colwidths.size(); + _colwidths.size(val); // enlarge or shrink as needed + while ( now_size < val ) { + _colwidths[now_size++] = default_w; // fill new + } + } + table_resized(); + redraw(); +} + +// Change mouse cursor to different type +void Fl_Table::change_cursor(Fl_Cursor newcursor) { + if ( newcursor != _last_cursor ) { + fl_cursor(newcursor, FL_BLACK, FL_WHITE); + _last_cursor = newcursor; + } +} + +void Fl_Table::damage_zone(int r1, int c1, int r2, int c2, int r3, int c3) { + int R1 = r1, C1 = c1; + int R2 = r2, C2 = c2; + if (r1 > R2) R2 = r1; + if (r2 < R1) R1 = r2; + if (r3 > R2) R2 = r3; + if (r3 < R1) R1 = r3; + if (c1 > C2) C2 = c1; + if (c2 < C1) C1 = c2; + if (c3 > C2) C2 = c3; + if (c3 < C1) C1 = c3; + if (R1 < 0) { + if (R2 < 0) return; + R1 = 0; + } + if (C1 < 0) { + if (C2 < 0) return; + C1 = 0; + } + if (R1 < toprow) R1 = toprow; + if (R2 > botrow) R2 = botrow; + if (C1 < leftcol) C1 = leftcol; + if (C2 > rightcol) C2 = rightcol; + redraw_range(R1, R2, C1, C2); +} + +int Fl_Table::move_cursor(int R, int C) { + if (select_row == -1) R++; + if (select_col == -1) C++; + R += select_row; + C += select_col; + if (R < 0) R = 0; + if (R >= rows()) R = rows() - 1; + if (C < 0) C = 0; + if (C >= cols()) C = cols() - 1; + if (R == select_row && C == select_col) return 0; + damage_zone(current_row, current_col, select_row, select_col, R, C); + select_row = R; + select_col = C; + if (!Fl::event_state(FL_SHIFT)) { + current_row = R; + current_col = C; + } + if (R < toprow + 1 || R > botrow - 1) row_position(R); + if (C < leftcol + 1 || C > rightcol - 1) col_position(C); + return 1; +} + +// #define DEBUG 1 +#ifdef DEBUG +#include "eventnames.h" +#define PRINTEVENT \ +fprintf(stderr,"Table %s: ** Event: %s --\n", (label()?label():"none"), eventnames[event]); +#else +#define PRINTEVENT +#endif + +// Handle FLTK events +int Fl_Table::handle(int event) { + PRINTEVENT; + int ret = Fl_Group::handle(event); // let FLTK group handle events first + if (ret) { + if (Fl::event_inside(hscrollbar) || Fl::event_inside(vscrollbar)) return 1; + if (Fl::focus() != this && contains(Fl::focus())) return 1; + } + // Which row/column are we over? + int R, C; // row/column being worked on + ResizeFlag resizeflag; // which resizing area are we over? (0=none) + TableContext context = cursor2rowcol(R, C, resizeflag); + switch ( event ) { + case FL_PUSH: + if (Fl::event_button() == 1 && !Fl::event_clicks()) { + if (Fl::focus() != this) { + take_focus(); + do_callback(CONTEXT_TABLE, -1, -1); + ret = 1; + } + damage_zone(current_row, current_col, select_row, select_col, R, C); + if (context == CONTEXT_CELL) { + current_row = select_row = R; + current_col = select_col = C; + _selecting = CONTEXT_CELL; + } else { + current_row = select_row = -1; + current_col = select_col = -1; + } + } + // Need this for eg. right click to pop up a menu + if ( Fl_Widget::callback() && // callback defined? + resizeflag == RESIZE_NONE ) { // not resizing? + do_callback(context, R, C); // do callback + } + switch ( context ) { + case CONTEXT_CELL: + // FL_PUSH on a cell? + ret = 1; // express interest in FL_RELEASE + break; + + case CONTEXT_NONE: + // FL_PUSH on table corner? + if ( Fl::event_button() == 1 && + Fl::event_x() < x() + row_header_width()) { + current_col = 0; + select_col = cols() - 1; + current_row = 0; + select_row = rows() - 1; + damage_zone(current_row, current_col, select_row, select_col); + ret = 1; + } + break; + + case CONTEXT_COL_HEADER: + // FL_PUSH on a column header? + if ( Fl::event_button() == 1) { + // Resizing? Handle it + if ( resizeflag ) { + // Start resize if left click on column border. + // "ret=1" ensures we get drag events from now on. + // (C-1) is used if mouse is over the left hand side + // of cell, so we resize the next column on the left. + // + _resizing_col = ( resizeflag & RESIZE_COL_LEFT ) ? C-1 : C; + _resizing_row = -1; + _dragging_x = Fl::event_x(); + ret = 1; + } else { + // Not resizing? Select the column + current_col = select_col = C; + current_row = 0; + select_row = rows() - 1; + _selecting = CONTEXT_COL_HEADER; + damage_zone(current_row, current_col, select_row, select_col); + ret = 1; + } + } + break; + + case CONTEXT_ROW_HEADER: + // FL_PUSH on a row header? + if ( Fl::event_button() == 1 ) { + // Resizing? Handle it + if ( resizeflag ) { + // Start resize if left mouse clicked on row border. + // "ret = 1" ensures we get drag events from now on. + // (R-1) is used if mouse is over the top of the cell, + // so that we resize the row above. + // + _resizing_row = ( resizeflag & RESIZE_ROW_ABOVE ) ? R-1 : R; + _resizing_col = -1; + _dragging_y = Fl::event_y(); + ret = 1; + } else { + // Not resizing? Select the row + current_row = select_row = R; + current_col = 0; + select_col = cols() - 1; + _selecting = CONTEXT_ROW_HEADER; + damage_zone(current_row, current_col, select_row, select_col); + ret = 1; + } + } + break; + + default: + ret = 0; // express disinterest + break; + } + _last_row = R; + break; + + case FL_DRAG: + if (_auto_drag == 1) { + ret = 1; + break; + } + if ( _resizing_col > -1 ) { + // Dragging column? + // + // Let user drag even /outside/ the row/col widget. + // Don't allow column width smaller than 1. + // Continue to show FL_CURSOR_WE at all times during drag. + // + int offset = _dragging_x - Fl::event_x(); + int new_w = col_width(_resizing_col) - offset; + if ( new_w < _col_resize_min ) new_w = _col_resize_min; + col_width(_resizing_col, new_w); + _dragging_x = Fl::event_x(); + table_resized(); + redraw(); + change_cursor(FL_CURSOR_WE); + ret = 1; + if ( Fl_Widget::callback() && when() & FL_WHEN_CHANGED ) { + do_callback(CONTEXT_RC_RESIZE, R, C); + } + } + else if ( _resizing_row > -1 ) { + // Dragging row? + // + // Let user drag even /outside/ the row/col widget. + // Don't allow row width smaller than 1. + // Continue to show FL_CURSOR_NS at all times during drag. + // + int offset = _dragging_y - Fl::event_y(); + int new_h = row_height(_resizing_row) - offset; + if ( new_h < _row_resize_min ) new_h = _row_resize_min; + row_height(_resizing_row, new_h); + _dragging_y = Fl::event_y(); + table_resized(); + redraw(); + change_cursor(FL_CURSOR_NS); + ret = 1; + if ( Fl_Widget::callback() && when() & FL_WHEN_CHANGED ) { + do_callback(CONTEXT_RC_RESIZE, R, C); + } + } else { + if (Fl::event_button() == 1 && + _selecting == CONTEXT_CELL && + context == CONTEXT_CELL) { + if (select_row != R || select_col != C) { + damage_zone(current_row, current_col, select_row, select_col, R, C); + } + select_row = R; + select_col = C; + ret = 1; + } + else if (Fl::event_button() == 1 && + _selecting == CONTEXT_ROW_HEADER && + context & (CONTEXT_ROW_HEADER|CONTEXT_COL_HEADER|CONTEXT_CELL)) { + if (select_row != R) { + damage_zone(current_row, current_col, select_row, select_col, R, C); + } + select_row = R; + ret = 1; + } + else if (Fl::event_button() == 1 && + _selecting == CONTEXT_COL_HEADER + && context & (CONTEXT_ROW_HEADER|CONTEXT_COL_HEADER|CONTEXT_CELL)) { + if (select_col != C) { + damage_zone(current_row, current_col, select_row, select_col, R, C); + } + select_col = C; + ret = 1; + } + } + // Enable autodrag if not resizing, and mouse has moved off table edge + if ( _resizing_row < 0 && _resizing_col < 0 && _auto_drag == 0 && + ( Fl::event_x() > x() + w() - 20 || + Fl::event_x() < x() + row_header_width() || + Fl::event_y() > y() + h() - 20 || + Fl::event_y() < y() + col_header_height() + ) ) { + _start_auto_drag(); + } + break; + + case FL_RELEASE: + _stop_auto_drag(); + switch ( context ) { + case CONTEXT_ROW_HEADER: // release on row header + case CONTEXT_COL_HEADER: // release on col header + case CONTEXT_CELL: // release on a cell + case CONTEXT_TABLE: // release on dead zone + if ( _resizing_col == -1 && // not resizing a column + _resizing_row == -1 && // not resizing a row + Fl_Widget::callback() && // callback defined + when() & FL_WHEN_RELEASE && // on button release + _last_row == R ) { // release on same row PUSHed? + // Need this for eg. left clicking on a cell to select it + do_callback(context, R, C); + } + break; + + default: + break; + } + if ( Fl::event_button() == 1 ) { + change_cursor(FL_CURSOR_DEFAULT); + _resizing_col = -1; + _resizing_row = -1; + ret = 1; + } + break; + + case FL_MOVE: + if ( context == CONTEXT_COL_HEADER && // in column header? + resizeflag ) { // resize + near boundary? + change_cursor(FL_CURSOR_WE); // show resize cursor + } + else if ( context == CONTEXT_ROW_HEADER && // in row header? + resizeflag ) { // resize + near boundary? + change_cursor(FL_CURSOR_NS); // show resize cursor + } else { + change_cursor(FL_CURSOR_DEFAULT); // normal cursor + } + ret = 1; + break; + + case FL_ENTER: // See FLTK event docs on the FL_ENTER widget + if (!ret) take_focus(); + ret = 1; + //FALLTHROUGH + + case FL_LEAVE: // We want to track the mouse if resizing is allowed. + if ( resizeflag ) { + ret = 1; + } + if ( event == FL_LEAVE ) { + _stop_auto_drag(); + change_cursor(FL_CURSOR_DEFAULT); + } + break; + + case FL_FOCUS: + Fl::focus(this); + //FALLTHROUGH + + case FL_UNFOCUS: + _stop_auto_drag(); + ret = 1; + break; + + case FL_KEYBOARD: { + ret = 0; + int is_row = select_row; + int is_col = select_col; + switch(Fl::event_key()) { + case FL_Home: + ret = move_cursor(0, -1000000); + break; + case FL_End: + ret = move_cursor(0, 1000000); + break; + case FL_Page_Up: + ret = move_cursor(-(botrow - toprow - 1), 0); + break; + case FL_Page_Down: + ret = move_cursor(botrow - toprow - 1 , 0); + break; + case FL_Left: + ret = move_cursor(0, -1); + break; + case FL_Right: + ret = move_cursor(0, 1); + break; + case FL_Up: + ret = move_cursor(-1, 0); + break; + case FL_Down: + ret = move_cursor(1, 0); + break; + } + if (ret && Fl::focus() != this) { + do_callback(CONTEXT_TABLE, -1, -1); + take_focus(); + } + //if (!ret && Fl_Widget::callback() && when() & FL_WHEN_NOT_CHANGED ) + if ( Fl_Widget::callback() && + ( + ( !ret && when() & FL_WHEN_NOT_CHANGED ) || + ( is_row!= select_row || is_col!= select_col ) + ) + ) { + do_callback(CONTEXT_CELL, select_row, select_col); + //damage_zone(current_row, current_col, select_row, select_col); + ret = 1; + } + break; + } + + default: + change_cursor(FL_CURSOR_DEFAULT); + break; + } + return(ret); +} + +// Resize FLTK override +// Handle resize events if user resizes parent window. +// +void Fl_Table::resize(int X, int Y, int W, int H) { + // Tell group to resize, and recalc our own widget as well + Fl_Group::resize(X, Y, W, H); + table_resized(); + redraw(); +} + +// Draw a cell +void Fl_Table::_redraw_cell(TableContext context, int r, int c) { + if ( r < 0 || c < 0 ) return; + int X,Y,W,H; + find_cell(context, r, c, X, Y, W, H); // find positions of cell + draw_cell(context, r, c, X, Y, W, H); // call users' function to draw it +} + +int Fl_Table::is_selected(int r, int c) { + int s_left, s_right, s_top, s_bottom; + + if (select_col > current_col) { + s_left = current_col; + s_right = select_col; + } else { + s_right = current_col; + s_left = select_col; + } + if (select_row > current_row) { + s_top = current_row; + s_bottom = select_row; + } else { + s_bottom = current_row; + s_top = select_row; + } + if (r >= s_top && r <= s_bottom && c >= s_left && c <= s_right) { + return 1; + } + return 0; +} + +void Fl_Table::get_selection(int& s_top, int& s_left, int& s_bottom, int& s_right) { + if (select_col > current_col) { + s_left = current_col; + s_right = select_col; + } else { + s_right = current_col; + s_left = select_col; + } + if (select_row > current_row) { + s_top = current_row; + s_bottom = select_row; + } else { + s_bottom = current_row; + s_top = select_row; + } +} + +void Fl_Table::set_selection(int s_top, int s_left, int s_bottom, int s_right) { + damage_zone(current_row, current_col, select_row, select_col); + current_col = s_left; + current_row = s_top; + select_col = s_right; + select_row = s_bottom; + damage_zone(current_row, current_col, select_row, select_col); +} + +// Draw the entire Fl_Table +// Override the draw() routine to draw the table. +// Then tell the group to draw over us. +// +void Fl_Table::draw() { + draw_cell(CONTEXT_STARTPAGE, 0, 0, // let user's drawing routine + tix, tiy, tiw, tih); // prep new page + + // Let fltk widgets draw themselves first. Do this after + // draw_cell(CONTEXT_STARTPAGE) in case user moves widgets around. + // Use window 'inner' clip to prevent drawing into table border. + // (unfortunately this clips FLTK's border, so we must draw it explicity below) + // + fl_push_clip(wix, wiy, wiw, wih); + { + Fl_Group::draw(); + } + fl_pop_clip(); + + // Explicitly draw border around widget, if any + draw_box(box(), x(), y(), w(), h(), color()); + + // If Fl_Scroll 'table' is hidden, draw its box + // Do this after Fl_Group::draw() so we draw over scrollbars + // that leak around the border. + // + if ( ! table->visible() ) { + if ( damage() & FL_DAMAGE_ALL || damage() & FL_DAMAGE_CHILD ) { + draw_box(table->box(), tox, toy, tow, toh, table->color()); + } + } + // Clip all further drawing to the inner widget dimensions + fl_push_clip(wix, wiy, wiw, wih); + { + // Only redraw a few cells? + if ( ! ( damage() & FL_DAMAGE_ALL ) && _redraw_leftcol != -1 ) { + fl_push_clip(tix, tiy, tiw, tih); + for ( int c = _redraw_leftcol; c <= _redraw_rightcol; c++ ) { + for ( int r = _redraw_toprow; r <= _redraw_botrow; r++ ) { + _redraw_cell(CONTEXT_CELL, r, c); + } + } + fl_pop_clip(); + } + if ( damage() & FL_DAMAGE_ALL ) { + int X,Y,W,H; + // Draw row headers, if any + if ( row_header() ) { + get_bounds(CONTEXT_ROW_HEADER, X, Y, W, H); + fl_push_clip(X,Y,W,H); + for ( int r = toprow; r <= botrow; r++ ) { + _redraw_cell(CONTEXT_ROW_HEADER, r, 0); + } + fl_pop_clip(); + } + // Draw column headers, if any + if ( col_header() ) { + get_bounds(CONTEXT_COL_HEADER, X, Y, W, H); + fl_push_clip(X,Y,W,H); + for ( int c = leftcol; c <= rightcol; c++ ) { + _redraw_cell(CONTEXT_COL_HEADER, 0, c); + } + fl_pop_clip(); + } + // Draw all cells. + // This includes cells partially obscured off edges of table. + // No longer do this last; you might think it would be nice + // to draw over dead zones, but on redraws it flickers. Avoid + // drawing over deadzones; prevent deadzones by sizing columns. + // + fl_push_clip(tix, tiy, tiw, tih); { + for ( int r = toprow; r <= botrow; r++ ) { + for ( int c = leftcol; c <= rightcol; c++ ) { + _redraw_cell(CONTEXT_CELL, r, c); + } + } + } + fl_pop_clip(); + // Draw little rectangle in corner of headers + if ( row_header() && col_header() ) { + fl_rectf(wix, wiy, row_header_width(), col_header_height(), color()); + } + + // Table has a boxtype? Close those few dead pixels + if ( table->box() ) { + if ( col_header() ) { + fl_rectf(tox, wiy, Fl::box_dx(table->box()), col_header_height(), color()); + } + if ( row_header() ) { + fl_rectf(wix, toy, row_header_width(), Fl::box_dx(table->box()), color()); + } + } + + // Table width smaller than window? Fill remainder with rectangle + if ( table_w < tiw ) { + fl_rectf(tix + table_w, tiy, tiw - table_w, tih, color()); + // Col header? fill that too + if ( col_header() ) { + fl_rectf(tix + table_w, + wiy, + // get that corner just right.. + (tiw - table_w + Fl::box_dw(table->box()) - + Fl::box_dx(table->box())), + col_header_height(), + color()); + } + } + // Table height smaller than window? Fill remainder with rectangle + if ( table_h < tih ) { + fl_rectf(tix, tiy + table_h, tiw, tih - table_h, color()); + if ( row_header() ) { + // NOTE: + // Careful with that lower corner; don't use tih; when eg. + // table->box(FL_THIN_UPFRAME) and hscrollbar hidden, + // leaves a row of dead pixels. + // + fl_rectf(wix, tiy + table_h, row_header_width(), + (wiy+wih) - (tiy+table_h) - + ( hscrollbar->visible() ? SCROLLBAR_SIZE : 0), + color()); + } + } + } + // Both scrollbars? Draw little box in lower right + if ( vscrollbar->visible() && hscrollbar->visible() ) { + fl_rectf(vscrollbar->x(), hscrollbar->y(), + vscrollbar->w(), hscrollbar->h(), color()); + } + draw_cell(CONTEXT_ENDPAGE, 0, 0, // let user's drawing + tix, tiy, tiw, tih); // routines cleanup + + _redraw_leftcol = _redraw_rightcol = _redraw_toprow = _redraw_botrow = -1; + } + fl_pop_clip(); +} + +// +// End of "$Id: Fl_Table.cxx 7117 2010-02-20 21:14:47Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Table_Row.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Table_Row.cxx new file mode 100644 index 000000000..82b1ef64e --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Table_Row.cxx @@ -0,0 +1,323 @@ +// +// "$Id: Fl_Table_Row.cxx 6943 2009-11-18 12:43:21Z AlbrechtS $" +// +// Fl_Table_Row -- A row oriented table widget +// +// A class specializing in a table of rows. +// Handles row-specific selection behavior. +// +// Copyright 2002 by Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "erco at seriss dot com". +// +// +// TODO: +// o Row headings (only column headings supported currently) +// + +#include // for debugging +#include +#include +#include + +// Is row selected? +int Fl_Table_Row::row_selected(int row) { + if ( row < 0 || row >= rows() ) return(-1); + return(_rowselect[row]); +} + +// Change row selection type +void Fl_Table_Row::type(TableRowSelectMode val) { + _selectmode = val; + switch ( _selectmode ) { + case SELECT_NONE: + { + for ( int row=0; row 1 ) { // only one allowed + _rowselect[row] = 0; + } + } + } + redraw(); + break; + } + case SELECT_MULTI: + break; + } +} + +// Change selection state for row +// +// flag: +// 0 - clear selection +// 1 - set selection +// 2 - toggle selection +// +// Returns: +// 0 - selection state did not change +// 1 - selection state changed +// -1 - row out of range or incorrect selection mode +// +int Fl_Table_Row::select_row(int row, int flag) { + int ret = 0; + if ( row < 0 || row >= rows() ) { return(-1); } + switch ( _selectmode ) { + case SELECT_NONE: + return(-1); + + case SELECT_SINGLE: + { + int oldval; + for ( int t=0; t= toprow && row <= botrow ) { // row visible? + // Extend partial redraw range + redraw_range(row, row, leftcol, rightcol); + } + ret = 1; + } + } + } + return(ret); +} + +// Select all rows to a known state +void Fl_Table_Row::select_all_rows(int flag) { + switch ( _selectmode ) { + case SELECT_NONE: + return; + + case SELECT_SINGLE: + if ( flag != 0 ) return; + //FALLTHROUGH + + case SELECT_MULTI: + { + char changed = 0; + if ( flag == 2 ) { + for ( int row=0; row<(int)_rowselect.size(); row++ ) { + _rowselect[row] ^= 1; + } + changed = 1; + } else { + for ( int row=0; row<(int)_rowselect.size(); row++ ) { + changed |= (_rowselect[row] != flag)?1:0; + _rowselect[row] = flag; + } + } + if ( changed ) { + redraw(); + } + } + } +} + +// Set number of rows +void Fl_Table_Row::rows(int val) { + Fl_Table::rows(val); + while ( val > (int)_rowselect.size() ) { _rowselect.push_back(0); } // enlarge + while ( val < (int)_rowselect.size() ) { _rowselect.pop_back(); } // shrink +} + +// #include "eventnames.h" // debugging +// #include + +// Handle events +int Fl_Table_Row::handle(int event) { + + // fprintf(stderr, "** EVENT: %s: EVENT XY=%d,%d\n", + // eventnames[event], Fl::event_x(), Fl::event_y()); // debugging + + // Let base class handle event + int ret = Fl_Table::handle(event); + + // The following code disables cell selection.. why was it added? -erco 05/18/03 + // if ( ret ) { _last_y = Fl::event_y(); return(1); } // base class 'handled' it (eg. column resize) + + int shiftstate = (Fl::event_state() & FL_CTRL) ? FL_CTRL : + (Fl::event_state() & FL_SHIFT) ? FL_SHIFT : 0; + + // Which row/column are we over? + int R, C; // row/column being worked on + ResizeFlag resizeflag; // which resizing area are we over? (0=none) + TableContext context = cursor2rowcol(R, C, resizeflag); + switch ( event ) { + case FL_PUSH: + if ( Fl::event_button() == 1 ) { + _last_push_x = Fl::event_x(); // save regardless of context + _last_push_y = Fl::event_y(); // " " + + // Handle selection in table. + // Select cell under cursor, and enable drag selection mode. + // + if ( context == CONTEXT_CELL ) { + // Ctrl key? Toggle selection state + switch ( shiftstate ) { + case FL_CTRL: + select_row(R, 2); // toggle + break; + + case FL_SHIFT: + { + select_row(R, 1); + if ( _last_row > -1 ) { + int srow = R, erow = _last_row; + if ( srow > erow ) { + srow = _last_row; + erow = R; + } + for ( int row = srow; row <= erow; row++ ) { + select_row(row, 1); + } + } + break; + } + + default: + select_all_rows(0); // clear all previous selections + select_row(R, 1); + break; + } + + _last_row = R; + _dragging_select = 1; + ret = 1; // FL_PUSH handled (ensures FL_DRAG will be sent) + // redraw(); // redraw() handled by select_row() + } + } + break; + + case FL_DRAG: + { + if ( _dragging_select ) { + // Dragged off table edges? Handle scrolling + int offtop = toy - _last_y; // >0 if off top of table + int offbot = _last_y - (toy + toh); // >0 if off bottom of table + + if ( offtop > 0 && row_position() > 0 ) { + // Only scroll in upward direction + int diff = _last_y - Fl::event_y(); + if ( diff < 1 ) { + ret = 1; + break; + } + row_position(row_position() - diff); + context = CONTEXT_CELL; C = 0; R = row_position(); // HACK: fake it + if ( R < 0 || R > rows() ) { ret = 1; break; } // HACK: ugly + } + else if ( offbot > 0 && botrow < rows() ) { + // Only scroll in downward direction + int diff = Fl::event_y() - _last_y; + if ( diff < 1 ) { + ret = 1; + break; + } + row_position(row_position() + diff); + context = CONTEXT_CELL; C = 0; R = botrow; // HACK: fake it + if ( R < 0 || R > rows() ) { ret = 1; break; } // HACK: ugly + } + if ( context == CONTEXT_CELL ) { + switch ( shiftstate ) { + case FL_CTRL: + if ( R != _last_row ) { // toggle if dragged to new row + select_row(R, 2); // 2=toggle + } + break; + + case FL_SHIFT: + default: + select_row(R, 1); + if ( _last_row > -1 ) { + int srow = R, erow = _last_row; + if ( srow > erow ) { + srow = _last_row; + erow = R; + } + for ( int row = srow; row <= erow; row++ ) { + select_row(row, 1); + } + } + break; + } + ret = 1; // drag handled + _last_row = R; + } + } + break; + } + + case FL_RELEASE: + if ( Fl::event_button() == 1 ) { + _dragging_select = 0; + ret = 1; // release handled + // Clicked off edges of data table? + // A way for user to clear the current selection. + // + int databot = tiy + table_h, + dataright = tix + table_w; + if ( + ( _last_push_x > dataright && Fl::event_x() > dataright ) || + ( _last_push_y > databot && Fl::event_y() > databot ) + ) { + select_all_rows(0); // clear previous selections + } + } + break; + + default: + break; + } + _last_y = Fl::event_y(); + return(ret); +} + +// +// End of "$Id: Fl_Table_Row.cxx 6943 2009-11-18 12:43:21Z AlbrechtS $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Tabs.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Tabs.cxx index af05fd80f..bb5e54b20 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Tabs.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Tabs.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Tabs.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_Tabs.cxx 7162 2010-02-26 21:10:46Z matt $" // // Tab widget for the Fast Light Tool Kit (FLTK). // @@ -151,6 +151,7 @@ int Fl_Tabs::handle(int event) { } else { if (Fl::event_y() < y()+h()+H) return Fl_Group::handle(event); }} + /* FALLTHROUGH */ case FL_DRAG: case FL_RELEASE: o = which(Fl::event_x(), Fl::event_y()); @@ -161,8 +162,10 @@ int Fl_Tabs::handle(int event) { redraw_tabs(); } if (o && value(o)) { + Fl_Widget_Tracker wp(o); set_changed(); do_callback(); + if (wp.deleted()) return 1; } Fl_Tooltip::current(o); } else { @@ -423,5 +426,5 @@ Fl_Tabs::Fl_Tabs(int X,int Y,int W, int H, const char *l) : } // -// End of "$Id: Fl_Tabs.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_Tabs.cxx 7162 2010-02-26 21:10:46Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Text_Buffer.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Text_Buffer.cxx index 73f72f121..6e244a006 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Text_Buffer.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Text_Buffer.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Text_Buffer.cxx 6825 2009-07-04 05:18:29Z fabien $" +// "$Id: Fl_Text_Buffer.cxx 7672 2010-07-10 09:44:45Z matt $" // // Copyright 2001-2009 by Bill Spitzak and others. // Original code Copyright Mark Edel. Permission to distribute under @@ -33,81 +33,141 @@ #include #include +/* + This file is based on a port of NEdit to FLTK many years ago. NEdit at that + point was already stretched beyond the task it was designed for which explains + why the source code is sometimes pretty convoluted. It still is a nice widget + for FLTK. -static void histogramCharacters(const char *string, int length, char hist[ 256 ], - int init); -static void subsChars(char *string, int length, char fromChar, char toChar); -static char chooseNullSubsChar(char hist[ 256 ]); -static void insertColInLine(const char *line, char *insLine, int column, int insWidth, - int tabDist, int useTabs, char nullSubsChar, char *outStr, int *outLen, - int *endOffset); -static void deleteRectFromLine(const char *line, int rectStart, int rectEnd, - int tabDist, int useTabs, char nullSubsChar, char *outStr, int *outLen, - int *endOffset); -static void overlayRectInLine(const char *line, char *insLine, int rectStart, - int rectEnd, int tabDist, int useTabs, char nullSubsChar, char *outStr, - int *outLen, int *endOffset); + With the introduction of Unicode and UTF-8, Fl_Text_... has to go into a whole + new generation of code. Originally designed for monspaced fonts only, many + features make les sense in the multibyte and multiwdth world of UTF-8. + + Columns are a good example. There is simply no such thing. + + Rectangular selections pose a real problem. + + Using multiple spaces to emulate tab stops will no longer work. + + And constantly recalculating character widths is just much too expensive. + + But nevertheless, we will get ths widget rolling again ;-) + + */ + + +/* + \todo unicode check + */ +static void insertColInLine(const char *line, char *insLine, int column, + int insWidth, int tabDist, int useTabs, + char *outStr, int *outLen, + int *endOffset); + +/* + \todo unicode check + */ +static void deleteRectFromLine(const char *line, int rectStart, + int rectEnd, int tabDist, int useTabs, + char *outStr, + int *outLen, int *endOffset); + +/* + \todo unicode check + */ +static void overlayRectInLine(const char *line, char *insLine, + int rectStart, int rectEnd, int tabDist, + int useTabs, char *outStr, + int *outLen, int *endOffset); + +/* + \todo unicode check + */ static void addPadding(char *string, int startIndent, int toIndent, - int tabDist, int useTabs, char nullSubsChar, int *charsAdded); -static char *copyLine(const char* text, int *lineLen); + int tabDist, int useTabs, int *charsAdded); + +/* + \todo unicode check + */ +static char *copyLine(const char *text, int *lineLen); + +/* + unicode tested + */ static int countLines(const char *string); -static int textWidth(const char *text, int tabDist, char nullSubsChar); + +/* + \todo unicode check + */ +static int textWidth(const char *text, int tabDist); + +/* + \todo unicode check + */ static char *realignTabs(const char *text, int origIndent, int newIndent, - int tabDist, int useTabs, char nullSubsChar, int *newLength); -static char *expandTabs(const char *text, int startIndent, int tabDist, - char nullSubsChar, int *newLen); -static char *unexpandTabs(char *text, int startIndent, int tabDist, - char nullSubsChar, int *newLen); + int tabDist, int useTabs, int *newLength); + +/* + \todo unicode check + */ +static char *expandTabs(const char *text, int startIndent, int tabDist, int *newLen); + +/* + \todo unicode check + */ +static char *unexpandTabs(char *text, int startIndent, int tabDist, int *newLen); + #ifndef min -static int max(int i1, int i2) { + +static int max(int i1, int i2) +{ return i1 >= i2 ? i1 : i2; } -static int min(int i1, int i2) { +static int min(int i1, int i2) +{ return i1 <= i2 ? i1 : i2; } + #endif -static const char *ControlCodeTable[ 32 ] = { +static const char *ControlCodeTable[32] = { "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", "bs", "ht", "nl", "vt", "np", "cr", "so", "si", "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", - "can", "em", "sub", "esc", "fs", "gs", "rs", "us"}; + "can", "em", "sub", "esc", "fs", "gs", "rs", "us" +}; -static char* undobuffer; +static char *undobuffer; static int undobufferlength; -static Fl_Text_Buffer* undowidget; -static int undoat; // points after insertion -static int undocut; // number of characters deleted there -static int undoinsert; // number of characters inserted -static int undoyankcut; // length of valid contents of buffer, even if undocut=0 +static Fl_Text_Buffer *undowidget; +static int undoat; // points after insertion +static int undocut; // number of characters deleted there +static int undoinsert; // number of characters inserted +static int undoyankcut; // length of valid contents of buffer, even if undocut=0 -static void undobuffersize(int n) { +static void undobuffersize(int n) +{ if (n > undobufferlength) { if (undobuffer) { - do {undobufferlength *= 2;} while (undobufferlength < n); - undobuffer = (char*)realloc(undobuffer, undobufferlength); + do { + undobufferlength *= 2; + } while (undobufferlength < n); + undobuffer = (char *) realloc(undobuffer, undobufferlength); } else { - undobufferlength = n+9; - undobuffer = (char*)malloc(undobufferlength); + undobufferlength = n + 9; + undobuffer = (char *) malloc(undobufferlength); } } } -/** - Create an empty text buffer of a pre-determined size. - \param requestedSize use this to avoid unnecessary re-allocation - if you know exactly how much the buffer will need to hold - \param preferredGapSize Initial size for the buffer gap (empty space - in the buffer where text might be inserted - if the user is typing sequential chars) -*/ -/** Creates a new text buffer of the specified initial size.*/ -Fl_Text_Buffer::Fl_Text_Buffer(int requestedSize, int preferredGapSize) { +// unicode ok +Fl_Text_Buffer::Fl_Text_Buffer(int requestedSize, int preferredGapSize) +{ mLength = 0; mPreferredGapSize = preferredGapSize; - mBuf = (char *)malloc(requestedSize + mPreferredGapSize); + mBuf = (char *) malloc(requestedSize + mPreferredGapSize); mGapStart = 0; mGapEnd = mPreferredGapSize; mTabDist = 8; @@ -128,83 +188,89 @@ Fl_Text_Buffer::Fl_Text_Buffer(int requestedSize, int preferredGapSize) { mPredeleteProcs = NULL; mPredeleteCbArgs = NULL; mCursorPosHint = 0; - mNullSubsChar = '\0'; mCanUndo = 1; #ifdef PURIFY -{ int i; for (i = mGapStart; i < mGapEnd; i++) mBuf[ i ] = '.'; } + { + int i; + for (i = mGapStart; i < mGapEnd; i++) + mBuf[i] = '.'; + } #endif } -/** Frees a text buffer */ -Fl_Text_Buffer::~Fl_Text_Buffer() { + +// unicode ok +Fl_Text_Buffer::~Fl_Text_Buffer() +{ free(mBuf); if (mNModifyProcs != 0) { - delete[] mModifyProcs; - delete[] mCbArgs; + delete[]mModifyProcs; + delete[]mCbArgs; } if (mNPredeleteProcs != 0) { - delete[] mPredeleteProcs; - delete[] mPredeleteCbArgs; + delete[]mPredeleteProcs; + delete[]mPredeleteCbArgs; } } -/** - Get the entire contents of a text buffer. Memory is allocated to contain - the returned string, which the caller must free. -*/ -char * Fl_Text_Buffer::text() const { - char *t = (char *)malloc(mLength + 1); //UTF8: we alloc from a string len, but as (non-utf8 aware) strlen() - // is used to affect mLength, it is equal to buffer size - 1 and thus correct. + +// This function copies verbose whatever is in front and after the gap into a +// single buffer. +// - unicode ok +char *Fl_Text_Buffer::text() const { + char *t = (char *) malloc(mLength + 1); memcpy(t, mBuf, mGapStart); - memcpy(&t[ mGapStart ], &mBuf[ mGapEnd ], - mLength - mGapStart); - t[ mLength ] = '\0'; + memcpy(&t[mGapStart], &mBuf[mGapEnd], mLength - mGapStart); + t[mLength] = '\0'; return t; -} +} -/** Replaces the entire contents of the text buffer */ -void Fl_Text_Buffer::text(const char *t) { + +// unicode ok, functions called have not been verified yet +void Fl_Text_Buffer::text(const char *t) +{ call_predelete_callbacks(0, length()); - + /* Save information for redisplay, and get rid of the old buffer */ const char *deletedText = text(); int deletedLength = mLength; - free((void *)mBuf); - - /* Start a new buffer with a gap of mPreferredGapSize in the center */ + free((void *) mBuf); + + /* Start a new buffer with a gap of mPreferredGapSize at the end */ int insertedLength = strlen(t); - mBuf = (char *)malloc(insertedLength + mPreferredGapSize); + mBuf = (char *) malloc(insertedLength + mPreferredGapSize); mLength = insertedLength; - mGapStart = insertedLength / 2; + mGapStart = insertedLength; mGapEnd = mGapStart + mPreferredGapSize; - memcpy(mBuf, t, mGapStart); - memcpy(&mBuf[ mGapEnd ], &t[ mGapStart ], insertedLength - mGapStart); + memcpy(mBuf, t, insertedLength); #ifdef PURIFY -{ int i; for (i = mGapStart; i < mGapEnd; i++) mBuf[ i ] = '.'; } + { + int i; + for (i = mGapStart; i < mGapEnd; i++) + mBuf[i] = '.'; + } #endif - + /* Zero all of the existing selections */ update_selections(0, deletedLength, 0); - + /* Call the saved display routine(s) to update the screen */ call_modify_callbacks(0, deletedLength, insertedLength, 0, deletedText); - free((void *)deletedText); + free((void *) deletedText); } -/** - Return a copy of the text between \p start and \p end character positions - from text buffer \p buf. Positions start at 0, and the range does not - include the character pointed to by \p end. - When you are done with the text, free it using the free() function. -*/ -char * Fl_Text_Buffer::text_range(int start, int end) const { - char * s = NULL; +// Creates a new buffer and copies verbose from around the gap. +// - unicode ok +char *Fl_Text_Buffer::text_range(int start, int end) const { + char *s = NULL; + /* Make sure start and end are ok, and allocate memory for returned string. - If start is bad, return "", if end is bad, adjust it. */ - if (start < 0 || start > mLength) { - s = (char *)malloc(1); - s[ 0 ] = '\0'; + If start is bad, return "", if end is bad, adjust it. */ + if (start < 0 || start > mLength) + { + s = (char *) malloc(1); + s[0] = '\0'; return s; } if (end < start) { @@ -215,254 +281,255 @@ char * Fl_Text_Buffer::text_range(int start, int end) const { if (end > mLength) end = mLength; int copiedLength = end - start; - s = (char *)malloc(copiedLength + 1); - + s = (char *) malloc(copiedLength + 1); + /* Copy the text from the buffer to the returned string */ if (end <= mGapStart) { - memcpy(s, &mBuf[ start ], copiedLength); + memcpy(s, &mBuf[start], copiedLength); } else if (start >= mGapStart) { - memcpy(s, &mBuf[ start + (mGapEnd - mGapStart) ], copiedLength); + memcpy(s, &mBuf[start + (mGapEnd - mGapStart)], copiedLength); } else { int part1Length = mGapStart - start; - memcpy(s, &mBuf[ start ], part1Length); - memcpy(&s[ part1Length ], &mBuf[ mGapEnd ], copiedLength - part1Length); + memcpy(s, &mBuf[start], part1Length); + memcpy(&s[part1Length], &mBuf[mGapEnd], copiedLength - part1Length); } - s[ copiedLength ] = '\0'; + s[copiedLength] = '\0'; return s; } -/** Returns the character at the specified position pos in the buffer. - Positions start at 0 */ -char Fl_Text_Buffer::character(int pos) const { + +// TODO: we will need the same signature function to get bytes (style buffer) +// unicode ok +unsigned int Fl_Text_Buffer::character(int pos) const { if (pos < 0 || pos >= mLength) return '\0'; - if (pos < mGapStart) - return mBuf[ pos ]; - else - return mBuf[ pos + mGapEnd - mGapStart ]; -} + const char *src = address(pos); + return fl_utf8decode(src, 0, 0); +} -/** Inserts null-terminated string \p text at position \p pos. */ -void Fl_Text_Buffer::insert(int pos, const char *text) { + +// unicode ok, dependents not tested +void Fl_Text_Buffer::insert(int pos, const char *text) +{ /* if pos is not contiguous to existing text, make it */ - if (pos > mLength) pos = mLength; - if (pos < 0) pos = 0; - + if (pos > mLength) + pos = mLength; + if (pos < 0) + pos = 0; + /* Even if nothing is deleted, we must call these callbacks */ call_predelete_callbacks(pos, 0); - + /* insert and redisplay */ int nInserted = insert_(pos, text); mCursorPosHint = pos + nInserted; call_modify_callbacks(pos, 0, nInserted, 0, NULL); } -/** - Deletes the characters between \p start and \p end, and inserts the null-terminated string \p text in their place in the buffer. -*/ -void Fl_Text_Buffer::replace(int start, int end, const char *text) { - // Range check... - if (!text) return; - if (start < 0) start = 0; - if (end > mLength) end = mLength; - call_predelete_callbacks(start, end-start); - const char * deletedText = text_range(start, end); +// unicode ok, dependents not tested +void Fl_Text_Buffer::replace(int start, int end, const char *text) +{ + // Range check... + if (!text) + return; + if (start < 0) + start = 0; + if (end > mLength) + end = mLength; + + call_predelete_callbacks(start, end - start); + const char *deletedText = text_range(start, end); remove_(start, end); - //undoyankcut = undocut; int nInserted = insert_(start, text); mCursorPosHint = start + nInserted; call_modify_callbacks(start, end - start, nInserted, 0, deletedText); - free((void *)deletedText); + free((void *) deletedText); } -/** Deletes a range of characters in the buffer.*/ -void Fl_Text_Buffer::remove(int start, int end) { + +// unicode ok, dependents not tested +void Fl_Text_Buffer::remove(int start, int end) +{ /* Make sure the arguments make sense */ if (start > end) { int temp = start; start = end; end = temp; } - if (start > mLength) start = mLength; - if (start < 0) start = 0; - if (end > mLength) end = mLength; - if (end < 0) end = 0; - - if (start == end) return; - - call_predelete_callbacks(start, end-start); + if (start > mLength) + start = mLength; + if (start < 0) + start = 0; + if (end > mLength) + end = mLength; + if (end < 0) + end = 0; + + if (start == end) + return; + + call_predelete_callbacks(start, end - start); /* Remove and redisplay */ - const char * deletedText = text_range(start, end); + const char *deletedText = text_range(start, end); remove_(start, end); mCursorPosHint = start; call_modify_callbacks(start, end - start, 0, 0, deletedText); - free((void *)deletedText); + free((void *) deletedText); } -/** - Copies text from one buffer to this one; fromBuf may - be the same as this. -*/ -void Fl_Text_Buffer::copy(Fl_Text_Buffer *fromBuf, int fromStart, - int fromEnd, int toPos) { +void Fl_Text_Buffer::copy(Fl_Text_Buffer * fromBuf, int fromStart, + int fromEnd, int toPos) +{ int copiedLength = fromEnd - fromStart; - + /* Prepare the buffer to receive the new text. If the new text fits in - the current buffer, just move the gap (if necessary) to where - the text should be inserted. If the new text is too large, reallocate - the buffer with a gap large enough to accomodate the new text and a - gap of mPreferredGapSize */ + the current buffer, just move the gap (if necessary) to where + the text should be inserted. If the new text is too large, reallocate + the buffer with a gap large enough to accomodate the new text and a + gap of mPreferredGapSize */ if (copiedLength > mGapEnd - mGapStart) reallocate_with_gap(toPos, copiedLength + mPreferredGapSize); else if (toPos != mGapStart) move_gap(toPos); - + /* Insert the new text (toPos now corresponds to the start of the gap) */ if (fromEnd <= fromBuf->mGapStart) { - memcpy(&mBuf[ toPos ], &fromBuf->mBuf[ fromStart ], copiedLength); + memcpy(&mBuf[toPos], &fromBuf->mBuf[fromStart], copiedLength); } else if (fromStart >= fromBuf->mGapStart) { - memcpy(&mBuf[ toPos ], - &fromBuf->mBuf[ fromStart + (fromBuf->mGapEnd - fromBuf->mGapStart) ], - copiedLength); + memcpy(&mBuf[toPos], + &fromBuf->mBuf[fromStart + + (fromBuf->mGapEnd - fromBuf->mGapStart)], + copiedLength); } else { int part1Length = fromBuf->mGapStart - fromStart; - memcpy(&mBuf[ toPos ], &fromBuf->mBuf[ fromStart ], part1Length); - memcpy(&mBuf[ toPos + part1Length ], &fromBuf->mBuf[ fromBuf->mGapEnd ], - copiedLength - part1Length); + memcpy(&mBuf[toPos], &fromBuf->mBuf[fromStart], part1Length); + memcpy(&mBuf[toPos + part1Length], + &fromBuf->mBuf[fromBuf->mGapEnd], copiedLength - part1Length); } mGapStart += copiedLength; mLength += copiedLength; update_selections(toPos, 0, copiedLength); } -/** - Undo text modification according to the undo variables or insert text - from the undo buffer -*/ -int Fl_Text_Buffer::undo(int *cursorPos) { - if (undowidget != this || !undocut && !undoinsert &&!mCanUndo) return 0; - +int Fl_Text_Buffer::undo(int *cursorPos) +{ + if (undowidget != this || !undocut && !undoinsert && !mCanUndo) + return 0; + int ilen = undocut; int xlen = undoinsert; - int b = undoat-xlen; - + int b = undoat - xlen; + if (xlen && undoyankcut && !ilen) { ilen = undoyankcut; } - + if (xlen && ilen) { - undobuffersize(ilen+1); + undobuffersize(ilen + 1); undobuffer[ilen] = 0; char *tmp = strdup(undobuffer); replace(b, undoat, tmp); - if (cursorPos) *cursorPos = mCursorPosHint; + if (cursorPos) + *cursorPos = mCursorPosHint; free(tmp); - } - else if (xlen) { + } else if (xlen) { remove(b, undoat); - if (cursorPos) *cursorPos = mCursorPosHint; - } - else if (ilen) { - undobuffersize(ilen+1); + if (cursorPos) + *cursorPos = mCursorPosHint; + } else if (ilen) { + undobuffersize(ilen + 1); undobuffer[ilen] = 0; insert(undoat, undobuffer); - if (cursorPos) *cursorPos = mCursorPosHint; + if (cursorPos) + *cursorPos = mCursorPosHint; undoyankcut = 0; } - + return 1; } -/** Lets the undo system know if we can undo changes */ -void Fl_Text_Buffer::canUndo(char flag) { + +// unicode ok +void Fl_Text_Buffer::canUndo(char flag) +{ mCanUndo = flag; } -/** - Insert \p s columnwise into buffer starting at displayed character - position \p column on the line beginning at \p startPos. Opens a rectangular - space the width and height of \p s, by moving all text to the right of - \p column right. If \p charsInserted and \p charsDeleted are not NULL, the - number of characters inserted and deleted in the operation (beginning - at \p startPos) are returned in these arguments. -*/ -void Fl_Text_Buffer::insert_column(int column, int startPos, const char *text, - int *charsInserted, int *charsDeleted) { - int nLines = countLines(text); - int lineStartPos = line_start(startPos); - int nDeleted = line_end(skip_lines(startPos, nLines)) - - lineStartPos; - call_predelete_callbacks(lineStartPos, nDeleted); - const char *deletedText = text_range(lineStartPos, lineStartPos + nDeleted); - int insertDeleted, nInserted; - insert_column_(column, lineStartPos, text, &insertDeleted, &nInserted, - &mCursorPosHint); - if (nDeleted != insertDeleted) - Fl::error("Fl_Text_Buffer::insert_column(): internal consistency check ins1 failed"); - call_modify_callbacks(lineStartPos, nDeleted, nInserted, 0, deletedText); - free((void *) deletedText); - if (charsInserted != NULL) - * charsInserted = nInserted; - if (charsDeleted != NULL) - * charsDeleted = nDeleted; -} - -/** - Overlay \p text between displayed character positions \p rectStart and - \p rectEnd on the line beginning at \p startPos. If \p charsInserted and - \p charsDeleted are not NULL, the number of characters inserted and deleted - in the operation (beginning at \p startPos) are returned in these arguments. -*/ -void Fl_Text_Buffer::overlay_rectangular(int startPos, int rectStart, - int rectEnd, const char *text, int *charsInserted, int *charsDeleted) { - +void Fl_Text_Buffer::insert_column(int column, int startPos, + const char *text, int *charsInserted, + int *charsDeleted) +{ int nLines = countLines(text); int lineStartPos = line_start(startPos); int nDeleted = line_end(skip_lines(startPos, nLines)) - lineStartPos; call_predelete_callbacks(lineStartPos, nDeleted); - const char *deletedText = text_range(lineStartPos, lineStartPos + nDeleted); + const char *deletedText = + text_range(lineStartPos, lineStartPos + nDeleted); int insertDeleted, nInserted; - overlay_rectangular_(lineStartPos, rectStart, rectEnd, text, &insertDeleted, - &nInserted, &mCursorPosHint); + insert_column_(column, lineStartPos, text, &insertDeleted, &nInserted, + &mCursorPosHint); if (nDeleted != insertDeleted) - Fl::error("Fl_Text_Buffer::overlay_rectangle(): internal consistency check ovly1 failed"); + Fl::error + ("Fl_Text_Buffer::insert_column(): internal consistency check ins1 failed"); call_modify_callbacks(lineStartPos, nDeleted, nInserted, 0, deletedText); free((void *) deletedText); if (charsInserted != NULL) - * charsInserted = nInserted; + *charsInserted = nInserted; if (charsDeleted != NULL) - * charsDeleted = nDeleted; + *charsDeleted = nDeleted; } -/** - Replaces a rectangular area in the buffer, given by \p start, \p end, - \p rectStart, and \p rectEnd, with \p text. If \p text is vertically - longer than the rectangle, add extra lines to make room for it. -*/ -void Fl_Text_Buffer::replace_rectangular(int start, int end, int rectStart, - int rectEnd, const char *text) { - char *insText = (char *)""; - int linesPadded = 0; +void Fl_Text_Buffer::overlay_rectangular(int startPos, int rectStart, + int rectEnd, const char *text, + int *charsInserted, + int *charsDeleted) +{ + + int nLines = countLines(text); + int lineStartPos = line_start(startPos); + int nDeleted = line_end(skip_lines(startPos, nLines)) - lineStartPos; + call_predelete_callbacks(lineStartPos, nDeleted); + const char *deletedText = + text_range(lineStartPos, lineStartPos + nDeleted); + int insertDeleted, nInserted; + overlay_rectangular_(lineStartPos, rectStart, rectEnd, text, + &insertDeleted, &nInserted, &mCursorPosHint); + if (nDeleted != insertDeleted) + Fl::error + ("Fl_Text_Buffer::overlay_rectangle(): internal consistency check ovly1 failed"); + call_modify_callbacks(lineStartPos, nDeleted, nInserted, 0, deletedText); + free((void *) deletedText); + if (charsInserted != NULL) + *charsInserted = nInserted; + if (charsDeleted != NULL) + *charsDeleted = nDeleted; +} +void Fl_Text_Buffer::replace_rectangular(int start, int end, int rectStart, + int rectEnd, const char *text) +{ + char *insText = (char *) ""; + int linesPadded = 0; + /* Make sure start and end refer to complete lines, since the - columnar delete and insert operations will replace whole lines */ + columnar delete and insert operations will replace whole lines */ start = line_start(start); end = line_end(end); - - call_predelete_callbacks(start, end-start); - + + call_predelete_callbacks(start, end - start); + /* If more lines will be deleted than inserted, pad the inserted text - with newlines to make it as long as the number of deleted lines. This - will indent all of the text to the right of the rectangle to the same - column. If more lines will be inserted than deleted, insert extra - lines in the buffer at the end of the rectangle to make room for the - additional lines in "text" */ + with newlines to make it as long as the number of deleted lines. This + will indent all of the text to the right of the rectangle to the same + column. If more lines will be inserted than deleted, insert extra + lines in the buffer at the end of the rectangle to make room for the + additional lines in "text" */ int nInsertedLines = countLines(text); int nDeletedLines = count_lines(start, end); if (nInsertedLines < nDeletedLines) { int insLen = strlen(text); - insText = (char *)malloc(insLen + nDeletedLines - nInsertedLines + 1); + insText = (char *) malloc(insLen + nDeletedLines - nInsertedLines + 1); strcpy(insText, text); char *insPtr = insText + insLen; for (int i = 0; i < nDeletedLines - nInsertedLines; i++) @@ -472,77 +539,72 @@ void Fl_Text_Buffer::replace_rectangular(int start, int end, int rectStart, linesPadded = nInsertedLines - nDeletedLines; for (int i = 0; i < linesPadded; i++) insert_(end, "\n"); - } /* else nDeletedLines == nInsertedLines; */ - + } + + /* else nDeletedLines == nInsertedLines; */ /* Save a copy of the text which will be modified for the modify CBs */ const char *deletedText = text_range(start, end); - + /* Delete then insert */ int insertDeleted, insertInserted, deleteInserted, hint; - remove_rectangular_(start, end, rectStart, rectEnd, &deleteInserted, &hint); - insert_column_(rectStart, start, insText, &insertDeleted, &insertInserted, - &mCursorPosHint); - + remove_rectangular_(start, end, rectStart, rectEnd, &deleteInserted, + &hint); + insert_column_(rectStart, start, insText, &insertDeleted, + &insertInserted, &mCursorPosHint); + /* Figure out how many chars were inserted and call modify callbacks */ if (insertDeleted != deleteInserted + linesPadded) - Fl::error("Fl_Text_Buffer::replace_rectangular(): internal consistency check repl1 failed"); - call_modify_callbacks(start, end - start, insertInserted, 0, deletedText); + Fl::error + ("Fl_Text_Buffer::replace_rectangular(): internal consistency check repl1 failed"); + call_modify_callbacks(start, end - start, insertInserted, 0, + deletedText); free((void *) deletedText); if (nInsertedLines < nDeletedLines) free((void *) insText); } -/** - Removes a rectangular swath of characters between character positions start - and end and horizontal displayed-character offsets rectStart and rectEnd. -*/ void Fl_Text_Buffer::remove_rectangular(int start, int end, int rectStart, - int rectEnd) { - + int rectEnd) +{ + start = line_start(start); end = line_end(end); - call_predelete_callbacks(start, end-start); - const char * deletedText = text_range(start, end); + call_predelete_callbacks(start, end - start); + const char *deletedText = text_range(start, end); int nInserted; remove_rectangular_(start, end, rectStart, rectEnd, &nInserted, - &mCursorPosHint); + &mCursorPosHint); call_modify_callbacks(start, end - start, nInserted, 0, deletedText); free((void *) deletedText); } -/** - Clears text in the specified area. - It clears a rectangular "hole" out of the buffer between character positions - start and end and horizontal displayed-character offsets rectStart and - rectEnd. -*/ void Fl_Text_Buffer::clear_rectangular(int start, int end, int rectStart, - int rectEnd) { + int rectEnd) +{ int nLines = count_lines(start, end); - char *newlineString = (char *)malloc(nLines + 1); + char *newlineString = (char *) malloc(nLines + 1); int i; for (i = 0; i < nLines; i++) - newlineString[ i ] = '\n'; - newlineString[ i ] = '\0'; + newlineString[i] = '\n'; + newlineString[i] = '\0'; overlay_rectangular(start, rectStart, rectEnd, newlineString, - NULL, NULL); + NULL, NULL); free((void *) newlineString); } -/** - Returns the text from the given rectangle. When you are done - with the text, free it using the free() function. -*/ -char * Fl_Text_Buffer::text_in_rectangle(int start, int end, - int rectStart, int rectEnd) const { + +char *Fl_Text_Buffer::text_in_rectangle(int start, int end, + int rectStart, + int rectEnd) const { start = line_start(start); end = line_end(end); - char *textOut = (char *)malloc((end - start) + 1); + char *textOut = (char *) malloc((end - start) + 1); int lineStart = start; char *outPtr = textOut; int selLeft, selRight; - while (lineStart <= end) { + while (lineStart <= end) + { rectangular_selection_boundaries(lineStart, rectStart, rectEnd, - &selLeft, &selRight); + &selLeft, &selRight); const char *textIn = text_range(selLeft, selRight); int len = selRight - selLeft; memcpy(outPtr, textIn, len); @@ -550,652 +612,624 @@ char * Fl_Text_Buffer::text_in_rectangle(int start, int end, outPtr += len; lineStart = line_end(selRight) + 1; *outPtr++ = '\n'; - } - if (outPtr != textOut) - outPtr--; /* don't leave trailing newline */ + } if (outPtr != textOut) + outPtr--; /* don't leave trailing newline */ *outPtr = '\0'; - + /* If necessary, realign the tabs in the selection as if the text were - positioned at the left margin */ + positioned at the left margin */ int len; char *retabbedStr = realignTabs(textOut, rectStart, 0, mTabDist, - mUseTabs, mNullSubsChar, &len); + mUseTabs, &len); free((void *) textOut); return retabbedStr; } -/** - Set the hardware tab distance (width) used by all displays for this buffer, - and used in computing offsets for rectangular selection operations. -*/ -void Fl_Text_Buffer::tab_distance(int tabDist) { - /* First call the pre-delete callbacks with the previous tab setting - still active. */ +void Fl_Text_Buffer::tab_distance(int tabDist) +{ + /* First call the pre-delete callbacks with the previous tab setting + still active. */ call_predelete_callbacks(0, mLength); - + /* Change the tab setting */ mTabDist = tabDist; - + /* Force any display routines to redisplay everything (unfortunately, - this means copying the whole buffer contents to provide "deletedText" */ - const char * deletedText = text(); + this means copying the whole buffer contents to provide "deletedText" */ + const char *deletedText = text(); call_modify_callbacks(0, mLength, mLength, 0, deletedText); free((void *) deletedText); } -/** Selects a range of characters in the buffer.*/ -void Fl_Text_Buffer::select(int start, int end) { +void Fl_Text_Buffer::select(int start, int end) +{ Fl_Text_Selection oldSelection = mPrimary; - + mPrimary.set(start, end); redisplay_selection(&oldSelection, &mPrimary); } -/** Cancels any previous selection on the primary text selection object */ -void Fl_Text_Buffer::unselect() { - Fl_Text_Selection oldSelection = mPrimary; +void Fl_Text_Buffer::unselect() +{ + Fl_Text_Selection oldSelection = mPrimary; + mPrimary.mSelected = 0; redisplay_selection(&oldSelection, &mPrimary); } -/** Achieves a rectangular selection on the primary text selection object */ -void Fl_Text_Buffer::select_rectangular(int start, int end, int rectStart, - int rectEnd) { - Fl_Text_Selection oldSelection = mPrimary; +void Fl_Text_Buffer::select_rectangular(int start, int end, int rectStart, + int rectEnd) +{ + Fl_Text_Selection oldSelection = mPrimary; + mPrimary.set_rectangular(start, end, rectStart, rectEnd); redisplay_selection(&oldSelection, &mPrimary); } -/** Gets the selection position */ -int Fl_Text_Buffer::selection_position(int *start, int *end) { +int Fl_Text_Buffer::selection_position(int *start, int *end) +{ return mPrimary.position(start, end); } -/** Gets the selection position, and rectangular selection info */ + int Fl_Text_Buffer::selection_position(int *start, int *end, - int *isRect, int *rectStart, int *rectEnd) { + int *isRect, int *rectStart, + int *rectEnd) +{ return mPrimary.position(start, end, isRect, rectStart, rectEnd); } -/** - Returns the currently selected text. When you are done with - the text, free it using the free() function. -*/ -char * Fl_Text_Buffer::selection_text() { +char *Fl_Text_Buffer::selection_text() +{ return selection_text_(&mPrimary); } -/** Removes the text in the primary selection.*/ -void Fl_Text_Buffer::remove_selection() { +void Fl_Text_Buffer::remove_selection() +{ remove_selection_(&mPrimary); } -/** Replaces the text in the primary selection.*/ -void Fl_Text_Buffer::replace_selection(const char *text) { + +void Fl_Text_Buffer::replace_selection(const char *text) +{ replace_selection_(&mPrimary, text); } -/** Selects a range of characters in the secondary selection.*/ -void Fl_Text_Buffer::secondary_select(int start, int end) { +void Fl_Text_Buffer::secondary_select(int start, int end) +{ Fl_Text_Selection oldSelection = mSecondary; - + mSecondary.set(start, end); redisplay_selection(&oldSelection, &mSecondary); } -/** Cancels any previous selection on the primary text selection object */ -void Fl_Text_Buffer::secondary_unselect() { - Fl_Text_Selection oldSelection = mSecondary; +void Fl_Text_Buffer::secondary_unselect() +{ + Fl_Text_Selection oldSelection = mSecondary; + mSecondary.mSelected = 0; redisplay_selection(&oldSelection, &mSecondary); } -/** Achieves a rectangular selection on the secondary text selection object */ void Fl_Text_Buffer::secondary_select_rectangular(int start, int end, - int rectStart, int rectEnd) { + int rectStart, + int rectEnd) +{ Fl_Text_Selection oldSelection = mSecondary; - + mSecondary.set_rectangular(start, end, rectStart, rectEnd); redisplay_selection(&oldSelection, &mSecondary); } -/** Returns the current selection in the secondary text selection object.*/ -int Fl_Text_Buffer::secondary_selection_position(int *start, int *end - ) { + +int Fl_Text_Buffer::secondary_selection_position(int *start, int *end) +{ return mSecondary.position(start, end); } -/** Returns the current selection in the secondary text selection object.*/ + int Fl_Text_Buffer::secondary_selection_position(int *start, int *end, - int *isRect, int *rectStart, int *rectEnd) { - return mSecondary.position(start, end, isRect, rectStart, - rectEnd); + int *isRect, + int *rectStart, + int *rectEnd) +{ + return mSecondary.position(start, end, isRect, rectStart, rectEnd); } -/** - Returns the text in the secondary selection. When you are - done with the text, free it using the free() function. -*/ -char * Fl_Text_Buffer::secondary_selection_text() { +char *Fl_Text_Buffer::secondary_selection_text() +{ return selection_text_(&mSecondary); } -/** Removes the text from the buffer corresponding to the secondary text selection object.*/ -void Fl_Text_Buffer::remove_secondary_selection() { + +void Fl_Text_Buffer::remove_secondary_selection() +{ remove_selection_(&mSecondary); } -/** Replaces the text from the buffer corresponding to the secondary - text selection object with the new string \p text.*/ -void Fl_Text_Buffer::replace_secondary_selection(const char *text) { + +void Fl_Text_Buffer::replace_secondary_selection(const char *text) +{ replace_selection_(&mSecondary, text); } -/** Highlights the specified text within the buffer.*/ -void Fl_Text_Buffer::highlight(int start, int end) { +void Fl_Text_Buffer::highlight(int start, int end) +{ Fl_Text_Selection oldSelection = mHighlight; - + mHighlight.set(start, end); redisplay_selection(&oldSelection, &mHighlight); } -/** Unhighlights text in the buffer.*/ -void Fl_Text_Buffer::unhighlight() { +void Fl_Text_Buffer::unhighlight() +{ Fl_Text_Selection oldSelection = mHighlight; - + mHighlight.mSelected = 0; redisplay_selection(&oldSelection, &mHighlight); } -/** Highlights a rectangular selection in the buffer */ -void Fl_Text_Buffer::highlight_rectangular(int start, int end, - int rectStart, int rectEnd) { - Fl_Text_Selection oldSelection = mHighlight; +void Fl_Text_Buffer::highlight_rectangular(int start, int end, + int rectStart, int rectEnd) +{ + Fl_Text_Selection oldSelection = mHighlight; + mHighlight.set_rectangular(start, end, rectStart, rectEnd); redisplay_selection(&oldSelection, &mHighlight); } -/** Highlights the specified text between \p start and \p end within the buffer.*/ -int Fl_Text_Buffer::highlight_position(int *start, int *end - ) { + +int Fl_Text_Buffer::highlight_position(int *start, int *end) +{ return mHighlight.position(start, end); } -/** Highlights the specified rectangle of text within the buffer.*/ + int Fl_Text_Buffer::highlight_position(int *start, int *end, - int *isRect, int *rectStart, int *rectEnd) { - return mHighlight.position(start, end, isRect, rectStart, - rectEnd); + int *isRect, int *rectStart, + int *rectEnd) +{ + return mHighlight.position(start, end, isRect, rectStart, rectEnd); } -/** - Returns the highlighted text. When you are done with the - text, free it using the free() function. -*/ -char * Fl_Text_Buffer::highlight_text() { +char *Fl_Text_Buffer::highlight_text() +{ return selection_text_(&mHighlight); } -/** - Adds a callback function that is called whenever the text buffer is - modified. The callback function is declared as follows: - - \code - typedef void (*Fl_Text_Modify_Cb)(int pos, int nInserted, int nDeleted, - int nRestyled, const char* deletedText, - void* cbArg); - \endcode -*/ void Fl_Text_Buffer::add_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, - void *cbArg) { - Fl_Text_Modify_Cb * newModifyProcs = new Fl_Text_Modify_Cb [ mNModifyProcs + 1 ]; - void* *newCBArgs = new void* [ mNModifyProcs + 1 ]; + void *cbArg) +{ + Fl_Text_Modify_Cb *newModifyProcs = + new Fl_Text_Modify_Cb[mNModifyProcs + 1]; + void **newCBArgs = new void *[mNModifyProcs + 1]; for (int i = 0; i < mNModifyProcs; i++) { - newModifyProcs[ i + 1 ] = mModifyProcs[ i ]; - newCBArgs[ i + 1 ] = mCbArgs[ i ]; + newModifyProcs[i + 1] = mModifyProcs[i]; + newCBArgs[i + 1] = mCbArgs[i]; } if (mNModifyProcs != 0) { - delete [] mModifyProcs; - delete [] mCbArgs; + delete[]mModifyProcs; + delete[]mCbArgs; } - newModifyProcs[ 0 ] = bufModifiedCB; - newCBArgs[ 0 ] = cbArg; + newModifyProcs[0] = bufModifiedCB; + newCBArgs[0] = cbArg; mNModifyProcs++; mModifyProcs = newModifyProcs; mCbArgs = newCBArgs; } -/** Removes a modify callback.*/ -void Fl_Text_Buffer::remove_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, - void *cbArg) { - int i, toRemove = -1; +void Fl_Text_Buffer:: +remove_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void *cbArg) +{ + int i, toRemove = -1; + /* find the matching callback to remove */ for (i = 0; i < mNModifyProcs; i++) { - if (mModifyProcs[ i ] == bufModifiedCB && mCbArgs[ i ] == cbArg) { + if (mModifyProcs[i] == bufModifiedCB && mCbArgs[i] == cbArg) { toRemove = i; break; } } if (toRemove == -1) { - Fl::error("Fl_Text_Buffer::remove_modify_callback(): Can't find modify CB to remove"); + Fl::error + ("Fl_Text_Buffer::remove_modify_callback(): Can't find modify CB to remove"); return; } - + /* Allocate new lists for remaining callback procs and args (if - any are left) */ + any are left) */ mNModifyProcs--; if (mNModifyProcs == 0) { mNModifyProcs = 0; - delete[] mModifyProcs; + delete[]mModifyProcs; mModifyProcs = NULL; - delete[] mCbArgs; + delete[]mCbArgs; mCbArgs = NULL; return; } - Fl_Text_Modify_Cb *newModifyProcs = new Fl_Text_Modify_Cb [ mNModifyProcs ]; - void * *newCBArgs = new void* [ mNModifyProcs ]; - + Fl_Text_Modify_Cb *newModifyProcs = new Fl_Text_Modify_Cb[mNModifyProcs]; + void **newCBArgs = new void *[mNModifyProcs]; + /* copy out the remaining members and free the old lists */ for (i = 0; i < toRemove; i++) { - newModifyProcs[ i ] = mModifyProcs[ i ]; - newCBArgs[ i ] = mCbArgs[ i ]; + newModifyProcs[i] = mModifyProcs[i]; + newCBArgs[i] = mCbArgs[i]; } for (; i < mNModifyProcs; i++) { - newModifyProcs[ i ] = mModifyProcs[ i + 1 ]; - newCBArgs[ i ] = mCbArgs[ i + 1 ]; + newModifyProcs[i] = mModifyProcs[i + 1]; + newCBArgs[i] = mCbArgs[i + 1]; } - delete[] mModifyProcs; - delete[] mCbArgs; + delete[]mModifyProcs; + delete[]mCbArgs; mModifyProcs = newModifyProcs; mCbArgs = newCBArgs; } -/** Adds a callback routine to be called before text is deleted from the buffer. */ -void Fl_Text_Buffer::add_predelete_callback(Fl_Text_Predelete_Cb bufPreDeleteCB, - void *cbArg) { - Fl_Text_Predelete_Cb *newPreDeleteProcs = new Fl_Text_Predelete_Cb[ mNPredeleteProcs + 1 ]; - void* *newCBArgs = new void * [ mNPredeleteProcs + 1 ]; - for (int i = 0; i < mNPredeleteProcs; i++) { - newPreDeleteProcs[i + 1] = mPredeleteProcs[i]; - newCBArgs[i + 1] = mPredeleteCbArgs[i]; - } - if (! mNPredeleteProcs != 0) { - delete [] mPredeleteProcs; - delete [] mPredeleteCbArgs; - } - newPreDeleteProcs[0] = bufPreDeleteCB; - newCBArgs[0] = cbArg; - mNPredeleteProcs++; - mPredeleteProcs = newPreDeleteProcs; - mPredeleteCbArgs = newCBArgs; -} -/** Removes a callback routine \p bufPreDeleteCB associated with argument \p cbArg - to be called before text is deleted from the buffer. */ -void Fl_Text_Buffer::remove_predelete_callback( - Fl_Text_Predelete_Cb bufPreDeleteCB, void *cbArg) { - int i, toRemove = -1; - /* find the matching callback to remove */ - for (i = 0; i < mNPredeleteProcs; i++) { - if (mPredeleteProcs[i] == bufPreDeleteCB && - mPredeleteCbArgs[i] == cbArg) { - toRemove = i; - break; - } - } - if (toRemove == -1) { - Fl::error("Fl_Text_Buffer::remove_predelete_callback(): Can't find pre-delete CB to remove"); - return; - } - - /* Allocate new lists for remaining callback procs and args (if - any are left) */ - mNPredeleteProcs--; - if (mNPredeleteProcs == 0) { - mNPredeleteProcs = 0; - delete[] mPredeleteProcs; - mPredeleteProcs = NULL; - delete[] mPredeleteCbArgs; - mPredeleteCbArgs = NULL; - return; - } - Fl_Text_Predelete_Cb *newPreDeleteProcs = new Fl_Text_Predelete_Cb [ mNPredeleteProcs ]; - void* *newCBArgs = new void* [ mNPredeleteProcs ]; - - /* copy out the remaining members and free the old lists */ - for (i = 0; i < toRemove; i++) { - newPreDeleteProcs[i] = mPredeleteProcs[i]; - newCBArgs[i] = mPredeleteCbArgs[i]; - } - for (; i < mNPredeleteProcs; i++) { - newPreDeleteProcs[i] = mPredeleteProcs[i+1]; - newCBArgs[i] = mPredeleteCbArgs[i+1]; - } - delete[] mPredeleteProcs; - delete[] mPredeleteCbArgs; - mPredeleteProcs = newPreDeleteProcs; - mPredeleteCbArgs = newCBArgs; +void Fl_Text_Buffer:: +add_predelete_callback(Fl_Text_Predelete_Cb bufPreDeleteCB, void *cbArg) +{ + Fl_Text_Predelete_Cb *newPreDeleteProcs = + new Fl_Text_Predelete_Cb[mNPredeleteProcs + 1]; + void **newCBArgs = new void *[mNPredeleteProcs + 1]; + for (int i = 0; i < mNPredeleteProcs; i++) { + newPreDeleteProcs[i + 1] = mPredeleteProcs[i]; + newCBArgs[i + 1] = mPredeleteCbArgs[i]; + } + if (!mNPredeleteProcs != 0) { + delete[]mPredeleteProcs; + delete[]mPredeleteCbArgs; + } + newPreDeleteProcs[0] = bufPreDeleteCB; + newCBArgs[0] = cbArg; + mNPredeleteProcs++; + mPredeleteProcs = newPreDeleteProcs; + mPredeleteCbArgs = newCBArgs; } -/** - Returns the text from the entire line containing the specified - character position. When you are done with the text, free it - using the free() function. -*/ -char * Fl_Text_Buffer::line_text(int pos) const { +void Fl_Text_Buffer:: +remove_predelete_callback(Fl_Text_Predelete_Cb bufPreDeleteCB, void *cbArg) +{ + int i, toRemove = -1; + /* find the matching callback to remove */ + for (i = 0; i < mNPredeleteProcs; i++) { + if (mPredeleteProcs[i] == bufPreDeleteCB && + mPredeleteCbArgs[i] == cbArg) { + toRemove = i; + break; + } + } + if (toRemove == -1) { + Fl::error + ("Fl_Text_Buffer::remove_predelete_callback(): Can't find pre-delete CB to remove"); + return; + } + + /* Allocate new lists for remaining callback procs and args (if + any are left) */ + mNPredeleteProcs--; + if (mNPredeleteProcs == 0) { + mNPredeleteProcs = 0; + delete[]mPredeleteProcs; + mPredeleteProcs = NULL; + delete[]mPredeleteCbArgs; + mPredeleteCbArgs = NULL; + return; + } + Fl_Text_Predelete_Cb *newPreDeleteProcs = + new Fl_Text_Predelete_Cb[mNPredeleteProcs]; + void **newCBArgs = new void *[mNPredeleteProcs]; + + /* copy out the remaining members and free the old lists */ + for (i = 0; i < toRemove; i++) { + newPreDeleteProcs[i] = mPredeleteProcs[i]; + newCBArgs[i] = mPredeleteCbArgs[i]; + } + for (; i < mNPredeleteProcs; i++) { + newPreDeleteProcs[i] = mPredeleteProcs[i + 1]; + newCBArgs[i] = mPredeleteCbArgs[i + 1]; + } + delete[]mPredeleteProcs; + delete[]mPredeleteCbArgs; + mPredeleteProcs = newPreDeleteProcs; + mPredeleteCbArgs = newCBArgs; +} + +char *Fl_Text_Buffer::line_text(int pos) const { return text_range(line_start(pos), line_end(pos)); -} +} -/** Returns the position of the start of the line containing position \p pos. */ int Fl_Text_Buffer::line_start(int pos) const { if (!findchar_backward(pos, '\n', &pos)) return 0; return pos + 1; -} +} -/** Finds and returns the position of the end of the line containing position \p pos - (which is either a pointer to the newline character ending the line, - or a pointer to one character beyond the end of the buffer) -*/ int Fl_Text_Buffer::line_end(int pos) const { if (!findchar_forward(pos, '\n', &pos)) pos = mLength; return pos; -} -/** Returns the position corresponding to the start of the word */ +} + int Fl_Text_Buffer::word_start(int pos) const { + // FIXME: character is ucs-4 while (pos && (isalnum(character(pos)) || character(pos) == '_')) { pos--; - } - if (!(isalnum(character(pos)) || character(pos) == '_')) pos++; - return pos; -} - -/** Returns the position corresponding to the end of the word.*/ -int Fl_Text_Buffer::word_end(int pos) const { - while (pos < length() && (isalnum(character(pos)) || character(pos) == '_')) { + } + // FIXME: character is ucs-4 + if (!(isalnum(character(pos)) || character(pos) == '_')) pos++; - } return pos; } -/** - Expands the given character to a displayable format. Tabs and - other control characters are given special treatment. - Get a character from the text buffer expanded into its screen - representation (which may be several characters for a tab or a - control code). Returns the number of characters written to \p outStr. - \p indent is the number of characters from the start of the line - for figuring tabs. Output string is guranteed to be shorter or - equal in length to FL_TEXT_MAX_EXP_CHAR_LEN -*/ -int Fl_Text_Buffer::expand_character(int pos, int indent, char *outStr) const { - char c = character(pos); - int ret = expand_character(c, indent, outStr, - mTabDist, mNullSubsChar); - if (ret > 1 && (c & 0x80)) { - int i; - i = fl_utf8len(c); - while (i > 1) { - i--; - pos++; - outStr++; - *outStr = character(pos); - } - } - - return ret; +int Fl_Text_Buffer::word_end(int pos) const { + // FIXME: character is ucs-4 + while (pos < length() && (isalnum(character(pos)) || character(pos) == '_')) + { + pos++; + } return pos; } -/** - Expand a single character \p c from the text buffer into it's displayable - screen representation (which may be several characters for a tab or a - control code). Returns the number of characters added to \p outStr. - \p indent is the number of characters from the start of the line - for figuring tabs of length \p tabDist. Output string is guaranteed - to be shorter or equal in length to FL_TEXT_MAX_EXP_CHAR_LEN - Tabs and other control characters are given special treatment. - \p nulSubsChar represent the null character to be transformed in \ -*/ -int Fl_Text_Buffer::expand_character(char c, int indent, char *outStr, int tabDist, - char nullSubsChar) { + +// Expand from the byte representation into some readable text. +// Under unicode, this is not really needed because all characters should +// be prinatble one way or the other. But since we use this to (badly) simulate +// tabs, we can leave this here anyway. +// - unicode ok +int Fl_Text_Buffer::expand_character(int pos, int indent, char *outStr) const { + const char *src = address(pos); + return expand_character(src, indent, outStr, mTabDist); +} + + +// static function and counterpart to "character_width" +// - unicode ok +// FIXME: harmonise with new character_width(char*...) version +// +int Fl_Text_Buffer::expand_character(const char *src, int indent, char *outStr, int tabDist) +{ + char c = *src; /* Convert tabs to spaces */ if (c == '\t') { int nSpaces = tabDist - (indent % tabDist); for (int i = 0; i < nSpaces; i++) - outStr[ i ] = ' '; + outStr[i] = ' '; return nSpaces; } - + /* Convert control codes to readable character sequences */ - /*... is this safe with international character sets? */ if (((unsigned char) c) <= 31) { - sprintf(outStr, "<%s>", ControlCodeTable[ (unsigned char) c ]); + sprintf(outStr, "<%s>", ControlCodeTable[(unsigned char) c]); return strlen(outStr); } else if (c == 127) { sprintf(outStr, ""); return 5; - } else if (c == nullSubsChar) { - sprintf(outStr, ""); - return 5; } else if ((c & 0x80) && !(c & 0x40)) { - return 0; - } else if (c & 0x80) { +#ifdef DEBUG + fprintf(stderr, "%s:%d - Error in UTF-8 encoding!\n", __FILE__, __LINE__); +#endif *outStr = c; - return fl_utf8len(c); + return 1; + } else if (c & 0x80) { + int i, n = fl_utf8len(c); + for (i=0; i %d (%d, %d, %s)\n", ucs, width, len, ret, src); + return width; + } + if ((c & 0x80) && !(c & 0x40)) { // other byte of UTF-8 sequence return 0; - else if (c & 0x80) { - return fl_utf8len(c); + } + return character_width(c, indent, tabDist); +} + +// FIXME: merge the following with the char* version above. +// but the question then is: how to reorganise expand_character()? +// +int Fl_Text_Buffer::character_width(const char c, int indent, int tabDist) +{ + /* Note, this code must parallel that in Fl_Text_Buffer::ExpandCharacter */ + if (c == '\t') { + return tabDist - (indent % tabDist); + } else if (((unsigned char) c) <= 31) { + return strlen(ControlCodeTable[(unsigned char) c]) + 2; + } else if (c == 127) { + return 5; + } else if ((c & 0x80) && !(c & 0x40)) { +#ifdef DEBUG + fprintf(stderr, "%s:%d - Error in UTF-8 encoding!\n", __FILE__, __LINE__); +#endif + return 1; + } else if (c & 0x80) { + // return fl_utf8len(c); + return 1; } return 1; } -/** - Count the number of displayed characters between buffer position - \p lineStartPos and \p targetPos. (displayed characters are the characters - shown on the screen to represent characters in the buffer, where tabs and - control characters are expanded) -*/ -int Fl_Text_Buffer::count_displayed_characters(int lineStartPos, int targetPos) const { +int Fl_Text_Buffer::count_displayed_characters(int lineStartPos, + int targetPos) const +{ int charCount = 0; - char expandedChar[ FL_TEXT_MAX_EXP_CHAR_LEN ]; - + char expandedChar[FL_TEXT_MAX_EXP_CHAR_LEN]; + int pos = lineStartPos; while (pos < targetPos) charCount += expand_character(pos++, charCount, expandedChar); return charCount; -} +} -/** - Count forward from buffer position \p startPos in displayed characters - (displayed characters are the characters shown on the screen to represent - characters in the buffer, where tabs and control characters are expanded) -*/ -int Fl_Text_Buffer::skip_displayed_characters(int lineStartPos, int nChars) { + +// All values are number of bytes. +// - unicode ok +int Fl_Text_Buffer::skip_displayed_characters(int lineStartPos, int nChars) +{ int pos = lineStartPos; - char c; - - for (int charCount=0; charCount < nChars && pos < mLength;) { - c = character(pos); + + for (int charCount = 0; charCount < nChars && pos < mLength;) { + const char *src = address(pos); + char c = *src; if (c == '\n') return pos; - charCount += character_width(c, charCount, mTabDist, mNullSubsChar); - pos++; + charCount += character_width(src, charCount, mTabDist); + pos += fl_utf8len(c); } return pos; } -/** - Counts the number of newlines between \p startPos and \p endPos in buffer. - The character at position \p endPos is not counted. -*/ int Fl_Text_Buffer::count_lines(int startPos, int endPos) const { int gapLen = mGapEnd - mGapStart; int lineCount = 0; - + int pos = startPos; - while (pos < mGapStart) { + while (pos < mGapStart) + { if (pos == endPos) return lineCount; - if (mBuf[ pos++ ] == '\n') + if (mBuf[pos++] == '\n') lineCount++; - } - while (pos < mLength) { + } while (pos < mLength) { if (pos == endPos) return lineCount; - if (mBuf[ pos++ + gapLen ] == '\n') + if (mBuf[pos++ + gapLen] == '\n') lineCount++; } return lineCount; } -/** - Finds the first character of the line \p nLines forward from \p startPos - in the buffer and returns its position -*/ -int Fl_Text_Buffer::skip_lines(int startPos, int nLines) { +int Fl_Text_Buffer::skip_lines(int startPos, int nLines) +{ if (nLines == 0) return startPos; - + int gapLen = mGapEnd - mGapStart; int pos = startPos; int lineCount = 0; while (pos < mGapStart) { - if (mBuf[ pos++ ] == '\n') { + if (mBuf[pos++] == '\n') { lineCount++; if (lineCount == nLines) - return pos; + return pos; } } while (pos < mLength) { - if (mBuf[ pos++ + gapLen ] == '\n') { + if (mBuf[pos++ + gapLen] == '\n') { lineCount++; if (lineCount >= nLines) - return pos; + return pos; } } return pos; } -/** - Finds and returns the position of the first character of the line \p nLines backwards - from \p startPos (not counting the character pointed to by \p startpos if - that is a newline) in the buffer. \p nLines == 0 means find the beginning of the line -*/ -int Fl_Text_Buffer::rewind_lines(int startPos, int nLines) { +int Fl_Text_Buffer::rewind_lines(int startPos, int nLines) +{ int pos = startPos - 1; if (pos <= 0) return 0; - + int gapLen = mGapEnd - mGapStart; int lineCount = -1; while (pos >= mGapStart) { - if (mBuf[ pos + gapLen ] == '\n') { + if (mBuf[pos + gapLen] == '\n') { if (++lineCount >= nLines) - return pos + 1; + return pos + 1; } pos--; } while (pos >= 0) { - if (mBuf[ pos ] == '\n') { + if (mBuf[pos] == '\n') { if (++lineCount >= nLines) - return pos + 1; + return pos + 1; } pos--; } return 0; } -/** - Search forwards in buffer for string \p searchString, starting with the - character \p startPos, and returning the result in \p foundPos - returns 1 if found, 0 if not. -*/ int Fl_Text_Buffer::search_forward(int startPos, const char *searchString, - int *foundPos, int matchCase) const + int *foundPos, + int matchCase) const { - if (!searchString) return 0; + if (!searchString) + return 0; int bp; - const char* sp; + const char *sp; while (startPos < length()) { bp = startPos; sp = searchString; do { - if (!*sp) { *foundPos = startPos; return 1; } + if (!*sp) { + *foundPos = startPos; + return 1; + } + // FIXME: character is ucs-4 } while ((matchCase ? character(bp++) == *sp++ : - toupper(character(bp++)) == toupper(*sp++)) + toupper(character(bp++)) == toupper(*sp++)) && bp < length()); startPos++; } return 0; } -/** - Search backwards in buffer for string searchCharssearchString, starting with the - character BEFORE \p startPos, returning the result in \p foundPos - returns 1 if found, 0 if not. -*/ int Fl_Text_Buffer::search_backward(int startPos, const char *searchString, - int *foundPos, int matchCase) const -{ - if (!searchString) return 0; + int *foundPos, + int matchCase) const { + if (!searchString) + return 0; int bp; - const char* sp; - while (startPos > 0) { - bp = startPos-1; - sp = searchString+strlen(searchString)-1; + const char *sp; + while (startPos > 0) + { + bp = startPos - 1; + sp = searchString + strlen(searchString) - 1; do { - if (sp < searchString) { *foundPos = bp+1; return 1; } + if (sp < searchString) { + *foundPos = bp + 1; + return 1; + } + // FIXME: character is ucs-4 } while ((matchCase ? character(bp--) == *sp-- : - toupper(character(bp--)) == toupper(*sp--)) + toupper(character(bp--)) == toupper(*sp--)) && bp >= 0); startPos--; } return 0; } -/** - Finds the next occurrence of the specified characters. - Search forwards in buffer for characters in \p searchChars, starting - with the character \p startPos, and returning the result in \p foundPos - returns 1 if found, 0 if not. -*/ -int Fl_Text_Buffer::findchars_forward(int startPos, const char *searchChars, - int *foundPos) const { +int Fl_Text_Buffer::findchars_forward(int startPos, + const char *searchChars, + int *foundPos) const { int gapLen = mGapEnd - mGapStart; const char *c; - + int pos = startPos; - while (pos < mGapStart) { + while (pos < mGapStart) + { for (c = searchChars; *c != '\0'; c++) { - if (mBuf[ pos ] == *c) { + if (mBuf[pos] == *c) { *foundPos = pos; return 1; } - } - pos++; + } pos++; } while (pos < mLength) { for (c = searchChars; *c != '\0'; c++) { - if (mBuf[ pos + gapLen ] == *c) { - *foundPos = pos; - return 1; + if (mBuf[pos + gapLen] == *c) { + *foundPos = pos; + return 1; } } pos++; @@ -1204,36 +1238,32 @@ int Fl_Text_Buffer::findchars_forward(int startPos, const char *searchChars, return 0; } -/** - Finds the previous occurrence of the specified characters. - Search backwards in buffer for characters in \p searchChars, starting - with the character BEFORE \p startPos, returning the result in \p foundPos - returns 1 if found, 0 if not. -*/ -int Fl_Text_Buffer::findchars_backward(int startPos, const char *searchChars, - int *foundPos) const { +int Fl_Text_Buffer::findchars_backward(int startPos, + const char *searchChars, + int *foundPos) const { int gapLen = mGapEnd - mGapStart; const char *c; - - if (startPos == 0) { + + if (startPos == 0) + { *foundPos = 0; return 0; } int pos = startPos == 0 ? 0 : startPos - 1; while (pos >= mGapStart) { for (c = searchChars; *c != '\0'; c++) { - if (mBuf[ pos + gapLen ] == *c) { - *foundPos = pos; - return 1; + if (mBuf[pos + gapLen] == *c) { + *foundPos = pos; + return 1; } } pos--; } while (pos >= 0) { for (c = searchChars; *c != '\0'; c++) { - if (mBuf[ pos ] == *c) { - *foundPos = pos; - return 1; + if (mBuf[pos] == *c) { + *foundPos = pos; + return 1; } } pos--; @@ -1242,170 +1272,52 @@ int Fl_Text_Buffer::findchars_backward(int startPos, const char *searchChars, return 0; } -/* - A horrible design flaw in NEdit (from the very start, before we knew that - NEdit would become so popular), is that it uses C NULL terminated strings - to hold text. This means editing text containing NUL characters is not - possible without special consideration. Here is the special consideration. - The routines below maintain a special substitution-character which stands - in for a null, and translates strings an buffers back and forth from/to - the substituted form, figure out what to substitute, and figure out - when we're in over our heads and no translation is possible. -*/ - -/** - The primary routine for integrating new text into a text buffer with - substitution of another character for ascii nuls. This substitutes null - characters in the string in preparation for being copied or replaced - into the buffer, and if necessary, adjusts the buffer as well, in the - event that the string contains the character it is currently using for - substitution. Returns 0, if substitution is no longer possible - because all non-printable characters are already in use. -*/ -int Fl_Text_Buffer::substitute_null_characters(char *string, int len) { - char histogram[ 256 ]; - - /* Find out what characters the string contains */ - histogramCharacters(string, len, histogram, 1); - - /* Does the string contain the null-substitute character? If so, re- - histogram the buffer text to find a character which is ok in both the - string and the buffer, and change the buffer's null-substitution - character. If none can be found, give up and return 0 */ - if (histogram[ (unsigned char) mNullSubsChar ] != 0) { - char * bufString; - char newSubsChar; - bufString = (char*)text(); - histogramCharacters(bufString, mLength, histogram, 0); - newSubsChar = chooseNullSubsChar(histogram); - if (newSubsChar == '\0') - return 0; - subsChars(bufString, mLength, mNullSubsChar, newSubsChar); - remove_(0, mLength); - insert_(0, bufString); - free((void *) bufString); - mNullSubsChar = newSubsChar; - } - - /* If the string contains null characters, substitute them with the - buffer's null substitution character */ - if (histogram[ 0 ] != 0) - subsChars(string, len, '\0', mNullSubsChar); - return 1; -} - -/** - Converts strings obtained from buffers which contain null characters, which - have been substituted for by a special substitution character, back to - a null-containing string. There is no time penalty for calling this - routine if no substitution has been done. -*/ -void Fl_Text_Buffer::unsubstitute_null_characters(char *string) { - register char * c, subsChar = mNullSubsChar; - - if (subsChar == '\0') - return; - for (c = string; *c != '\0'; c++) - if (*c == subsChar) - * c = '\0'; -} - -/** - Creates a pseudo-histogram of the characters in a string (don't actually - count, because we don't want overflow, just mark the character's presence - with a 1). If init is true, initialize the histogram before acumulating. - if not, add the new data to an existing histogram. -*/ -static void histogramCharacters(const char *string, int length, char hist[ 256 ], - int init) { - if (init) memset(hist,0,sizeof(char)*256); // faster than the original per-char for loop - for (const char* c = string; c < &string[ length ]; c++) - hist[ *((unsigned char *) c) ] |= 1; -} - -/** - Substitute fromChar with toChar in string. -*/ -static void subsChars(char *string, int length, char fromChar, char toChar) { - for (char* c = string; c < &string[ length ]; c++) - if (*c == fromChar) *c = toChar; -} - -/** - Search through ascii control characters in histogram in order of least - likelihood of use, find an unused character to use as a stand-in for a - null. If the character set is full (no available characters outside of - the printable set, return the null character. -*/ -static char chooseNullSubsChar(char hist[ 256 ]) { -#define N_REPLACEMENTS 25 - static char replacements[ N_REPLACEMENTS ] = {1, 2, 3, 4, 5, 6, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 28, 29, 30, 31, 11, 7}; - - for (int i = 0; i < N_REPLACEMENTS; i++) - if (hist[ replacements[ i ] ] == 0) - return replacements[ i ]; - return '\0'; -} - -/** - Internal (non-redisplaying) version of BufInsert. Returns the length of - text inserted (this is just strlen(\p text), however this calculation can be - expensive and the length will be required by any caller who will continue - on to call redisplay). \p pos must be contiguous with the existing text in - the buffer (i.e. not past the end). -*/ -int Fl_Text_Buffer::insert_(int pos, const char *text) { +int Fl_Text_Buffer::insert_(int pos, const char *text) +{ int insertedLength = strlen(text); - + /* Prepare the buffer to receive the new text. If the new text fits in - the current buffer, just move the gap (if necessary) to where - the text should be inserted. If the new text is too large, reallocate - the buffer with a gap large enough to accomodate the new text and a - gap of mPreferredGapSize */ + the current buffer, just move the gap (if necessary) to where + the text should be inserted. If the new text is too large, reallocate + the buffer with a gap large enough to accomodate the new text and a + gap of mPreferredGapSize */ if (insertedLength > mGapEnd - mGapStart) reallocate_with_gap(pos, insertedLength + mPreferredGapSize); else if (pos != mGapStart) move_gap(pos); - + /* Insert the new text (pos now corresponds to the start of the gap) */ - memcpy(&mBuf[ pos ], text, insertedLength); + memcpy(&mBuf[pos], text, insertedLength); mGapStart += insertedLength; mLength += insertedLength; update_selections(pos, 0, insertedLength); - + if (mCanUndo) { - if (undowidget==this && undoat==pos && undoinsert) { + if (undowidget == this && undoat == pos && undoinsert) { undoinsert += insertedLength; - } - else { + } else { undoinsert = insertedLength; - undoyankcut = (undoat==pos) ? undocut : 0 ; + undoyankcut = (undoat == pos) ? undocut : 0; } - undoat = pos+insertedLength; + undoat = pos + insertedLength; undocut = 0; undowidget = this; } - + return insertedLength; } -/** - Internal (non-redisplaying) version of BufRemove. Removes the contents - of the buffer between start and end (and moves the gap to the site of - the delete). -*/ -void Fl_Text_Buffer::remove_(int start, int end) { +void Fl_Text_Buffer::remove_(int start, int end) +{ /* if the gap is not contiguous to the area to remove, move it there */ - + if (mCanUndo) { - if (undowidget==this && undoat==end && undocut) { - undobuffersize(undocut+end-start+1); - memmove(undobuffer+end-start, undobuffer, undocut); - undocut += end-start; - } - else { - undocut = end-start; + if (undowidget == this && undoat == end && undocut) { + undobuffersize(undocut + end - start + 1); + memmove(undobuffer + end - start, undobuffer, undocut); + undocut += end - start; + } else { + undocut = end - start; undobuffersize(undocut); } undoat = start; @@ -1413,89 +1325,80 @@ void Fl_Text_Buffer::remove_(int start, int end) { undoyankcut = 0; undowidget = this; } - + if (start > mGapStart) { if (mCanUndo) - memcpy(undobuffer, mBuf+(mGapEnd-mGapStart)+start, end-start); + memcpy(undobuffer, mBuf + (mGapEnd - mGapStart) + start, + end - start); move_gap(start); - } - else if (end < mGapStart) { + } else if (end < mGapStart) { if (mCanUndo) - memcpy(undobuffer, mBuf+start, end-start); + memcpy(undobuffer, mBuf + start, end - start); move_gap(end); - } - else { + } else { int prelen = mGapStart - start; if (mCanUndo) { - memcpy(undobuffer, mBuf+start, prelen); - memcpy(undobuffer+prelen, mBuf+mGapEnd, end-start-prelen); + memcpy(undobuffer, mBuf + start, prelen); + memcpy(undobuffer + prelen, mBuf + mGapEnd, end - start - prelen); } } - + /* expand the gap to encompass the deleted characters */ mGapEnd += end - mGapStart; mGapStart -= mGapStart - start; - + /* update the length */ mLength -= end - start; - + /* fix up any selections which might be affected by the change */ update_selections(start, end - start, 0); } -/** - Inserts a column of text without calling the modify callbacks. Note that - in some pathological cases, inserting can actually decrease the size of - the buffer because of spaces being coalesced into tabs. \p nDeleted and - \p nInserted return the number of characters deleted and inserted beginning - at the start of the line containing \p startPos. \p endPos returns buffer - position of the lower left edge of the inserted column (as a hint for - routines which need to set a cursor position). -*/ -void Fl_Text_Buffer::insert_column_(int column, int startPos, const char *insText, - int *nDeleted, int *nInserted, int *endPos) { +void Fl_Text_Buffer::insert_column_(int column, int startPos, + const char *insText, int *nDeleted, + int *nInserted, int *endPos) +{ if (column < 0) column = 0; - + /* Allocate a buffer for the replacement string large enough to hold - possibly expanded tabs in both the inserted text and the replaced - area, as well as per line: 1) an additional 2*FL_TEXT_MAX_EXP_CHAR_LEN - characters for padding where tabs and control characters cross the - column of the selection, 2) up to "column" additional spaces per - line for padding out to the position of "column", 3) padding up - to the width of the inserted text if that must be padded to align - the text beyond the inserted column. (Space for additional - newlines if the inserted text extends beyond the end of the buffer - is counted with the length of insText) */ + possibly expanded tabs in both the inserted text and the replaced + area, as well as per line: 1) an additional 2*FL_TEXT_MAX_EXP_CHAR_LEN + characters for padding where tabs and control characters cross the + column of the selection, 2) up to "column" additional spaces per + line for padding out to the position of "column", 3) padding up + to the width of the inserted text if that must be padded to align + the text beyond the inserted column. (Space for additional + newlines if the inserted text extends beyond the end of the buffer + is counted with the length of insText) */ int start = line_start(startPos); int nLines = countLines(insText) + 1; - int insWidth = textWidth(insText, mTabDist, mNullSubsChar); + int insWidth = textWidth(insText, mTabDist); // this function probably returns a useless value int end = line_end(skip_lines(start, nLines - 1)); int expReplLen, expInsLen, len, endOffset; - const char* replText = text_range(start, end); - char* expText = expandTabs(replText, 0, mTabDist, mNullSubsChar, - &expReplLen); + const char *replText = text_range(start, end); + char *expText = expandTabs(replText, 0, mTabDist, &expReplLen); free((void *) replText); free((void *) expText); - expText = expandTabs(insText, 0, mTabDist, mNullSubsChar, - &expInsLen); + expText = expandTabs(insText, 0, mTabDist, &expInsLen); free((void *) expText); - char* outStr = (char *)malloc(expReplLen + expInsLen + - nLines * (column + insWidth + FL_TEXT_MAX_EXP_CHAR_LEN) + 1); - + char *outStr = (char *) malloc(expReplLen + expInsLen + + nLines * (column + insWidth + + FL_TEXT_MAX_EXP_CHAR_LEN) + 1); + /* Loop over all lines in the buffer between start and end removing the - text between rectStart and rectEnd and padding appropriately. Trim - trailing space from line (whitespace at the ends of lines otherwise - tends to multiply, since additional padding is added to maintain it */ - char* outPtr = outStr, *insLine; - const char* insPtr = insText, *line; + text between rectStart and rectEnd and padding appropriately. Trim + trailing space from line (whitespace at the ends of lines otherwise + tends to multiply, since additional padding is added to maintain it */ + char *outPtr = outStr, *insLine; + const char *insPtr = insText, *line; for (int lineStart = start, lineEnd;;) { lineEnd = line_end(lineStart); line = text_range(lineStart, lineEnd); insLine = copyLine(insPtr, &len); insPtr += len; insertColInLine(line, insLine, column, insWidth, mTabDist, - mUseTabs, mNullSubsChar, outPtr, &len, &endOffset); + mUseTabs, outPtr, &len, &endOffset); free((void *) line); free((void *) insLine); for (const char *c = outPtr + len - 1; c > outPtr && isspace(*c); c--) @@ -1508,9 +1411,9 @@ void Fl_Text_Buffer::insert_column_(int column, int startPos, const char *insTex insPtr++; } if (outPtr != outStr) - outPtr--; /* trim back off extra newline */ + outPtr--; /* trim back off extra newline */ *outPtr = '\0'; - + /* replace the text between start and end with the new stuff */ remove_(start, end); insert_(start, outStr); @@ -1520,49 +1423,45 @@ void Fl_Text_Buffer::insert_column_(int column, int startPos, const char *insTex free((void *) outStr); } -/** - Deletes a rectangle of text without calling the modify callbacks. Returns - the number of characters replacing those between \p start and \p end. Note that - in some pathological cases, deleting can actually increase the size of - the buffer because of tab expansions. \p endPos returns the buffer position - of the point in the last line where the text was removed (as a hint for - routines which need to position the cursor after a delete operation) -*/ void Fl_Text_Buffer::remove_rectangular_(int start, int end, int rectStart, - int rectEnd, int *replaceLen, int *endPos) { + int rectEnd, int *replaceLen, + int *endPos) +{ /* allocate a buffer for the replacement string large enough to hold - possibly expanded tabs as well as an additional FL_TEXT_MAX_EXP_CHAR_LEN * 2 - characters per line for padding where tabs and control characters cross - the edges of the selection */ + possibly expanded tabs as well as an additional FL_TEXT_MAX_EXP_CHAR_LEN * 2 + characters per line for padding where tabs and control characters cross + the edges of the selection */ start = line_start(start); end = line_end(end); int nLines = count_lines(start, end) + 1; - const char* s = text_range(start, end); + const char *s = text_range(start, end); int len; - char* expText = expandTabs(s, 0, mTabDist, mNullSubsChar, &len); + char *expText = expandTabs(s, 0, mTabDist, &len); free((void *) s); free((void *) expText); - char* outStr = (char *)malloc(len + nLines * FL_TEXT_MAX_EXP_CHAR_LEN * 2 + 1); - + char *outStr = + (char *) malloc(len + nLines * FL_TEXT_MAX_EXP_CHAR_LEN * 2 + 1); + /* loop over all lines in the buffer between start and end removing - the text between rectStart and rectEnd and padding appropriately */ + the text between rectStart and rectEnd and padding appropriately */ int endOffset = 0; - char* outPtr = outStr; + char *outPtr = outStr; const char *line; - for (int lineStart=start,lineEnd; lineStart <= mLength && lineStart <= end;) { + for (int lineStart = start, lineEnd; + lineStart <= mLength && lineStart <= end;) { lineEnd = line_end(lineStart); line = text_range(lineStart, lineEnd); deleteRectFromLine(line, rectStart, rectEnd, mTabDist, - mUseTabs, mNullSubsChar, outPtr, &len, &endOffset); + mUseTabs, outPtr, &len, &endOffset); free((void *) line); outPtr += len; *outPtr++ = '\n'; lineStart = lineEnd + 1; } if (outPtr != outStr) - outPtr--; /* trim back off extra newline */ + outPtr--; /* trim back off extra newline */ *outPtr = '\0'; - + /* replace the text between start and end with the newly created string */ remove_(start, end); insert_(start, outStr); @@ -1571,52 +1470,47 @@ void Fl_Text_Buffer::remove_rectangular_(int start, int end, int rectStart, free((void *) outStr); } -/** - Overlay a rectangular area of text without calling the modify callbacks. - \p nDeleted and \p nInserted return the number of characters deleted and - inserted beginning at the start of the line containing \p startPos. - \p endPos returns buffer position of the lower left edge of the inserted - column (as a hint for routines which need to set a cursor position). -*/ void Fl_Text_Buffer::overlay_rectangular_(int startPos, int rectStart, - int rectEnd, const char *insText,int *nDeleted, int *nInserted, - int *endPos) { - + int rectEnd, const char *insText, + int *nDeleted, int *nInserted, + int *endPos) +{ + /* Allocate a buffer for the replacement string large enough to hold - possibly expanded tabs in the inserted text, as well as per line: 1) - an additional 2*FL_TEXT_MAX_EXP_CHAR_LEN characters for padding where tabs - and control characters cross the column of the selection, 2) up to - "column" additional spaces per line for padding out to the position - of "column", 3) padding up to the width of the inserted text if that - must be padded to align the text beyond the inserted column. (Space - for additional newlines if the inserted text extends beyond the end - of the buffer is counted with the length of insText) */ + possibly expanded tabs in the inserted text, as well as per line: 1) + an additional 2*FL_TEXT_MAX_EXP_CHAR_LEN characters for padding where tabs + and control characters cross the column of the selection, 2) up to + "column" additional spaces per line for padding out to the position + of "column", 3) padding up to the width of the inserted text if that + must be padded to align the text beyond the inserted column. (Space + for additional newlines if the inserted text extends beyond the end + of the buffer is counted with the length of insText) */ int start = line_start(startPos); int nLines = countLines(insText) + 1; int end = line_end(skip_lines(start, nLines - 1)), expInsLen; - char* expText = expandTabs(insText, 0, mTabDist, mNullSubsChar, - &expInsLen); + char *expText = expandTabs(insText, 0, mTabDist, &expInsLen); free((void *) expText); - char* outStr = (char *)malloc(end - start + expInsLen + - nLines * (rectEnd + FL_TEXT_MAX_EXP_CHAR_LEN) + 1); - + char *outStr = (char *) malloc(end - start + expInsLen + + nLines * (rectEnd + + FL_TEXT_MAX_EXP_CHAR_LEN) + 1); + /* Loop over all lines in the buffer between start and end overlaying the - text between rectStart and rectEnd and padding appropriately. Trim - trailing space from line (whitespace at the ends of lines otherwise - tends to multiply, since additional padding is added to maintain it */ + text between rectStart and rectEnd and padding appropriately. Trim + trailing space from line (whitespace at the ends of lines otherwise + tends to multiply, since additional padding is added to maintain it */ int len, endOffset; - char* outPtr = outStr, *insLine; - const char* insPtr = insText,*line; - for (int lineStart = start,lineEnd;;) { + char *outPtr = outStr, *insLine; + const char *insPtr = insText, *line; + for (int lineStart = start, lineEnd;;) { lineEnd = line_end(lineStart); line = text_range(lineStart, lineEnd); insLine = copyLine(insPtr, &len); insPtr += len; overlayRectInLine(line, insLine, rectStart, rectEnd, mTabDist, - mUseTabs, mNullSubsChar, outPtr, &len, &endOffset); + mUseTabs, outPtr, &len, &endOffset); free((void *) line); free((void *) insLine); - for (const char* c = outPtr + len - 1; c > outPtr && isspace(*c); c--) + for (const char *c = outPtr + len - 1; c > outPtr && isspace(*c); c--) len--; outPtr += len; *outPtr++ = '\n'; @@ -1626,9 +1520,9 @@ void Fl_Text_Buffer::overlay_rectangular_(int startPos, int rectStart, insPtr++; } if (outPtr != outStr) - outPtr--; /* trim back off extra newline */ + outPtr--; /* trim back off extra newline */ *outPtr = '\0'; - + /* replace the text between start and end with the new stuff */ remove_(start, end); insert_(start, outStr); @@ -1638,34 +1532,36 @@ void Fl_Text_Buffer::overlay_rectangular_(int startPos, int rectStart, free((void *) outStr); } -/** - Inserts characters from single-line string \p insLine in single-line string - \p line at \p column, leaving \p insWidth space before continuing line. - \p outLen returns the number of characters written to \p outStr, \p endOffset - returns the number of characters from the beginning of the string to - the right edge of the inserted text (as a hint for routines which need - to position the cursor). -*/ -static void insertColInLine(const char *line, char *insLine, int column, int insWidth, - int tabDist, int useTabs, char nullSubsChar, char *outStr, int *outLen, - int *endOffset) { +/* + Inserts characters from single-line string \p insLine in single-line string + \p line at \p column, leaving \p insWidth space before continuing line. + \p outLen returns the number of characters written to \p outStr, \p endOffset + returns the number of characters from the beginning of the string to + the right edge of the inserted text (as a hint for routines which need + to position the cursor). + */ +static void insertColInLine(const char *line, char *insLine, int column, + int insWidth, int tabDist, int useTabs, + char *outStr, int *outLen, + int *endOffset) +{ /* copy the line up to "column" */ - char* outPtr = outStr; + char *outPtr = outStr; int indent = 0, len; const char *linePtr; - + for (linePtr = line; *linePtr != '\0'; linePtr++) { - len = Fl_Text_Buffer::character_width(*linePtr, indent, tabDist, nullSubsChar); + len = Fl_Text_Buffer::character_width(linePtr, indent, tabDist); if (indent + len > column) break; indent += len; *outPtr++ = *linePtr; } - + /* If "column" falls in the middle of a character, and the character is a - tab, leave it off and leave the indent short and it will get padded - later. If it's a control character, insert it and adjust indent - accordingly. */ + tab, leave it off and leave the indent short and it will get padded + later. If it's a control character, insert it and adjust indent + accordingly. */ int postColIndent; if (indent < column && *linePtr != '\0') { postColIndent = indent + len; @@ -1677,49 +1573,49 @@ static void insertColInLine(const char *line, char *insLine, int column, int ins } } else postColIndent = indent; - + /* If there's no text after the column and no text to insert, that's all */ if (*insLine == '\0' && *linePtr == '\0') { *outLen = *endOffset = outPtr - outStr; return; } - + /* pad out to column if text is too short */ if (indent < column) { - addPadding(outPtr, indent, column, tabDist, useTabs, nullSubsChar, &len); + addPadding(outPtr, indent, column, tabDist, useTabs, &len); outPtr += len; indent = column; } - + /* Copy the text from "insLine" (if any), recalculating the tabs as if - the inserted string began at column 0 to its new column destination */ + the inserted string began at column 0 to its new column destination */ if (*insLine != '\0') { - char* retabbedStr = realignTabs(insLine, 0, indent, tabDist, useTabs, - nullSubsChar, &len); - for (const char* c = retabbedStr; *c != '\0'; c++) { + char *retabbedStr = realignTabs(insLine, 0, indent, tabDist, useTabs, + &len); + for (const char *c = retabbedStr; *c != '\0'; c++) { *outPtr++ = *c; - len = Fl_Text_Buffer::character_width(*c, indent, tabDist, nullSubsChar); + len = Fl_Text_Buffer::character_width(c, indent, tabDist); indent += len; } free((void *) retabbedStr); } - + /* If the original line did not extend past "column", that's all */ if (*linePtr == '\0') { *outLen = *endOffset = outPtr - outStr; return; } - + /* Pad out to column + width of inserted text + (additional original - offset due to non-breaking character at column) */ + offset due to non-breaking character at column) */ int toIndent = column + insWidth + postColIndent - column; - addPadding(outPtr, indent, toIndent, tabDist, useTabs, nullSubsChar, &len); + addPadding(outPtr, indent, toIndent, tabDist, useTabs, &len); outPtr += len; indent = toIndent; - + /* realign tabs for text beyond "column" and write it out */ - char * retabbedStr = realignTabs(linePtr, postColIndent, indent, tabDist, - useTabs, nullSubsChar, &len); + char *retabbedStr = realignTabs(linePtr, postColIndent, indent, tabDist, + useTabs, &len); strcpy(outPtr, retabbedStr); free((void *) retabbedStr); *endOffset = outPtr - outStr; @@ -1727,57 +1623,58 @@ static void insertColInLine(const char *line, char *insLine, int column, int ins } /** - Removes characters in single-line string \p line between displayed positions - \p rectStart and \p rectEnd, and write the result to \p outStr, which is - assumed to be large enough to hold the returned string. Note that in - certain cases, it is possible for the string to get longer due to - expansion of tabs. \p endOffset returns the number of characters from - the beginning of the string to the point where the characters were - deleted (as a hint for routines which need to position the cursor). -*/ -static void deleteRectFromLine(const char *line, int rectStart, int rectEnd, - int tabDist, int useTabs, char nullSubsChar, char *outStr, int *outLen, - int *endOffset) { - + Removes characters in single-line string \p line between displayed positions + \p rectStart and \p rectEnd, and write the result to \p outStr, which is + assumed to be large enough to hold the returned string. Note that in + certain cases, it is possible for the string to get longer due to + expansion of tabs. \p endOffset returns the number of characters from + the beginning of the string to the point where the characters were + deleted (as a hint for routines which need to position the cursor). + */ +static void deleteRectFromLine(const char *line, int rectStart, + int rectEnd, int tabDist, int useTabs, + char *outStr, + int *outLen, int *endOffset) +{ + /* copy the line up to rectStart */ - char* outPtr = outStr; + char *outPtr = outStr; int indent = 0, len; const char *c; for (c = line; *c != '\0'; c++) { if (indent > rectStart) break; - len = Fl_Text_Buffer::character_width(*c, indent, tabDist, nullSubsChar); + len = Fl_Text_Buffer::character_width(c, indent, tabDist); if (indent + len > rectStart && (indent == rectStart || *c == '\t')) break; indent += len; *outPtr++ = *c; } int preRectIndent = indent; - + /* skip the characters between rectStart and rectEnd */ for (; *c != '\0' && indent < rectEnd; c++) - indent += Fl_Text_Buffer::character_width(*c, indent, tabDist, nullSubsChar); + indent += Fl_Text_Buffer::character_width(c, indent, tabDist); int postRectIndent = indent; - + /* If the line ended before rectEnd, there's nothing more to do */ if (*c == '\0') { *outPtr = '\0'; *outLen = *endOffset = outPtr - outStr; return; } - + /* fill in any space left by removed tabs or control characters - which straddled the boundaries */ + which straddled the boundaries */ indent = max(rectStart + postRectIndent - rectEnd, preRectIndent); - addPadding(outPtr, preRectIndent, indent, tabDist, useTabs, nullSubsChar, - &len); + addPadding(outPtr, preRectIndent, indent, tabDist, useTabs, &len); outPtr += len; - + /* Copy the rest of the line. If the indentation has changed, preserve - the position of non-whitespace characters by converting tabs to - spaces, then back to tabs with the correct offset */ - char* retabbedStr = realignTabs(c, postRectIndent, indent, tabDist, useTabs, - nullSubsChar, &len); + the position of non-whitespace characters by converting tabs to + spaces, then back to tabs with the correct offset */ + char *retabbedStr = + realignTabs(c, postRectIndent, indent, tabDist, useTabs, &len); strcpy(outPtr, retabbedStr); free((void *) retabbedStr); *endOffset = outPtr - outStr; @@ -1785,34 +1682,36 @@ static void deleteRectFromLine(const char *line, int rectStart, int rectEnd, } /** - Overlay characters from single-line string \p insLine on single-line string - \p line between displayed character offsets \p rectStart and \p rectEnd. - \p outLen returns the number of characters written to \p outStr, \p endOffset - returns the number of characters from the beginning of the string to - the right edge of the inserted text (as a hint for routines which need - to position the cursor). -*/ -static void overlayRectInLine(const char *line, char *insLine, int rectStart, - int rectEnd, int tabDist, int useTabs, char nullSubsChar, char *outStr, - int *outLen, int *endOffset) { + Overlay characters from single-line string \p insLine on single-line string + \p line between displayed character offsets \p rectStart and \p rectEnd. + \p outLen returns the number of characters written to \p outStr, \p endOffset + returns the number of characters from the beginning of the string to + the right edge of the inserted text (as a hint for routines which need + to position the cursor). + */ +static void overlayRectInLine(const char *line, char *insLine, + int rectStart, int rectEnd, int tabDist, + int useTabs, char *outStr, + int *outLen, int *endOffset) +{ /* copy the line up to "rectStart" */ char *outPtr = outStr; - int inIndent=0, outIndent=0, len; - const char *linePtr=line; - + int inIndent = 0, outIndent = 0, len; + const char *linePtr = line; + for (; *linePtr != '\0'; linePtr++) { - len = Fl_Text_Buffer::character_width(*linePtr, inIndent, tabDist, nullSubsChar); + len = Fl_Text_Buffer::character_width(linePtr, inIndent, tabDist); if (inIndent + len > rectStart) break; inIndent += len; outIndent += len; *outPtr++ = *linePtr; } - + /* If "rectStart" falls in the middle of a character, and the character - is a tab, leave it off and leave the outIndent short and it will get - padded later. If it's a control character, insert it and adjust - outIndent accordingly. */ + is a tab, leave it off and leave the outIndent short and it will get + padded later. If it's a control character, insert it and adjust + outIndent accordingly. */ if (inIndent < rectStart && *linePtr != '\0') { if (*linePtr == '\t') { linePtr++; @@ -1823,73 +1722,79 @@ static void overlayRectInLine(const char *line, char *insLine, int rectStart, inIndent += len; } } - + /* skip the characters between rectStart and rectEnd */ int postRectIndent = rectEnd; for (; *linePtr != '\0'; linePtr++) { - inIndent += Fl_Text_Buffer::character_width(*linePtr, inIndent, tabDist, nullSubsChar); + inIndent += Fl_Text_Buffer::character_width(linePtr, inIndent, tabDist); if (inIndent >= rectEnd) { linePtr++; postRectIndent = inIndent; break; } } - + /* If there's no text after rectStart and no text to insert, that's all */ if (*insLine == '\0' && *linePtr == '\0') { *outLen = *endOffset = outPtr - outStr; return; } - + /* pad out to rectStart if text is too short */ if (outIndent < rectStart) { - addPadding(outPtr, outIndent, rectStart, tabDist, useTabs, nullSubsChar, - &len); + addPadding(outPtr, outIndent, rectStart, tabDist, useTabs, &len); outPtr += len; } outIndent = rectStart; - + /* Copy the text from "insLine" (if any), recalculating the tabs as if - the inserted string began at column 0 to its new column destination */ + the inserted string began at column 0 to its new column destination */ if (*insLine != '\0') { - char *retabbedStr = realignTabs(insLine, 0, rectStart, tabDist, useTabs, - nullSubsChar, &len); - for (const char*c = retabbedStr; *c != '\0'; c++) { + char *retabbedStr = + realignTabs(insLine, 0, rectStart, tabDist, useTabs, &len); + for (const char *c = retabbedStr; *c != '\0'; c++) { *outPtr++ = *c; - len = Fl_Text_Buffer::character_width(*c, outIndent, tabDist, nullSubsChar); + len = Fl_Text_Buffer::character_width(c, outIndent, tabDist); outIndent += len; } free((void *) retabbedStr); } - + /* If the original line did not extend past "rectStart", that's all */ if (*linePtr == '\0') { *outLen = *endOffset = outPtr - outStr; return; } - + /* Pad out to rectEnd + (additional original offset - due to non-breaking character at right boundary) */ - addPadding(outPtr, outIndent, postRectIndent, tabDist, useTabs, - nullSubsChar, &len); + due to non-breaking character at right boundary) */ + addPadding(outPtr, outIndent, postRectIndent, tabDist, useTabs, &len); outPtr += len; outIndent = postRectIndent; - + /* copy the text beyond "rectEnd" */ strcpy(outPtr, linePtr); *endOffset = outPtr - outStr; *outLen = (outPtr - outStr) + strlen(linePtr); } -void Fl_Text_Selection::set(int startpos, int endpos) { + +// simple setter +// Unicode safe +void Fl_Text_Selection::set(int startpos, int endpos) +{ mSelected = startpos != endpos; mRectangular = 0; mStart = min(startpos, endpos); mEnd = max(startpos, endpos); } + +// simple setter +// Unicode safe void Fl_Text_Selection::set_rectangular(int startpos, int endpos, - int rectStart, int rectEnd) { + int rectStart, int rectEnd) +{ mSelected = rectStart < rectEnd; mRectangular = 1; mStart = startpos; @@ -1898,63 +1803,71 @@ void Fl_Text_Selection::set_rectangular(int startpos, int endpos, mRectEnd = rectEnd; } + +// simple getter +// Unicode safe int Fl_Text_Selection::position(int *startpos, int *endpos) const { if (!mSelected) return 0; *startpos = mStart; *endpos = mEnd; - + return 1; -} +} + +// simple getter +// Unicode safe int Fl_Text_Selection::position(int *startpos, int *endpos, - int *isRect, int *rectStart, int *rectEnd) const { + int *isRect, int *rectStart, + int *rectEnd) const { if (!mSelected) return 0; *isRect = mRectangular; *startpos = mStart; *endpos = mEnd; - if (mRectangular) { + if (mRectangular) + { *rectStart = mRectStart; *rectEnd = mRectEnd; } return 1; } -/** - Return true if position \p pos with indentation \p dispIndex is in - the Fl_Text_Selection. -*/ + +// unicode safe int Fl_Text_Selection::includes(int pos, int lineStartPos, int dispIndex) const { - return selected() && - ((!rectangular() && pos >= start() && pos < end()) || - (rectangular() && pos >= start() && lineStartPos <= end() && - dispIndex >= rect_start() && dispIndex < rect_end()) - ); -} + return (selected() + && ( (!rectangular() && pos >= start() && pos < end()) + || (rectangular() && pos >= start() && lineStartPos <= end() + && dispIndex >= rect_start() && dispIndex < rect_end() + ) + ) + ); +} - - -char * Fl_Text_Buffer::selection_text_(Fl_Text_Selection *sel) const { +char *Fl_Text_Buffer::selection_text_(Fl_Text_Selection * sel) const { int start, end, isRect, rectStart, rectEnd; - + /* If there's no selection, return an allocated empty string */ - if (!sel->position(&start, &end, &isRect, &rectStart, &rectEnd)) { - char *s = (char *)malloc(1); + if (!sel->position(&start, &end, &isRect, &rectStart, &rectEnd)) + { + char *s = (char *) malloc(1); *s = '\0'; return s; } - + /* If the selection is not rectangular, return the selected range */ if (isRect) return text_in_rectangle(start, end, rectStart, rectEnd); else return text_range(start, end); } -/** Removes the text from the buffer corresponding to \p sel.*/ -void Fl_Text_Buffer::remove_selection_(Fl_Text_Selection *sel) { - int start, end, isRect, rectStart, rectEnd; +void Fl_Text_Buffer::remove_selection_(Fl_Text_Selection * sel) +{ + int start, end, isRect, rectStart, rectEnd; + if (!sel->position(&start, &end, &isRect, &rectStart, &rectEnd)) return; if (isRect) @@ -1965,42 +1878,45 @@ void Fl_Text_Buffer::remove_selection_(Fl_Text_Selection *sel) { } } -/** Replaces the \p text in selection \p sel.*/ -void Fl_Text_Buffer::replace_selection_(Fl_Text_Selection *sel, const char *text) { +void Fl_Text_Buffer::replace_selection_(Fl_Text_Selection * sel, + const char *text) +{ Fl_Text_Selection oldSelection = *sel; - + /* If there's no selection, return */ int start, end, isRect, rectStart, rectEnd; if (!sel->position(&start, &end, &isRect, &rectStart, &rectEnd)) return; - + /* Do the appropriate type of replace */ if (isRect) replace_rectangular(start, end, rectStart, rectEnd, text); else replace(start, end, text); - + /* Unselect (happens automatically in BufReplace, but BufReplaceRect - can't detect when the contents of a selection goes away) */ + can't detect when the contents of a selection goes away) */ sel->mSelected = 0; redisplay_selection(&oldSelection, sel); } static void addPadding(char *string, int startIndent, int toIndent, - int tabDist, int useTabs, char nullSubsChar, int *charsAdded) { + int tabDist, int useTabs, int *charsAdded) +{ int indent = startIndent, len; char *outPtr = string; - + if (useTabs) { - while(indent < toIndent) { - len = Fl_Text_Buffer::character_width('\t', indent, tabDist, nullSubsChar); + while (indent < toIndent) { + //static char t = '\t'; + len = Fl_Text_Buffer::character_width("\t", indent, tabDist); if (len > 1 && indent + len <= toIndent) { - *outPtr++ = '\t'; - indent += len; + *outPtr++ = '\t'; + indent += len; } else { - *outPtr++ = ' '; - indent++; + *outPtr++ = ' '; + indent++; } } } else { @@ -2012,37 +1928,26 @@ static void addPadding(char *string, int startIndent, int toIndent, *charsAdded = outPtr - string; } -/** - Calls the stored modify callback procedure(s) for this buffer to update the - changed area(s) on the screen and any other listeners. -*/ void Fl_Text_Buffer::call_modify_callbacks(int pos, int nDeleted, - int nInserted, int nRestyled, const char *deletedText) const { + int nInserted, int nRestyled, + const char *deletedText) const { for (int i = 0; i < mNModifyProcs; i++) - (*mModifyProcs[ i ]) (pos, nInserted, nDeleted, nRestyled, - deletedText, mCbArgs[ i ]); -} - -/** - Calls the stored pre-delete callback procedure(s) for this buffer to update - the changed area(s) on the screen and any other listeners. -*/ -void Fl_Text_Buffer::call_predelete_callbacks(int pos, int nDeleted) const { - for (int i=0; imStart; newStart = newSelection->mStart; oldEnd = oldSelection->mEnd; @@ -2051,12 +1956,13 @@ void Fl_Text_Buffer::redisplay_selection(Fl_Text_Selection *oldSelection, oldEnd++; if (newSelection->mRectangular) newEnd++; - + /* If the old or new selection is unselected, just redisplay the - single area that is (was) selected and return */ + single area that is (was) selected and return */ if (!oldSelection->mSelected && !newSelection->mSelected) return; - if (!oldSelection->mSelected) { + if (!oldSelection->mSelected) + { call_modify_callbacks(newStart, 0, 0, newEnd - newStart, NULL); return; } @@ -2064,30 +1970,32 @@ void Fl_Text_Buffer::redisplay_selection(Fl_Text_Selection *oldSelection, call_modify_callbacks(oldStart, 0, 0, oldEnd - oldStart, NULL); return; } - + /* If the selection changed from normal to rectangular or visa versa, or - if a rectangular selection changed boundaries, redisplay everything */ + if a rectangular selection changed boundaries, redisplay everything */ if ((oldSelection->mRectangular && !newSelection->mRectangular) || - (!oldSelection->mRectangular && newSelection->mRectangular) || - (oldSelection->mRectangular && ( - (oldSelection->mRectStart != newSelection->mRectStart) || - (oldSelection->mRectEnd != newSelection->mRectEnd)))) { - call_modify_callbacks(min(oldStart, newStart), 0, 0, - max(oldEnd, newEnd) - min(oldStart, newStart), NULL); - return; - } - + (!oldSelection->mRectangular && newSelection->mRectangular) || + (oldSelection->mRectangular && ((oldSelection->mRectStart != + newSelection->mRectStart) + || (oldSelection->mRectEnd != + newSelection->mRectEnd)))) { + call_modify_callbacks(min(oldStart, newStart), 0, 0, + max(oldEnd, newEnd) - min(oldStart, + newStart), NULL); + return; + } + /* If the selections are non-contiguous, do two separate updates - and return */ + and return */ if (oldEnd < newStart || newEnd < oldStart) { call_modify_callbacks(oldStart, 0, 0, oldEnd - oldStart, NULL); call_modify_callbacks(newStart, 0, 0, newEnd - newStart, NULL); return; } - + /* Otherwise, separate into 3 separate regions: ch1, and ch2 (the two - changed areas), and the unchanged area of their intersection, - and update only the changed area(s) */ + changed areas), and the unchanged area of their intersection, + and update only the changed area(s) */ ch1Start = min(oldStart, newStart); ch2End = max(oldEnd, newEnd); ch1End = max(oldStart, newStart); @@ -2098,64 +2006,61 @@ void Fl_Text_Buffer::redisplay_selection(Fl_Text_Selection *oldSelection, call_modify_callbacks(ch2Start, 0, 0, ch2End - ch2Start, NULL); } -void Fl_Text_Buffer::move_gap(int pos) { +void Fl_Text_Buffer::move_gap(int pos) +{ int gapLen = mGapEnd - mGapStart; - + if (pos > mGapStart) - memmove(&mBuf[ mGapStart ], &mBuf[ mGapEnd ], - pos - mGapStart); + memmove(&mBuf[mGapStart], &mBuf[mGapEnd], pos - mGapStart); else - memmove(&mBuf[ pos + gapLen ], &mBuf[ pos ], mGapStart - pos); + memmove(&mBuf[pos + gapLen], &mBuf[pos], mGapStart - pos); mGapEnd += pos - mGapStart; mGapStart += pos - mGapStart; } -/** - Reallocates the text storage in the buffer to have a gap starting at \p newGapStart - and a gap size of \p newGapLen, preserving the buffer's current contents. -*/ -void Fl_Text_Buffer::reallocate_with_gap(int newGapStart, int newGapLen) { - char *newBuf = (char *)malloc(mLength + newGapLen); +void Fl_Text_Buffer::reallocate_with_gap(int newGapStart, int newGapLen) +{ + char *newBuf = (char *) malloc(mLength + newGapLen); int newGapEnd = newGapStart + newGapLen; - + if (newGapStart <= mGapStart) { memcpy(newBuf, mBuf, newGapStart); - memcpy(&newBuf[ newGapEnd ], &mBuf[ newGapStart ], - mGapStart - newGapStart); - memcpy(&newBuf[ newGapEnd + mGapStart - newGapStart ], - &mBuf[ mGapEnd ], mLength - mGapStart); - } else { /* newGapStart > mGapStart */ + memcpy(&newBuf[newGapEnd], &mBuf[newGapStart], + mGapStart - newGapStart); + memcpy(&newBuf[newGapEnd + mGapStart - newGapStart], + &mBuf[mGapEnd], mLength - mGapStart); + } else { /* newGapStart > mGapStart */ memcpy(newBuf, mBuf, mGapStart); - memcpy(&newBuf[ mGapStart ], &mBuf[ mGapEnd ], - newGapStart - mGapStart); - memcpy(&newBuf[ newGapEnd ], - &mBuf[ mGapEnd + newGapStart - mGapStart ], - mLength - newGapStart); + memcpy(&newBuf[mGapStart], &mBuf[mGapEnd], newGapStart - mGapStart); + memcpy(&newBuf[newGapEnd], + &mBuf[mGapEnd + newGapStart - mGapStart], + mLength - newGapStart); } free((void *) mBuf); mBuf = newBuf; mGapStart = newGapStart; mGapEnd = newGapEnd; #ifdef PURIFY -{int i; for (i = mGapStart; i < mGapEnd; i++) mBuf[ i ] = '.'; } + { + int i; + for (i = mGapStart; i < mGapEnd; i++) + mBuf[i] = '.'; + } #endif } -/** - Updates all of the selections in the buffer for changes in the buffer's text -*/ void Fl_Text_Buffer::update_selections(int pos, int nDeleted, - int nInserted) { + int nInserted) +{ mPrimary.update(pos, nDeleted, nInserted); mSecondary.update(pos, nDeleted, nInserted); mHighlight.update(pos, nDeleted, nInserted); } -/** - Updates an individual selection for changes in the corresponding text -*/ -void Fl_Text_Selection::update(int pos, int nDeleted, - int nInserted) { + +// unicode safe, assuming the arguments are on character boundaries +void Fl_Text_Selection::update(int pos, int nDeleted, int nInserted) +{ if (!mSelected || pos > mEnd) return; if (pos + nDeleted <= mStart) { @@ -2175,33 +2080,25 @@ void Fl_Text_Selection::update(int pos, int nDeleted, } } -/** - Finds the next occurrence of the specified character. - Search forwards in buffer for character \p searchChar, starting - with the character \p startPos, and returning the result in \p foundPos - returns 1 if found, 0 if not. (The difference between this and - BufSearchForward is that it's optimized for single characters. The - overall performance of the text widget is dependent on its ability to - count lines quickly, hence searching for a single character: newline) -*/ int Fl_Text_Buffer::findchar_forward(int startPos, char searchChar, - int *foundPos) const { - if (startPos < 0 || startPos >= mLength) { + int *foundPos) const { + if (startPos < 0 || startPos >= mLength) + { *foundPos = mLength; return 0; } - + int pos = startPos; while (pos < mGapStart) { - if (mBuf[ pos ] == searchChar) { + if (mBuf[pos] == searchChar) { *foundPos = pos; return 1; } pos++; } - - for(int gapLen = mGapEnd - mGapStart; pos < mLength; pos++) { - if (mBuf[ pos + gapLen ] == searchChar) { + + for (int gapLen = mGapEnd - mGapStart; pos < mLength; pos++) { + if (mBuf[pos + gapLen] == searchChar) { *foundPos = pos; return 1; } @@ -2210,32 +2107,25 @@ int Fl_Text_Buffer::findchar_forward(int startPos, char searchChar, return 0; } -/** - Search backwards in buffer \p buf for character \p searchChar, starting - with the character BEFORE \p startPos, returning the result in \p foundPos - returns 1 if found, 0 if not. (The difference between this and - BufSearchBackward is that it's optimized for single characters. The - overall performance of the text widget is dependent on its ability to - count lines quickly, hence searching for a single character: newline) -*/ int Fl_Text_Buffer::findchar_backward(int startPos, char searchChar, - int *foundPos) const{ - - if (startPos <= 0 || startPos > mLength) { + int *foundPos) const { + + if (startPos <= 0 || startPos > mLength) + { *foundPos = 0; return 0; } - + int pos = startPos - 1; for (int gapLen = mGapEnd - mGapStart; pos >= mGapStart; pos--) { - if (mBuf[ pos + gapLen ] == searchChar) { + if (mBuf[pos + gapLen] == searchChar) { *foundPos = pos; return 1; } } - + for (; pos >= 0; pos--) { - if (mBuf[ pos ] == searchChar) { + if (mBuf[pos] == searchChar) { *foundPos = pos; return 1; } @@ -2245,76 +2135,76 @@ int Fl_Text_Buffer::findchar_backward(int startPos, char searchChar, } /* - Copies from \p text to end up to but not including newline (or end of \p text) - and return the copy as the function value, and the length of the line in - \p lineLen -*/ -static char *copyLine(const char *text, int *lineLen) { + Copies from \p text to end up to but not including newline (or end of \p text) + and return the copy as the function value, and the length of the line in + \p lineLen + */ +static char *copyLine(const char *text, int *lineLen) +{ int len = 0; - + for (const char *c = text; *c != '\0' && *c != '\n'; c++) len++; - char* outStr = (char *)malloc(len + 1); + char *outStr = (char *) malloc(len + 1); strlcpy(outStr, text, len + 1); *lineLen = len; return outStr; } /* - Counts the number of newlines in a null-terminated text string; -*/ -static int countLines(const char *string) { + Counts the number of newlines in a null-terminated text string. + Unicode tested. + */ +static int countLines(const char *string) +{ int lineCount = 0; - - for (const char * c = string; *c != '\0'; c++) - if (*c == '\n') lineCount++; + + for (const char *c = string; *c != '\0'; c++) + if (*c == '\n') + lineCount++; return lineCount; } /* - Measures the width in displayed characters of string \p text -*/ -static int textWidth(const char *text, int tabDist, char nullSubsChar) { + Measures the width in displayed characters of string \p text + */ +static int textWidth(const char *text, int tabDist) +{ int width = 0, maxWidth = 0; - + + // HUH? Why is "c" incremented? Shouldn't "text" be incrmented? + // FIXME: increment is wrong! for (const char *c = text; *c != '\0'; c++) { if (*c == '\n') { if (width > maxWidth) - maxWidth = width; + maxWidth = width; width = 0; } else - width += Fl_Text_Buffer::character_width(*c, width, tabDist, nullSubsChar); + width += Fl_Text_Buffer::character_width(c, width, tabDist); } if (width > maxWidth) return width; return maxWidth; } -/** - Finds the first and last character position in a line within a rectangular - selection (for copying). Includes tabs which cross rectStart, but not - control characters which do so. Leaves off tabs which cross rectEnd. - - Technically, the calling routine should convert tab characters which - cross the right boundary of the selection to spaces which line up with - the edge of the selection. Unfortunately, the additional memory - management required in the parent routine to allow for the changes - in string size is not worth all the extra work just for a couple of - shifted characters, so if a tab protrudes, just lop it off and hope - that there are other characters in the selection to establish the right - margin for subsequent columnar pastes of this data. -*/ void Fl_Text_Buffer::rectangular_selection_boundaries(int lineStartPos, - int rectStart, int rectEnd, int *selStart, int *selEnd) const { + int rectStart, + int rectEnd, + int *selStart, + int *selEnd) const +{ int pos, width, indent = 0; char c; - + /* find the start of the selection */ - for (pos = lineStartPos; pos < mLength; pos++) { + for (pos = lineStartPos; pos < mLength; pos++) + { + // FIXME: character is ucs-4 c = character(pos); if (c == '\n') break; - width = Fl_Text_Buffer::character_width(c, indent, mTabDist, mNullSubsChar); + width = + Fl_Text_Buffer::character_width(&c, indent, mTabDist); // FIXME: c is not unicode if (indent + width > rectStart) { if (indent != rectStart && c != '\t') { pos++; @@ -2325,17 +2215,19 @@ void Fl_Text_Buffer::rectangular_selection_boundaries(int lineStartPos, indent += width; } *selStart = pos; - + /* find the end */ for (; pos < mLength; pos++) { + // FIXME: character is ucs-4 c = character(pos); if (c == '\n') break; - width = Fl_Text_Buffer::character_width(c, indent, mTabDist, mNullSubsChar); + width = + Fl_Text_Buffer::character_width(&c, indent, mTabDist); // FIXME: c is not unicode indent += width; if (indent > rectEnd) { if (indent - width != rectEnd && c != '\t') - pos++; + pos++; break; } } @@ -2343,105 +2235,114 @@ void Fl_Text_Buffer::rectangular_selection_boundaries(int lineStartPos, } /* - Adjust the space and tab characters from string \p text so that non-white - characters remain stationary when the text is shifted from starting at - \p origIndent to starting at \p newIndent. Returns an allocated string - which must be freed by the caller with XtFree. -*/ + Adjust the space and tab characters from string \p text so that non-white + characters remain stationary when the text is shifted from starting at + \p origIndent to starting at \p newIndent. Returns an allocated string + which must be freed by the caller with XtFree. + */ static char *realignTabs(const char *text, int origIndent, int newIndent, - int tabDist, int useTabs, char nullSubsChar, int *newLength) { + int tabDist, int useTabs, int *newLength) +{ /* If the tabs settings are the same, retain original tabs */ int len; char *outStr; if (origIndent % tabDist == newIndent % tabDist) { len = strlen(text); - outStr = (char *)malloc(len + 1); + outStr = (char *) malloc(len + 1); strcpy(outStr, text); *newLength = len; return outStr; } - + /* If the tab settings are not the same, brutally convert tabs to - spaces, then back to tabs in the new position */ - char *expStr = expandTabs(text, origIndent, tabDist, nullSubsChar, &len); + spaces, then back to tabs in the new position */ + char *expStr = expandTabs(text, origIndent, tabDist, &len); if (!useTabs) { *newLength = len; return expStr; } - outStr = unexpandTabs(expStr, newIndent, tabDist, nullSubsChar, newLength); + outStr = + unexpandTabs(expStr, newIndent, tabDist, newLength); free((void *) expStr); return outStr; } /* - Expand tabs to spaces for a block of text. The additional parameter - \p startIndent if nonzero, indicates that the text is a rectangular selection - beginning at column \p startIndent -*/ -static char *expandTabs(const char *text, int startIndent, int tabDist, - char nullSubsChar, int *newLen) { + Expand tabs to spaces for a block of text. The additional parameter + \p startIndent if nonzero, indicates that the text is a rectangular selection + beginning at column \p startIndent + */ +static char *expandTabs(const char *text, int startIndent, int tabDist, int *newLen) +{ /* rehearse the expansion to figure out length for output string */ int indent = startIndent, len, outLen = 0; const char *c; for (c = text; *c != '\0'; c++) { if (*c == '\t') { - len = Fl_Text_Buffer::character_width(*c, indent, tabDist, nullSubsChar); + len = + Fl_Text_Buffer::character_width(c, indent, tabDist); outLen += len; indent += len; } else if (*c == '\n') { indent = startIndent; outLen++; } else { - indent += Fl_Text_Buffer::character_width(*c, indent, tabDist, nullSubsChar); + // FIXME: character_width does not return number of bytes for UTF-8! + indent += + Fl_Text_Buffer::character_width(c, indent, tabDist); outLen++; } } - + /* do the expansion */ - char *outStr = (char *)malloc(outLen + 1); + char *outStr = (char *) malloc(outLen + 1); char *outPtr = outStr; indent = startIndent; for (c = text; *c != '\0'; c++) { if (*c == '\t') { - len = Fl_Text_Buffer::expand_character(*c, indent, outPtr, tabDist, nullSubsChar); + len = + Fl_Text_Buffer::expand_character(c, indent, outPtr, tabDist); outPtr += len; indent += len; } else if (*c == '\n') { indent = startIndent; *outPtr++ = *c; } else { - indent += Fl_Text_Buffer::character_width(*c, indent, tabDist, nullSubsChar); + // FIXME: character_width does not return number of bytes for UTF-8! + indent += + Fl_Text_Buffer::character_width(c, indent, tabDist); *outPtr++ = *c; } } - outStr[ outLen ] = '\0'; + outStr[outLen] = '\0'; *newLen = outLen; return outStr; } /* - Convert sequences of spaces into tabs. The threshold for conversion is - when 3 or more spaces can be converted into a single tab, this avoids - converting double spaces after a period withing a block of text. -*/ -static char *unexpandTabs(char *text, int startIndent, int tabDist, - char nullSubsChar, int *newLen) { - char expandedChar[ FL_TEXT_MAX_EXP_CHAR_LEN ]; - char *outStr = (char *)malloc(strlen(text) + 1); + Convert sequences of spaces into tabs. The threshold for conversion is + when 3 or more spaces can be converted into a single tab, this avoids + converting double spaces after a period withing a block of text. + */ +static char *unexpandTabs(char *text, int startIndent, int tabDist, int *newLen) +{ + char expandedChar[FL_TEXT_MAX_EXP_CHAR_LEN]; + char *outStr = (char *) malloc(strlen(text) + 1); char *outPtr = outStr; int indent = startIndent, len; - - for (const char *c=text; *c != '\0';) { + + for (const char *c = text; *c != '\0';) { if (*c == ' ') { - len = Fl_Text_Buffer::expand_character('\t', indent, expandedChar, tabDist, - nullSubsChar); + static char tab = '\t'; + len = + Fl_Text_Buffer::expand_character(&tab, indent, expandedChar, tabDist); if (len >= 3 && !strncmp(c, expandedChar, len)) { - c += len; - *outPtr++ = '\t'; - indent += len; + c += len; + *outPtr++ = '\t'; + indent += len; } else { - *outPtr++ = *c++; - indent++; + *outPtr++ = *c++; + indent++; } } else if (*c == '\n') { indent = startIndent; @@ -2456,45 +2357,37 @@ static char *unexpandTabs(char *text, int startIndent, int tabDist, return outStr; } -int -/** - Inserts a file at the specified position. Returns 0 on success, - non-zero on error (strerror() contains reason). 1 indicates open - for read failed (no data loaded). 2 indicates error occurred - while reading data (data was partially loaded). -*/ -Fl_Text_Buffer::insertfile(const char *file, int pos, int buflen) { - FILE *fp; - if (!(fp = fl_fopen(file, "r"))) return 1; +int Fl_Text_Buffer::insertfile(const char *file, int pos, int buflen) +{ + FILE *fp; + if (!(fp = fl_fopen(file, "r"))) + return 1; char *buffer = new char[buflen]; for (int r; (r = fread(buffer, 1, buflen - 1, fp)) > 0; pos += r) { - buffer[r] = (char)0; + buffer[r] = (char) 0; insert(pos, buffer); } - + int e = ferror(fp) ? 2 : 0; fclose(fp); - delete[] buffer; + delete[]buffer; return e; } -int -/** - Writes the specified portions of the file to a file. Returns 0 on success, non-zero - on error (strerror() contains reason). 1 indicates open for write failed - (no data saved). 2 indicates error occurred while writing data - (data was partially saved). -*/ -Fl_Text_Buffer::outputfile(const char *file, int start, int end, int buflen) { +int Fl_Text_Buffer::outputfile(const char *file, int start, int end, + int buflen) +{ FILE *fp; - if (!(fp = fl_fopen(file, "w"))) return 1; + if (!(fp = fl_fopen(file, "wb"))) + return 1; for (int n; (n = min(end - start, buflen)); start += n) { const char *p = text_range(start, start + n); int r = fwrite(p, 1, n, fp); - free((void *)p); - if (r != n) break; + free((void *) p); + if (r != n) + break; } - + int e = ferror(fp) ? 2 : 0; fclose(fp); return e; @@ -2502,5 +2395,5 @@ Fl_Text_Buffer::outputfile(const char *file, int start, int end, int buflen) { // -// End of "$Id: Fl_Text_Buffer.cxx 6825 2009-07-04 05:18:29Z fabien $". +// End of "$Id: Fl_Text_Buffer.cxx 7672 2010-07-10 09:44:45Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Text_Display.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Text_Display.cxx index 3e09584e8..c6b5a8195 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Text_Display.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Text_Display.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Text_Display.cxx 6909 2009-09-28 14:41:43Z matt $" +// "$Id: Fl_Text_Display.cxx 7527 2010-04-18 14:33:33Z engelsman $" // // Copyright 2001-2009 by Bill Spitzak and others. // Original code Copyright Mark Edel. Permission to distribute under @@ -223,133 +223,9 @@ void Fl_Text_Display::highlight_data(Fl_Text_Buffer *styleBuffer, mHighlightCBArg = cbArg; mStyleBuffer->canUndo(0); -#if 0 - // FIXME: this is in nedit code -- is it needed? - /* Call TextDSetFont to combine font information from style table and - primary font, adjust font-related parameters, and then redisplay */ - TextDSetFont(textD, textD->fontStruct); -#endif damage(FL_DAMAGE_EXPOSE); } -#if 0 - // FIXME: this is in nedit code -- is it needed? -/** - Change the (non highlight) font -*/ -void TextDSetFont(textDisp *textD, XFontStruct *fontStruct) { - Display *display = XtDisplay(textD->w); - int i, maxAscent = fontStruct->ascent, maxDescent = fontStruct->descent; - int width, height, fontWidth; - Pixel bgPixel, fgPixel, selectFGPixel, selectBGPixel; - Pixel highlightFGPixel, highlightBGPixel; - XGCValues values; - XFontStruct *styleFont; - - /* If font size changes, cursor will be redrawn in a new position */ - blankCursorProtrusions(textD); - - /* If there is a (syntax highlighting) style table in use, find the new - maximum font height for this text display */ - for (i=0; inStyles; i++) { - styleFont = textD->styleTable[i].font; - if (styleFont != NULL && styleFont->ascent > maxAscent) - maxAscent = styleFont->ascent; - if (styleFont != NULL && styleFont->descent > maxDescent) - maxDescent = styleFont->descent; - } - textD->ascent = maxAscent; - textD->descent = maxDescent; - - /* If all of the current fonts are fixed and match in width, compute */ - fontWidth = fontStruct->max_bounds.width; - if (fontWidth != fontStruct->min_bounds.width) - fontWidth = -1; - else { - for (i=0; inStyles; i++) { - styleFont = textD->styleTable[i].font; - if (styleFont != NULL && (styleFont->max_bounds.width != fontWidth || - styleFont->max_bounds.width != styleFont->min_bounds.width)) - fontWidth = -1; - } - } - textD->fixedFontWidth = fontWidth; - - /* Don't let the height dip below one line, or bad things can happen */ - if (textD->height < maxAscent + maxDescent) - textD->height = maxAscent + maxDescent; - - /* Change the font. In most cases, this means re-allocating the - affected GCs (they are shared with other widgets, and if the primary - font changes, must be re-allocated to change it). Unfortunately, - this requres recovering all of the colors from the existing GCs */ - textD->fontStruct = fontStruct; - XGetGCValues(display, textD->gc, GCForeground|GCBackground, &values); - fgPixel = values.foreground; - bgPixel = values.background; - XGetGCValues(display, textD->selectGC, GCForeground|GCBackground, &values); - selectFGPixel = values.foreground; - selectBGPixel = values.background; - XGetGCValues(display, textD->highlightGC,GCForeground|GCBackground,&values); - highlightFGPixel = values.foreground; - highlightBGPixel = values.background; - releaseGC(textD->w, textD->gc); - releaseGC(textD->w, textD->selectGC); - releaseGC(textD->w, textD->highlightGC); - releaseGC(textD->w, textD->selectBGGC); - releaseGC(textD->w, textD->highlightBGGC); - if (textD->lineNumGC != NULL) - releaseGC(textD->w, textD->lineNumGC); - textD->lineNumGC = NULL; - allocateFixedFontGCs(textD, fontStruct, bgPixel, fgPixel, selectFGPixel, - selectBGPixel, highlightFGPixel, highlightBGPixel); - XSetFont(display, textD->styleGC, fontStruct->fid); - - /* Do a full resize to force recalculation of font related parameters */ - width = textD->width; - height = textD->height; - textD->width = textD->height = 0; - TextDResize(textD, width, height); - - /* Redisplay */ - TextDRedisplayRect(textD, textD->left, textD->top, textD->width, - textD->height); - - /* Clean up line number area in case spacing has changed */ - draw_line_numbers(textD, True); -} - -int TextDMinFontWidth(textDisp *textD, Boolean considerStyles) { - int fontWidth = textD->fontStruct->max_bounds.width; - int i; - - if (considerStyles) { - for (i = 0; i < textD->nStyles; ++i) { - int thisWidth = (textD->styleTable[i].font)->min_bounds.width; - if (thisWidth < fontWidth) { - fontWidth = thisWidth; - } - } - } - return(fontWidth); -} - -int TextDMaxFontWidth(textDisp *textD, Boolean considerStyles) { - int fontWidth = textD->fontStruct->max_bounds.width; - int i; - - if (considerStyles) { - for (i = 0; i < textD->nStyles; ++i) { - int thisWidth = (textD->styleTable[i].font)->max_bounds.width; - if (thisWidth > fontWidth) { - fontWidth = thisWidth; - } - } - } - return(fontWidth); -} -#endif - int Fl_Text_Display::longest_vline() const { int longest = 0; for (int i = 0; i < mNVisibleLines; i++) @@ -550,6 +426,7 @@ void Fl_Text_Display::draw_text( int left, int top, int width, int height ) { void Fl_Text_Display::redisplay_range(int startpos, int endpos) { int ok = 0; while (!ok && startpos > 0) { + // FIXME: character is ucs-4 char c = buffer()->character( startpos ); if (!((c & 0x80) && !(c & 0x40))) { ok = 1; @@ -558,6 +435,7 @@ void Fl_Text_Display::redisplay_range(int startpos, int endpos) { } } while (!ok && endpos < buffer()->length()) { + // FIXME: character is ucs-4 char c = buffer()->character( endpos ); if (!((c & 0x80) && !(c & 0x40))) { ok = 1; @@ -753,7 +631,7 @@ void Fl_Text_Display::overstrike(const char* text) { startIndent = mBuffer->count_displayed_characters( lineStart, startPos ); indent = startIndent; for ( c = text; *c != '\0'; c++ ) - indent += Fl_Text_Buffer::character_width( *c, indent, buf->tab_distance(), buf->null_substitution_character() ); + indent += Fl_Text_Buffer::character_width( c, indent, buf->tab_distance() ); endIndent = indent; /* find which characters to remove, and if necessary generate additional @@ -762,10 +640,12 @@ void Fl_Text_Display::overstrike(const char* text) { for ( p = startPos; ; p++ ) { if ( p == buf->length() ) break; + // FIXME: character is ucs-4 ch = buf->character( p ); if ( ch == '\n' ) break; - indent += Fl_Text_Buffer::character_width( ch, indent, buf->tab_distance(), buf->null_substitution_character() ); + const char *s = buf->address(p); + indent += Fl_Text_Buffer::character_width(s, indent, buf->tab_distance() ); // FIXME: not unicode if ( indent == endIndent ) { p++; break; @@ -846,18 +726,12 @@ int Fl_Text_Display::position_to_xy( int pos, int* X, int* Y ) const { to "pos" to calculate the X coordinate */ xStep = text_area.x - mHorizOffset; outIndex = 0; - for ( charIndex = 0; charIndex < lineLen && charIndex < pos - lineStartPos; charIndex++ ) { - charLen = Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar, - mBuffer->tab_distance(), mBuffer->null_substitution_character() ); - if (charLen > 1 && (lineStr[ charIndex ] & 0x80)) { - int i, ii = 0;; - i = fl_utf8len(lineStr[ charIndex ]); - while (i > 1) { - i--; - ii++; - expandedChar[ii] = lineStr[ charIndex + ii]; - } - } + for (charIndex = 0; + charIndex < lineLen && charIndex < pos - lineStartPos; + charIndex += fl_utf8len(lineStr[charIndex]) ) + { + charLen = Fl_Text_Buffer::expand_character( lineStr+charIndex, outIndex, expandedChar, + mBuffer->tab_distance()); charStyle = position_style( lineStartPos, lineLen, charIndex, outIndex ); xStep += string_width( expandedChar, charLen, charStyle ); @@ -909,6 +783,7 @@ int Fl_Text_Display::in_selection( int X, int Y ) const { Fl_Text_Buffer *buf = mBuffer; int ok = 0; while (!ok) { + // FIXME: character is ucs-4 char c = buffer()->character( pos ); if (!((c & 0x80) && !(c & 0x40))) { ok = 1; @@ -1024,6 +899,7 @@ int Fl_Text_Display::move_right() { return 0; insert_position( mCursorPos + 1 ); int pos = insert_position(); + // FIXME: character is ucs-4 char c = buffer()->character( pos ); if (!((c & 0x80) && !(c & 0x40))) ok = 1; } @@ -1037,6 +913,7 @@ int Fl_Text_Display::move_left() { return 0; insert_position( mCursorPos - 1 ); int pos = insert_position(); + // FIXME: character is ucs-4 char c = buffer()->character( pos ); if (!((c & 0x80) && !(c & 0x40))) ok = 1; } @@ -1077,6 +954,7 @@ int Fl_Text_Display::move_up() { int ok = 0; while (!ok) { int pos = insert_position(); + // FIXME: character is ucs-4 char c = buffer()->character( pos ); if (!((c & 0x80) && !(c & 0x40))) { ok = 1; @@ -1113,6 +991,7 @@ int Fl_Text_Display::move_down() { int ok = 0; while (!ok) { int pos = insert_position(); + // FIXME: character is ucs-4 char c = buffer()->character( pos ); if (!((c & 0x80) && !(c & 0x40))) { ok = 1; @@ -1262,9 +1141,11 @@ static inline int fl_isseparator(int c) { /** Moves the current insert position right one word.*/ void Fl_Text_Display::next_word() { int pos = insert_position(); + // FIXME: character is ucs-4 while (pos < buffer()->length() && !fl_isseparator(buffer()->character(pos))) { pos++; } + // FIXME: character is ucs-4 while (pos < buffer()->length() && fl_isseparator(buffer()->character(pos))) { pos++; } @@ -1277,12 +1158,15 @@ void Fl_Text_Display::previous_word() { int pos = insert_position(); if (pos==0) return; pos--; + // FIXME: character is ucs-4 while (pos && fl_isseparator(buffer()->character(pos))) { pos--; } + // FIXME: character is ucs-4 while (pos && !fl_isseparator(buffer()->character(pos))) { pos--; } + // FIXME: character is ucs-4 if (fl_isseparator(buffer()->character(pos))) pos++; insert_position( pos ); @@ -1599,20 +1483,10 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip, that character */ X = text_area.x - mHorizOffset; outIndex = 0; - for ( charIndex = 0; ; charIndex++ ) { + for ( charIndex = 0; ; charIndex += lineStr ? fl_utf8len(lineStr[charIndex]) : 1 ) { charLen = charIndex >= lineLen ? 1 : - Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, - expandedChar, buf->tab_distance(), buf->null_substitution_character() ); - if (charIndex < lineLen && charLen > 1 && (lineStr[ charIndex ] & 0x80)) { - int i, ii = 0;; - i = fl_utf8len(lineStr[ charIndex ]); - while (i > 1) { - i--; - ii++; - expandedChar[ii] = lineStr[ charIndex + ii]; - } - } - + Fl_Text_Buffer::expand_character( lineStr+charIndex, outIndex, + expandedChar, buf->tab_distance()); style = position_style( lineStartPos, lineLen, charIndex, outIndex + dispIndexOffset ); charWidth = charIndex >= lineLen ? stdCharWidth : @@ -1637,22 +1511,16 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip, outPtr = outStr; outIndex = outStartIndex; X = startX; - for ( charIndex = startIndex; charIndex < rightCharIndex; charIndex++ ) { + for (charIndex = startIndex; + charIndex < rightCharIndex; + charIndex += lineStr ? fl_utf8len(lineStr[charIndex]) : 1 ) + { charLen = charIndex >= lineLen ? 1 : - Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar, - buf->tab_distance(), buf->null_substitution_character() ); - if (charIndex < lineLen && charLen > 1 && (lineStr[ charIndex ] & 0x80)) { - int i, ii = 0;; - i = fl_utf8len(lineStr[ charIndex ]); - while (i > 1) { - i--; - ii++; - expandedChar[ii] = lineStr[ charIndex + ii]; - } - } + Fl_Text_Buffer::expand_character( lineStr+charIndex, outIndex, expandedChar, + buf->tab_distance()); charStyle = position_style( lineStartPos, lineLen, charIndex, outIndex + dispIndexOffset ); - for ( i = 0; i < charLen; i++ ) { + for ( i = 0; i < charLen; i++ ) { // FIXME: this rips apart the utf-8 sequneces if ( i != 0 && charIndex < lineLen && lineStr[ charIndex ] == '\t' ) charStyle = position_style( lineStartPos, lineLen, charIndex, outIndex + dispIndexOffset ); @@ -1667,6 +1535,7 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip, int l = 1; if (*outPtr & 0x80) { l = fl_utf8len(*outPtr); + if (l<=0) l = 1; } charWidth = string_width( &expandedChar[ i ], l, charStyle ); } else @@ -1684,22 +1553,16 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip, outPtr = outStr; outIndex = outStartIndex; X = startX; - for ( charIndex = startIndex; charIndex < rightCharIndex; charIndex++ ) { + for (charIndex = startIndex; + charIndex < rightCharIndex; + charIndex += lineStr ? fl_utf8len(lineStr[charIndex]) : 0) + { charLen = charIndex >= lineLen ? 1 : - Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar, - buf->tab_distance(), buf->null_substitution_character() ); - if (charIndex < lineLen && charLen > 1 && (lineStr[ charIndex ] & 0x80)) { - int i, ii = 0;; - i = fl_utf8len(lineStr[ charIndex ]); - while (i > 1) { - i--; - ii++; - expandedChar[ii] = lineStr[ charIndex + ii]; - } - } + Fl_Text_Buffer::expand_character( lineStr+charIndex, outIndex, expandedChar, + buf->tab_distance()); charStyle = position_style( lineStartPos, lineLen, charIndex, outIndex + dispIndexOffset ); - for ( i = 0; i < charLen; i++ ) { + for ( i = 0; i < charLen; i++ ) { // FIXME: this rips apart the utf-8 sequneces if ( i != 0 && charIndex < lineLen && lineStr[ charIndex ] == '\t' ) charStyle = position_style( lineStartPos, lineLen, charIndex, outIndex + dispIndexOffset ); @@ -1714,6 +1577,7 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip, int l = 1; if (*outPtr & 0x80) { l = fl_utf8len(*outPtr); + if (l<=0) l = 1; } charWidth = string_width( &expandedChar[ i ], l, charStyle ); } else @@ -1772,7 +1636,6 @@ void Fl_Text_Display::draw_string( int style, int X, int Y, int toX, clear_rect( style, X, Y, toX - X, mMaxsize ); return; } - /* Set font, color, and gc depending on style. For normal text, GCs for normal drawing, or drawing within a Fl_Text_Selection or highlight are pre-allocated and pre-configured. For syntax highlighting, GCs are @@ -1970,10 +1833,12 @@ int Fl_Text_Display::position_style( int lineStartPos, if ( lineIndex >= lineLen ) style = FILL_MASK; else if ( styleBuf != NULL ) { + // FIXME: character is ucs-4 style = ( unsigned char ) styleBuf->character( pos ); if (style == mUnfinishedStyle && mUnfinishedHighlightCB) { /* encountered "unfinished" style, trigger parsing */ (mUnfinishedHighlightCB)( pos, mHighlightCBArg); + // FIXME: character is ucs-4 style = (unsigned char) styleBuf->character( pos); } } @@ -2045,18 +1910,12 @@ int Fl_Text_Display::xy_to_position( int X, int Y, int posType ) const { to find the character position corresponding to the X coordinate */ xStep = text_area.x - mHorizOffset; outIndex = 0; - for ( charIndex = 0; charIndex < lineLen; charIndex++ ) { - charLen = Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar, - mBuffer->tab_distance(), mBuffer->null_substitution_character() ); - if (charLen > 1 && (lineStr[ charIndex ] & 0x80)) { - int i, ii = 0;; - i = fl_utf8len(lineStr[ charIndex ]); - while (i > 1) { - i--; - ii++; - expandedChar[ii] = lineStr[ charIndex + ii]; - } - } + for (charIndex = 0; + charIndex < lineLen; + charIndex += fl_utf8len(lineStr[charIndex]) ) + { + charLen = Fl_Text_Buffer::expand_character( lineStr+charIndex, outIndex, expandedChar, + mBuffer->tab_distance()); charStyle = position_style( lineStart, lineLen, charIndex, outIndex ); charWidth = string_width( expandedChar, charLen, charStyle ); if ( X < xStep + ( posType == CURSOR_POS ? charWidth / 2 : charWidth ) ) { @@ -2500,6 +2359,7 @@ int Fl_Text_Display::measure_vline( int visLineNum ) const { for ( i = 0; i < lineLen; i++ ) { len = mBuffer->expand_character( lineStartPos + i, charCount, expandedChar ); + // FIXME: character is ucs-4 style = ( unsigned char ) mStyleBuffer->character( lineStartPos + i ) - 'A'; @@ -2608,6 +2468,7 @@ void Fl_Text_Display::find_wrap_range(const char *deletedText, int pos, lineStart = retPos; nLines++; if (lineStart > pos + nInserted && + // FIXME: character is ucs-4 buf->character(lineStart-1) == '\n') { countTo = lineStart; *modRangeEnd = lineStart; @@ -2753,6 +2614,7 @@ void Fl_Text_Display::measure_deleted_lines(int pos, int nDeleted) { lineStart = retPos; nLines++; if (lineStart > pos + nDeleted && + // FIXME: character is ucs-4 buf->character(lineStart-1) == '\n') { break; } @@ -2800,7 +2662,6 @@ void Fl_Text_Display::wrapped_line_counter(Fl_Text_Buffer *buf, int startPos, bool countPixels; int nLines = 0, tabDist = buffer()->tab_distance(); unsigned char c; - char nullSubsChar = buffer()->null_substitution_character(); /* If the font is fixed, or there's a wrap margin set, it's more efficient to measure in columns, than to count pixels. Determine if we can count @@ -2831,6 +2692,7 @@ void Fl_Text_Display::wrapped_line_counter(Fl_Text_Buffer *buf, int startPos, colNum = 0; width = 0; for (p=lineStart; plength(); p++) { + // FIXME: character is ucs-4 c = (unsigned char)buf->character(p); /* If the character was a newline, count the line and start over, @@ -2855,9 +2717,10 @@ void Fl_Text_Display::wrapped_line_counter(Fl_Text_Buffer *buf, int startPos, colNum = 0; width = 0; } else { - colNum += Fl_Text_Buffer::character_width(c, colNum, tabDist, nullSubsChar); + const char *s = buf->address(p); + colNum += Fl_Text_Buffer::character_width(s, colNum, tabDist); // FIXME: unicode if (countPixels) - width += measure_proportional_character(c, colNum, p+styleBufOffset); + width += measure_proportional_character(s, colNum, p+styleBufOffset); } /* If character exceeded wrap margin, find the break point @@ -2865,6 +2728,7 @@ void Fl_Text_Display::wrapped_line_counter(Fl_Text_Buffer *buf, int startPos, if (colNum > wrapMargin || width > maxWidth) { foundBreak = false; for (b=p; b>=lineStart; b--) { + // FIXME: character is ucs-4 c = (unsigned char)buf->character(b); if (c == '\t' || c == ' ') { newLineStart = b + 1; @@ -2873,7 +2737,8 @@ void Fl_Text_Display::wrapped_line_counter(Fl_Text_Buffer *buf, int startPos, width = 0; for (i=b+1; icharacter(i), colNum, + // FIXME: character is ucs-4 + buf->address(i), colNum, i+styleBufOffset); colNum++; } @@ -2885,9 +2750,10 @@ void Fl_Text_Display::wrapped_line_counter(Fl_Text_Buffer *buf, int startPos, } if (!foundBreak) { /* no whitespace, just break at margin */ newLineStart = max(p, lineStart+1); - colNum = Fl_Text_Buffer::character_width(c, colNum, tabDist, nullSubsChar); + const char *s = buf->address(b); + colNum = Fl_Text_Buffer::character_width(s, colNum, tabDist); // FIXME: unicode if (countPixels) - width = measure_proportional_character(c, colNum, p+styleBufOffset); + width = measure_proportional_character(s, colNum, p+styleBufOffset); } if (p >= maxPos) { *retPos = maxPos; @@ -2919,9 +2785,9 @@ void Fl_Text_Display::wrapped_line_counter(Fl_Text_Buffer *buf, int startPos, } /** - Measure the width in pixels of a character "c" at a particular column - "colNum" and buffer position "pos". This is for measuring characters in - proportional or mixed-width highlighting fonts. + Measure the width in pixels of the first character of string "s" at a + particular column "colNum" and buffer position "pos". This is for measuring + characters in proportional or mixed-width highlighting fonts. ** A note about proportional and mixed-width fonts: the mixed width and proportional font code in nedit does not get much use in general editing, @@ -2932,20 +2798,22 @@ void Fl_Text_Display::wrapped_line_counter(Fl_Text_Buffer *buf, int startPos, insertion/deletion, though static display and wrapping and resizing should now be solid because they are now used for online help display. */ -int Fl_Text_Display::measure_proportional_character(char c, int colNum, int pos) const { + +int Fl_Text_Display::measure_proportional_character(const char *s, int colNum, int pos) const { int charLen, style; char expChar[ FL_TEXT_MAX_EXP_CHAR_LEN ]; Fl_Text_Buffer *styleBuf = mStyleBuffer; - charLen = Fl_Text_Buffer::expand_character(c, colNum, expChar, - buffer()->tab_distance(), buffer()->null_substitution_character()); + charLen = Fl_Text_Buffer::expand_character(s, colNum, expChar, buffer()->tab_distance()); // FIXME: unicode if (styleBuf == 0) { style = 0; } else { + // FIXME: character is ucs-4 style = (unsigned char)styleBuf->character(pos); if (style == mUnfinishedStyle && mUnfinishedHighlightCB) { /* encountered "unfinished" style, trigger parsing */ (mUnfinishedHighlightCB)(pos, mHighlightCBArg); + // FIXME: character is ucs-4 style = (unsigned char)styleBuf->character(pos); } } @@ -3002,6 +2870,7 @@ int Fl_Text_Display::wrap_uses_character(int lineEndPos) const { if (!mContinuousWrap || lineEndPos == buffer()->length()) return 1; + // FIXME: character is ucs-4 c = buffer()->character(lineEndPos); return c == '\n' || ((c == '\t' || c == ' ') && lineEndPos + 1 != buffer()->length()); @@ -3281,6 +3150,7 @@ int Fl_Text_Display::handle(int event) { int pos = xy_to_position(Fl::event_x(), Fl::event_y(), CURSOR_POS); int ok = 0; while (!ok) { + // FIXME: character is ucs-4 char c = buffer()->character( pos ); if (!((c & 0x80) && !(c & 0x40))) { ok = 1; @@ -3346,6 +3216,7 @@ int Fl_Text_Display::handle(int event) { pos = xy_to_position(X, Y, CURSOR_POS); int ok = 0; while (!ok) { + // FIXME: character is ucs-4 char c = buffer()->character( pos ); if (!((c & 0x80) && !(c & 0x40))) { ok = 1; @@ -3439,5 +3310,5 @@ int Fl_Text_Display::handle(int event) { // -// End of "$Id: Fl_Text_Display.cxx 6909 2009-09-28 14:41:43Z matt $". +// End of "$Id: Fl_Text_Display.cxx 7527 2010-04-18 14:33:33Z engelsman $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Text_Editor.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Text_Editor.cxx index dc471cafe..a670fb780 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Text_Editor.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Text_Editor.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Text_Editor.cxx 6894 2009-09-20 21:55:21Z greg.ercolano $" +// "$Id: Fl_Text_Editor.cxx 7462 2010-04-06 23:00:56Z matt $" // // Copyright 2001-2009 by Bill Spitzak and others. // Original code Copyright Mark Edel. Permission to distribute under @@ -254,6 +254,7 @@ int Fl_Text_Editor::kf_ignore(int, Fl_Text_Editor*) { int Fl_Text_Editor::kf_backspace(int, Fl_Text_Editor* e) { if (!e->buffer()->selected() && e->move_left()) { int l = 1; + // FIXME: character is ucs-4 char c = e->buffer()->character(e->insert_position()); if (c & 0x80 && c & 0x40) { l = fl_utf8len(c); @@ -449,6 +450,7 @@ int Fl_Text_Editor::kf_insert(int, Fl_Text_Editor* e) { int Fl_Text_Editor::kf_delete(int, Fl_Text_Editor* e) { if (!e->buffer()->selected()) { int l = 1; + // FIXME: character is ucs-4 char c = e->buffer()->character(e->insert_position()); if (c & 0x80 && c & 0x40) { l = fl_utf8len(c); @@ -614,5 +616,5 @@ int Fl_Text_Editor::handle(int event) { } // -// End of "$Id: Fl_Text_Editor.cxx 6894 2009-09-20 21:55:21Z greg.ercolano $". +// End of "$Id: Fl_Text_Editor.cxx 7462 2010-04-06 23:00:56Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Tree.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Tree.cxx new file mode 100644 index 000000000..76cabe9f0 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Tree.cxx @@ -0,0 +1,482 @@ +// +// "$Id: Fl_Tree.cxx 7672 2010-07-10 09:44:45Z matt $" +// + +#include +#include +#include + +#include +#include + +#define SCROLL_W 15 + +////////////////////// +// Fl_Tree.cxx +////////////////////// +// +// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK +// Copyright (C) 2009 by Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +// INTERNAL: scroller callback +static void scroll_cb(Fl_Widget*,void *data) { + ((Fl_Tree*)data)->redraw(); +} + +// INTERNAL: Parse elements from path into an array of null terminated strings +// Path="/aa/bb" +// Return: arr[0]="aa", arr[1]="bb", arr[2]=0 +// Caller must: free(arr[0]); free(arr); +// +static char **parse_path(const char *path) { + while ( *path == '/' ) path++; // skip leading '/' + // First pass: identify, null terminate, and count separators + int seps = 1; // separator count (1: first item) + int arrsize = 1; // array size (1: first item) + char *save = strdup(path); // make copy we can modify + char *s = save; + while ( ( s = strchr(s, '/') ) ) { + while ( *s == '/' ) { *s++ = 0; seps++; } + if ( *s ) { arrsize++; } + } + arrsize++; // (room for terminating NULL) + // Second pass: create array, save nonblank elements + char **arr = (char**)malloc(sizeof(char*) * arrsize); + int t = 0; + s = save; + while ( seps-- > 0 ) { + if ( *s ) { arr[t++] = s; } // skips empty fields, eg. '//' + s += (strlen(s) + 1); + } + arr[t] = 0; + return(arr); +} + +// INTERNAL: Recursively descend tree hierarchy, accumulating total child count +static int find_total_children(Fl_Tree_Item *item, int count=0) { + count++; + for ( int t=0; tchildren(); t++ ) { + count = find_total_children(item->child(t), count); + } + return(count); +} + +/// Constructor. +Fl_Tree::Fl_Tree(int X, int Y, int W, int H, const char *L) : Fl_Group(X,Y,W,H,L) { + _root = new Fl_Tree_Item(_prefs); + _root->parent(0); // we are root of tree + _root->label("ROOT"); + _item_clicked = 0; + box(FL_DOWN_BOX); + color(FL_WHITE); + when(FL_WHEN_CHANGED); + _vscroll = new Fl_Scrollbar(0,0,0,0); // will be resized by draw() + _vscroll->hide(); + _vscroll->type(FL_VERTICAL); + _vscroll->step(1); + _vscroll->callback(scroll_cb, (void*)this); + end(); +} + +/// Destructor. +Fl_Tree::~Fl_Tree() { + if ( _root ) { delete _root; _root = 0; } +} + +/// Adds a new item, given a 'menu style' path, eg: "/Parent/Child/item". +/// Any parent nodes that don't already exist are created automatically. +/// Adds the item based on the value of sortorder(). +/// \returns the child item created, or 0 on error. +/// +Fl_Tree_Item* Fl_Tree::add(const char *path) { + if ( ! _root ) { // Create root if none + _root = new Fl_Tree_Item(_prefs); + _root->parent(0); + _root->label("ROOT"); + } + char **arr = parse_path(path); + Fl_Tree_Item *item = _root->add(_prefs, arr); + free((void*)arr[0]); + free((void*)arr); + return(item); +} + +/// Inserts a new item above the specified Fl_Tree_Item, with the label set to 'name'. +/// \returns the item that was added, or 0 if 'above' could not be found. +/// +Fl_Tree_Item* Fl_Tree::insert_above(Fl_Tree_Item *above, const char *name) { + return(above->insert_above(_prefs, name)); +} + +/// Insert a new item into a tree-item's children at a specified position. +/// \returns the item that was added. +Fl_Tree_Item* Fl_Tree::insert(Fl_Tree_Item *item, const char *name, int pos) { + return(item->insert(_prefs, name, pos)); +} + +/// Add a new child to a tree-item. +/// \returns the item that was added. +Fl_Tree_Item* Fl_Tree::add(Fl_Tree_Item *item, const char *name) { + return(item->add(_prefs, name)); +} + +/// Find the item, given a menu style path, eg: "/Parent/Child/item". +/// +/// There is both a const and non-const version of this method. +/// Const version allows pure const methods to use this method +/// to do lookups without causing compiler errors. +/// \returns the item, or 0 if not found. +/// +Fl_Tree_Item *Fl_Tree::find_item(const char *path) { + if ( ! _root ) return(0); + char **arr = parse_path(path); + Fl_Tree_Item *item = _root->find_item(arr); + free((void*)arr[0]); + free((void*)arr); + return(item); +} + +/// A const version of Fl_Tree::find_item(const char *path) +const Fl_Tree_Item *Fl_Tree::find_item(const char *path) const { + if ( ! _root ) return(0); + char **arr = parse_path(path); + const Fl_Tree_Item *item = _root->find_item(arr); + free((void*)arr[0]); + free((void*)arr); + return(item); +} + +/// Standard FLTK draw() method, handles draws the tree widget. +void Fl_Tree::draw() { + // Let group draw box+label but *NOT* children. + // We handle drawing children ourselves by calling each item's draw() + // + Fl_Group::draw_box(); + Fl_Group::draw_label(); + if ( ! _root ) return; + int cx = x() + Fl::box_dx(box()); + int cy = y() + Fl::box_dy(box()); + int cw = w() - Fl::box_dw(box()); + int ch = h() - Fl::box_dh(box()); + // These values are changed during drawing + // 'Y' will be the lowest point on the tree + int X = cx + _prefs.marginleft(); + int Y = cy + _prefs.margintop() - (_vscroll->visible() ? _vscroll->value() : 0); + int W = cw - _prefs.marginleft(); // - _prefs.marginright(); + int Ysave = Y; + fl_push_clip(cx,cy,cw,ch); + { + fl_font(_prefs.labelfont(), _prefs.labelsize()); + _root->draw(X, Y, W, this, _prefs); + } + fl_pop_clip(); + + // Show vertical scrollbar? + int ydiff = (Y+_prefs.margintop())-Ysave; // ydiff=size of tree + int ytoofar = (cy+ch) - Y; // ytoofar -- scrolled beyond bottom (eg. stow) + + //printf("ydiff=%d ch=%d Ysave=%d ytoofar=%d value=%d\n", + //int(ydiff),int(ch),int(Ysave),int(ytoofar), int(_vscroll->value())); + + if ( ytoofar > 0 ) ydiff += ytoofar; + if ( Ysave ch || int(_vscroll->value()) > 1 ) { + _vscroll->visible(); + int sx = x()+w()-Fl::box_dx(box())-SCROLL_W; + int sy = y()+Fl::box_dy(box()); + int sw = SCROLL_W; + int sh = h()-Fl::box_dh(box()); + _vscroll->show(); + _vscroll->range(0.0,ydiff-ch); + _vscroll->resize(sx,sy,sw,sh); + _vscroll->slider_size(float(ch)/float(ydiff)); + } else { + _vscroll->Fl_Slider::value(0); + _vscroll->hide(); + } + fl_push_clip(cx,cy,cw,ch); + Fl_Group::draw_children(); // draws any FLTK children set via Fl_Tree::widget() + fl_pop_clip(); +} + +/// Standard FLTK event handler for this widget. +int Fl_Tree::handle(int e) { + static Fl_Tree_Item *lastselect = 0; + int changed = 0; + int ret = Fl_Group::handle(e); + if ( ! _root ) return(ret); + switch ( e ) { + case FL_PUSH: { + lastselect = 0; + item_clicked(0); // assume no item was clicked + Fl_Tree_Item *o = _root->find_clicked(_prefs); + if ( o ) { + ret |= 1; // handled + if ( Fl::event_button() == FL_LEFT_MOUSE ) { + // Was collapse icon clicked? + if ( o->event_on_collapse_icon(_prefs) ) { + o->open_toggle(); + redraw(); + } + // Item's label clicked? + else if ( o->event_on_label(_prefs) && + (!o->widget() || !Fl::event_inside(o->widget())) && + callback() && + (!_vscroll->visible() || !Fl::event_inside(_vscroll)) ) { + item_clicked(o); // save item clicked + + // Handle selection behavior + switch ( _prefs.selectmode() ) { + case FL_TREE_SELECT_NONE: { // no selection changes + break; + } + case FL_TREE_SELECT_SINGLE: { + changed = select_only(o); + break; + } + case FL_TREE_SELECT_MULTI: { + int state = Fl::event_state(); + if ( state & FL_SHIFT ) { + if ( ! o->is_selected() ) { + o->select(); // add to selection + changed = 1; // changed + } + } else if ( state & FL_CTRL ) { + changed = 1; // changed + o->select_toggle(); // toggle selection state + lastselect = o; // save we toggled it (prevents oscillation) + } else { + changed = select_only(o); + } + break; + } + } + + if ( changed ) { + redraw(); // make change(s) visible + if ( when() & FL_WHEN_CHANGED ) { + set_changed(); + do_callback((Fl_Widget*)this, user_data()); // item callback + } + } + } + } + } + break; + } + case FL_DRAG: { + if ( Fl::event_button() != FL_LEFT_MOUSE ) break; + Fl_Tree_Item *o = _root->find_clicked(_prefs); + if ( o ) { + ret |= 1; // handled + // Item's label clicked? + if ( o->event_on_label(_prefs) && + (!o->widget() || !Fl::event_inside(o->widget())) && + callback() && + (!_vscroll->visible() || !Fl::event_inside(_vscroll)) ) { + item_clicked(o); // save item clicked + // Handle selection behavior + switch ( _prefs.selectmode() ) { + case FL_TREE_SELECT_NONE: { // no selection changes + break; + } + case FL_TREE_SELECT_SINGLE: { + changed = select_only(o); + break; + } + case FL_TREE_SELECT_MULTI: { + int state = Fl::event_state(); + if ( state & FL_CTRL ) { + if ( lastselect != o ) {// not already toggled from last microdrag? + changed = 1; // changed + o->select_toggle(); // toggle selection + lastselect = o; // save we toggled it (prevents oscillation) + } + } else { + if ( ! o->is_selected() ) { + changed = 1; // changed + o->select(); // select this + } + } + break; + } + } + if ( changed ) { + redraw(); // make change(s) visible + if ( when() & FL_WHEN_CHANGED ) { + set_changed(); + do_callback((Fl_Widget*)this, user_data()); // item callback + } + } + } + } + break; + } + case FL_RELEASE: { + if ( Fl::event_button() == FL_LEFT_MOUSE ) { + ret |= 1; + if ( when() & FL_WHEN_RELEASE || ( this->changed() && (when() & FL_WHEN_CHANGED)) ) { + do_callback((Fl_Widget*)this, user_data()); // item callback + } + } + break; + } + } + return(ret); +} + +/// Deselect item and all its children. +/// If item is NULL, root() is used. +/// Handles calling redraw() if anything was changed. +/// Returns count of how many items were in the 'selected' state, +/// ie. how many items were "changed". +/// +/// \p docallback is an optional paramemter that can either be 0 or 1: +/// +/// - 0 - the callback() is not invoked (default) +/// - 1 - the callback() is invoked once if \b any items changed state, +/// and item_clicked() will be NULL (since many items could have been changed). +// +/// \todo deselect_all()'s docallback should support '2' (invoke callback for each item changed) +/// +int Fl_Tree::deselect_all(Fl_Tree_Item *item, int docallback) { + item = item ? item : root(); // NULL? use root() + int count = item->deselect_all(); + if ( count ) { + redraw(); // anything changed? cause redraw + if ( docallback == 1 ) + do_callback_for_item(0); + } + return(count); +} + +/// Select item and all its children. +/// If item is NULL, root() is used. +/// Handles calling redraw() if anything was changed. +/// Returns count of how many items were in the 'deselected' state, +/// ie. how many items were "changed". +/// +/// \p docallback is an optional paramemter that can either be 0 or 1: +/// +/// - 0 - the callback() is not invoked (default) +/// - 1 - the callback() is invoked once if \b any items changed state, +/// and item_clicked() will be NULL (since many items could have been changed). +/// +/// \todo select_all()'s docallback should support '2' (invoke callback for each item changed) +/// +int Fl_Tree::select_all(Fl_Tree_Item *item, int docallback) { + item = item ? item : root(); // NULL? use root() + int count = item->select_all(); + if ( count ) { + redraw(); // anything changed? cause redraw + if (docallback == 1) + do_callback_for_item(0); + } + return(count); +} + +/// Select only this item. +/// If item is NULL, root() is used. +/// Handles calling redraw() if anything was changed. +/// Returns how many items were changed, if any. +/// +/// \p docallback is an optional paramemter that can either be 0, 1 or 2: +/// +/// - 0 - the callback() is not invoked (default) +/// - 1 - the callback() is invoked once if \b any items changed state, +/// and item_clicked() will be NULL (since many items could have been changed). +/// - 2 - the callback() is invoked once for \b each item that changed state, +/// and the callback() can use item_clicked() to determine the item changed. +/// +int Fl_Tree::select_only(Fl_Tree_Item *selitem, int docallback) { + selitem = selitem ? selitem : root(); // NULL? use root() + int changed = 0; + for ( Fl_Tree_Item *item = first(); item; item = item->next() ) { + if ( item == selitem ) { + if ( item->is_selected() ) continue; // don't count if already selected + item->select(); + ++changed; + if ( docallback == 2 ) do_callback_for_item(item); + } else { + if ( item->is_selected() ) { + item->deselect(); + ++changed; + if ( docallback == 2 ) do_callback_for_item(item); + } + } + } + if ( changed ) { + redraw(); // anything changed? redraw + if ( docallback == 1 ) do_callback_for_item(0); + } + return(changed); +} + +/** + * Read a preferences database into the tree widget. + * A preferences database is a hierarchical collection of data which can be + * directly loaded into the tree view for inspection. + * \param[in] prefs the Fl_Preferences database + */ +void Fl_Tree::load(Fl_Preferences &prefs) +{ + int i, j, n, pn = strlen(prefs.path()); + char *p; + const char *path = prefs.path(); + if (strcmp(path, ".")==0) + path += 1; // root path is empty + else + path += 2; // child path starts with "./" + n = prefs.groups(); + for (i=0; i +#include +#include +#include +#include +#include + +////////////////////// +// Fl_Tree_Item.cxx +////////////////////// +// +// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK +// Copyright (C) 2009 by Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +// Was the last event inside the specified xywh? +static int event_inside(const int xywh[4]) { + return(Fl::event_inside(xywh[0],xywh[1],xywh[2],xywh[3])); +} + +/// Constructor. +/// Makes a new instance of Fl_Tree_Item using defaults from 'prefs'. +/// +Fl_Tree_Item::Fl_Tree_Item(const Fl_Tree_Prefs &prefs) { + _label = 0; + _labelfont = prefs.labelfont(); + _labelsize = prefs.labelsize(); + _labelfgcolor = prefs.fgcolor(); + _labelbgcolor = prefs.bgcolor(); + _widget = 0; + _open = 1; + _visible = 1; + _active = 1; + _selected = 0; + _xywh[0] = 0; + _xywh[1] = 0; + _xywh[2] = 0; + _xywh[3] = 0; + _collapse_xywh[0] = 0; + _collapse_xywh[1] = 0; + _collapse_xywh[2] = 0; + _collapse_xywh[3] = 0; + _label_xywh[0] = 0; + _label_xywh[1] = 0; + _label_xywh[2] = 0; + _label_xywh[3] = 0; + _usericon = 0; + _userdata = 0; + _parent = 0; +} + +// DTOR +Fl_Tree_Item::~Fl_Tree_Item() { + if ( _label ) { + free((void*)_label); + _label = 0; + } + _widget = 0; // Fl_Group will handle destruction + _usericon = 0; // user handled allocation + //_children.clear(); // array's destructor handles itself +} + +/// Copy constructor. +Fl_Tree_Item::Fl_Tree_Item(const Fl_Tree_Item *o) { + _label = o->label() ? strdup(o->label()) : 0; + _labelfont = o->labelfont(); + _labelsize = o->labelsize(); + _labelfgcolor = o->labelfgcolor(); + _labelbgcolor = o->labelbgcolor(); + _widget = o->widget(); + _open = o->_open; + _visible = o->_visible; + _active = o->_active; + _selected = o->_selected; + _xywh[0] = o->_xywh[0]; + _xywh[1] = o->_xywh[1]; + _xywh[2] = o->_xywh[2]; + _xywh[3] = o->_xywh[3]; + _collapse_xywh[0] = o->_collapse_xywh[0]; + _collapse_xywh[1] = o->_collapse_xywh[1]; + _collapse_xywh[2] = o->_collapse_xywh[2]; + _collapse_xywh[3] = o->_collapse_xywh[3]; + _label_xywh[0] = o->_label_xywh[0]; + _label_xywh[1] = o->_label_xywh[1]; + _label_xywh[2] = o->_label_xywh[2]; + _label_xywh[3] = o->_label_xywh[3]; + _usericon = o->usericon(); + _userdata = o->user_data(); + _parent = o->_parent; +} + +/// Print the tree as 'ascii art' to stdout. +/// Used mainly for debugging. +/// +void Fl_Tree_Item::show_self(const char *indent) const { + if ( label() ) { + printf("%s-%s (%d children, this=%p, parent=%p depth=%d)\n", + indent,label(),children(),(void*)this, (void*)_parent, depth()); + } + if ( children() ) { + char *i2 = (char*)malloc(strlen(indent) + 2); + strcpy(i2, indent); + strcat(i2, " |"); + for ( int t=0; tshow_self(i2); + } + } + fflush(stdout); +} + +/// Set the label. Makes a copy of the name. +void Fl_Tree_Item::label(const char *name) { + if ( _label ) { free((void*)_label); _label = 0; } + _label = name ? strdup(name) : 0; +} + +/// Return the label. +const char *Fl_Tree_Item::label() const { + return(_label); +} + +/// Return child item for the specified 'index'. +const Fl_Tree_Item *Fl_Tree_Item::child(int index) const { + return(_children[index]); +} + +/// Clear all the children for this item. +void Fl_Tree_Item::clear_children() { + _children.clear(); +} + +/// Return the index of the immediate child of this item that has the label 'name'. +/// +/// \returns index of found item, or -1 if not found. +/// +int Fl_Tree_Item::find_child(const char *name) { + if ( name ) { + for ( int t=0; tlabel() ) { + if ( strcmp(child(t)->label(), name) == 0 ) { + return(t); + } + } + } + } + return(-1); +} + +/// Find item by descending array of names. +/// Only Fl_Tree should need this method. +/// +/// \returns item, or 0 if not found +/// +const Fl_Tree_Item *Fl_Tree_Item::find_item(char **arr) const { + for ( int t=0; tlabel() ) { + if ( strcmp(child(t)->label(), *arr) == 0 ) { // match? + if ( *(arr+1) ) { // more in arr? descend + return(_children[t]->find_item(arr+1)); + } else { // end of arr? done + return(_children[t]); + } + } + } + } + return(0); +} + +/// Find item by by descending array of names. +/// Only Fl_Tree should need this method. +/// +/// \returns item, or 0 if not found +/// +Fl_Tree_Item *Fl_Tree_Item::find_item(char **arr) { + for ( int t=0; tlabel() ) { + if ( strcmp(child(t)->label(), *arr) == 0 ) { // match? + if ( *(arr+1) ) { // more in arr? descend + return(_children[t]->find_item(arr+1)); + } else { // end of arr? done + return(_children[t]); + } + } + } + } + return(0); +} + +/// Find the index number for the specified 'item' +/// in the current item's list of children. +/// +/// \returns the index, or -1 if not found. +/// +int Fl_Tree_Item::find_child(Fl_Tree_Item *item) { + for ( int t=0; tlabel(new_label); + item->_parent = this; + switch ( prefs.sortorder() ) { + case FL_TREE_SORT_NONE: { + _children.add(item); + return(item); + } + case FL_TREE_SORT_ASCENDING: { + for ( int t=0; t<_children.total(); t++ ) { + Fl_Tree_Item *c = _children[t]; + if ( c->label() && strcmp(c->label(), new_label) > 0 ) { + _children.insert(t, item); + return(item); + } + } + _children.add(item); + return(item); + } + case FL_TREE_SORT_DESCENDING: { + for ( int t=0; t<_children.total(); t++ ) { + Fl_Tree_Item *c = _children[t]; + if ( c->label() && strcmp(c->label(), new_label) < 0 ) { + _children.insert(t, item); + return(item); + } + } + _children.add(item); + return(item); + } + } + return(item); +} + +/// Descend into the path specified by \p arr, and add a new child there. +/// Should be used only by Fl_Tree's internals. +/// Adds the item based on the value of prefs.sortorder(). +/// \returns the item added. +/// +Fl_Tree_Item *Fl_Tree_Item::add(const Fl_Tree_Prefs &prefs, char **arr) { + int t = find_child(*arr); + Fl_Tree_Item *item; + if ( t == -1 ) { + item = (Fl_Tree_Item*)add(prefs, *arr); + } else { + item = (Fl_Tree_Item*)child(t); + } + if ( *(arr+1) ) { // descend? + return(item->add(prefs, arr+1)); + } else { + return(item); // end? done + } +} + +/// Insert a new item into current item's children at a specified position. +/// \returns the new item inserted. +/// +Fl_Tree_Item *Fl_Tree_Item::insert(const Fl_Tree_Prefs &prefs, const char *new_label, int pos) { + Fl_Tree_Item *item = new Fl_Tree_Item(prefs); + item->label(new_label); + item->_parent = this; + _children.insert(pos, item); + return(item); +} + +/// Insert a new item above this item. +/// \returns the new item inserted, or 0 if an error occurred. +/// +Fl_Tree_Item *Fl_Tree_Item::insert_above(const Fl_Tree_Prefs &prefs, const char *new_label) { + Fl_Tree_Item *p = _parent; + if ( ! p ) return(0); + // Walk our parent's children to find ourself + for ( int t=0; tchildren(); t++ ) { + Fl_Tree_Item *c = p->child(t); + if ( this == c ) { + return(p->insert(prefs, new_label, t)); + } + } + return(0); +} + +/// Remove child by item. +/// \returns 0 if removed, -1 if item not an immediate child. +/// +int Fl_Tree_Item::remove_child(Fl_Tree_Item *item) { + for ( int t=0; tclear_children(); + _children.remove(t); + return(0); + } + } + return(-1); +} + +/// Remove immediate child (and its children) by its label 'name'. +/// \returns 0 if removed, -1 if not found. +/// +int Fl_Tree_Item::remove_child(const char *name) { + for ( int t=0; tlabel() ) { + if ( strcmp(child(t)->label(), name) == 0 ) { + _children.remove(t); + return(0); + } + } + } + return(-1); +} + +/// Swap two of our children, given two child index values. +/// Use this eg. for sorting. +/// +/// This method is FAST, and does not involve lookups. +/// +/// No range checking is done on either index value. +/// +/// \returns +/// - 0 : OK +/// - -1 : failed: 'a' or 'b' is not our immediate child +/// +void Fl_Tree_Item::swap_children(int ax, int bx) { + _children.swap(ax, bx); +} + +/// Swap two of our children, given item pointers. +/// Use this eg. for sorting. +/// +/// This method is SLOW because it involves linear lookups. +/// For speed, use swap_children(int,int) instead. +/// +/// \returns +/// - 0 : OK +/// - -1 : failed: 'a' or 'b' is not our immediate child +/// +int Fl_Tree_Item::swap_children(Fl_Tree_Item *a, Fl_Tree_Item *b) { + int ax = -1, bx = -1; + for ( int t=0; tfind_clicked(prefs) ) != NULL) { // check child and its descendents + return(item); // found? + } + } + } + return(0); +} + +/// Non-const version of the above. +/// Find the item that the last event was over. +/// +/// Returns the item if its visible, and mouse is over it. +/// Works even if widget deactivated. +/// Use event_on_collapse_icon() to determine if collapse button was pressed. +/// +/// \returns the visible item under the event if found, or 0 if none. +/// +Fl_Tree_Item *Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs &prefs) { + if ( ! _visible ) return(0); + if ( is_root() && !prefs.showroot() ) { + // skip event check if we're root but root not being shown + } else { + // See if event is over us + if ( event_inside(_xywh) ) { // event within this item? + return(this); // found + } + } + if ( is_open() ) { // open? check children of this item + for ( int t=0; tfind_clicked(prefs) ) != NULL ) { // check child and its descendents + return(item); // found? + } + } + } + return(0); +} + +/// Draw this item and its children. +void Fl_Tree_Item::draw(int X, int &Y, int W, Fl_Widget *tree, + const Fl_Tree_Prefs &prefs, int lastchild) { + if ( ! _visible ) return; + fl_font(_labelfont, _labelsize); + int H = _labelsize; + if(usericon() && H < usericon()->h()) H = usericon()->h(); + H += prefs.linespacing() + fl_descent(); + // adjust horizontally if we draw no connecting lines + if ( is_root() && prefs.connectorstyle() == FL_TREE_CONNECTOR_NONE ) { + X -= prefs.openicon()->w(); + W += prefs.openicon()->w(); + } + // Colors, fonts + Fl_Color fg = _selected ? prefs.bgcolor() : _labelfgcolor; + Fl_Color bg = _selected ? prefs.selectcolor() : _labelbgcolor; + if ( ! _active ) { + fg = fl_inactive(fg); + if ( _selected ) bg = fl_inactive(bg); + } + // Update the xywh of this item + _xywh[0] = X; + _xywh[1] = Y; + _xywh[2] = W; + _xywh[3] = H; + // Text size + int textw=0, texth=0; + fl_measure(_label, textw, texth, 0); + int textycenter = Y+(H/2); + int &icon_w = _collapse_xywh[2] = prefs.openicon()->w(); + int &icon_x = _collapse_xywh[0] = X + (icon_w + prefs.connectorwidth())/2 - 3; + int &icon_y = _collapse_xywh[1] = textycenter - (prefs.openicon()->h()/2); + _collapse_xywh[3] = prefs.openicon()->h(); + // Horizontal connector values + int hstartx = X+icon_w/2-1; + int hendx = hstartx + prefs.connectorwidth(); + int hcenterx = X + icon_w + ((hendx - (X + icon_w)) / 2); + + // See if we should draw this item + // If this item is root, and showroot() is disabled, don't draw. + // + char drawthis = ( is_root() && prefs.showroot() == 0 ) ? 0 : 1; + if ( drawthis ) { + // Draw connectors + if ( prefs.connectorstyle() != FL_TREE_CONNECTOR_NONE ) { + // Horiz connector between center of icon and text + // if this is root, the connector should not dangle in thin air on the left + if (is_root()) + draw_horizontal_connector(hcenterx, hendx, textycenter, prefs); + else + draw_horizontal_connector(hstartx, hendx, textycenter, prefs); + if ( has_children() && is_open() ) { + // Small vertical line down to children + draw_vertical_connector(hcenterx, textycenter, Y+H, prefs); + } + // Connectors for last child + if ( ! is_root() ) { + if ( lastchild ) { + draw_vertical_connector(hstartx, Y, textycenter, prefs); + } else { + draw_vertical_connector(hstartx, Y, Y+H, prefs); + } + } + } + // Draw collapse icon + if ( has_children() && prefs.showcollapse() ) { + // Draw icon image + if ( is_open() ) { + prefs.closeicon()->draw(icon_x,icon_y); + } else { + prefs.openicon()->draw(icon_x,icon_y); + } + } + // Background for this item + int cw1 = icon_w+prefs.connectorwidth()/2, cw2 = prefs.connectorwidth(); + int cwidth = cw1>cw2 ? cw1 : cw2; + int &bx = _label_xywh[0] = X+(icon_w/2-1+cwidth); + int &by = _label_xywh[1] = Y; + int &bw = _label_xywh[2] = W-(icon_w/2-1+cwidth); + int &bh = _label_xywh[3] = H; + // Draw bg only if different from tree's bg + if ( bg != tree->color() || is_selected() ) { + if ( is_selected() ) { + // Selected? Use selectbox() style + fl_draw_box(prefs.selectbox(), bx, by, bw, bh, bg); + } else { + // Not Selected? use plain filled rectangle + fl_color(bg); + fl_rectf(bx, by, bw, bh); + } + } + // Draw user icon (if any) + int useroff = (icon_w/2-1+cwidth); + if ( usericon() ) { + // Item has user icon? Use it + useroff += prefs.usericonmarginleft(); + icon_y = textycenter - (usericon()->h() >> 1); + usericon()->draw(X+useroff,icon_y); + useroff += usericon()->w(); + } else if ( prefs.usericon() ) { + // Prefs has user icon? Use it + useroff += prefs.usericonmarginleft(); + icon_y = textycenter - (prefs.usericon()->h() >> 1); + prefs.usericon()->draw(X+useroff,icon_y); + useroff += prefs.usericon()->w(); + } + useroff += prefs.labelmarginleft(); + // Draw label + if ( widget() ) { + // Widget? Draw it + int lx = X+useroff; + int ly = by; + int lw = widget()->w(); + int lh = bh; + if ( widget()->x() != lx || widget()->y() != ly || + widget()->w() != lw || widget()->h() != lh ) { + widget()->resize(lx, ly, lw, lh); // fltk will handle drawing this + } + } else { + // No label widget? Draw text label + if ( _label ) { + fl_color(fg); + fl_draw(_label, X+useroff, Y+H-fl_descent()-1); + } + } + Y += H; + } // end drawthis + // Draw children + if ( has_children() && is_open() ) { + int child_x = drawthis ? // offset children to right, + (hcenterx - (icon_w/2) + 1) : X; // unless didn't drawthis + int child_w = W - (child_x-X); + int child_y_start = Y; + for ( int t=0; tdraw(child_x, Y, child_w, tree, prefs, lastchild); + } + if ( has_children() && is_open() ) { + Y += prefs.openchild_marginbottom(); // offset below open child tree + } + if ( ! lastchild ) { + draw_vertical_connector(hstartx, child_y_start, Y, prefs); + } + } +} + +/// Was the event on the 'collapse' button? +/// +int Fl_Tree_Item::event_on_collapse_icon(const Fl_Tree_Prefs &prefs) const { + if ( _visible && _active && has_children() && prefs.showcollapse() ) { + return(event_inside(_collapse_xywh) ? 1 : 0); + } else { + return(0); + } +} + +/// Was event on the label()? +/// +int Fl_Tree_Item::event_on_label(const Fl_Tree_Prefs &prefs) const { + if ( _visible && _active ) { + return(event_inside(_label_xywh) ? 1 : 0); + } else { + return(0); + } +} + +/// Internal: Show the FLTK widget() for this item and all children. +/// Used by open() to re-show widgets that were hidden by a previous close() +/// +void Fl_Tree_Item::show_widgets() { + if ( _widget ) _widget->show(); + if ( is_open() ) { + for ( int t=0; t<_children.total(); t++ ) { + _children[t]->show_widgets(); + } + } +} + +/// Internal: Hide the FLTK widget() for this item and all children. +/// Used by close() to hide widgets. +/// +void Fl_Tree_Item::hide_widgets() { + if ( _widget ) _widget->hide(); + for ( int t=0; t<_children.total(); t++ ) { + _children[t]->hide_widgets(); + } +} + +/// Open this item and all its children. +void Fl_Tree_Item::open() { + _open = 1; + // Tell children to show() their widgets + for ( int t=0; t<_children.total(); t++ ) { + _children[t]->show_widgets(); + } +} + +/// Close this item and all its children. +void Fl_Tree_Item::close() { + _open = 0; + // Tell children to hide() their widgets + for ( int t=0; t<_children.total(); t++ ) { + _children[t]->hide_widgets(); + } +} + +/// Returns how many levels deep this item is in the hierarchy. +/// +/// For instance; root has a depth of zero, and its immediate children +/// would have a depth of 1, and so on. +/// +int Fl_Tree_Item::depth() const { + int count = 0; + const Fl_Tree_Item *item = parent(); + while ( item ) { + ++count; + item = item->parent(); + } + return(count); +} + +/// Return the next item in the tree. +/// +/// This method can be used to walk the tree forward. +/// For an example of how to use this method, see Fl_Tree::first(). +/// +/// \returns the next item in the tree, or 0 if there's no more items. +/// +Fl_Tree_Item *Fl_Tree_Item::next() { + Fl_Tree_Item *p, *c = this; + if ( c->has_children() ) { + return(c->child(0)); + } + while ( ( p = c->parent() ) != NULL ) { // loop upwards through parents + int t = p->find_child(c); // find our position in parent's children[] array + if ( ++t < p->children() ) // not last child? + return(p->child(t)); // return next child + c = p; // child becomes parent to move up generation + } // loop: moves up to next parent + return(0); // hit root? done +} + +/// Return the previous item in the tree. +/// +/// This method can be used to walk the tree backwards. +/// For an example of how to use this method, see Fl_Tree::last(). +/// +/// \returns the previous item in the tree, or 0 if there's no item above this one (hit the root). +/// +Fl_Tree_Item *Fl_Tree_Item::prev() { + Fl_Tree_Item *p=parent(); // start with parent + if ( ! p ) return(0); // hit root? done + int t = p->find_child(this); // find our position in parent's children[] array + if ( --t == -1 ) { // are we first child? + return(p); // return immediate parent + } + p = p->child(t); // take parent's previous child + while ( p->has_children() ) { // has children? + p = p->child(p->children()-1); // take last child + } + return(p); +} + +// +// End of "$Id: Fl_Tree_Item.cxx 7672 2010-07-10 09:44:45Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Tree_Item_Array.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Tree_Item_Array.cxx new file mode 100644 index 000000000..16d5dc547 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Tree_Item_Array.cxx @@ -0,0 +1,157 @@ +// +// "$Id: Fl_Tree_Item_Array.cxx 6956 2009-12-08 08:06:44Z greg.ercolano $" +// + +#include +#include +#include + +#include +#include + +////////////////////// +// Fl_Tree_Item_Array.cxx +////////////////////// +// +// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK +// Copyright (C) 2009 by Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +/// Constructor; creates an empty array. +/// +/// The optional 'chunksize' can be specified to optimize +/// memory allocation for potentially large arrays. Default chunksize is 10. +/// +Fl_Tree_Item_Array::Fl_Tree_Item_Array(int new_chunksize) { + _items = 0; + _total = 0; + _size = 0; + _chunksize = new_chunksize; +} + +/// Destructor. Calls each item's destructor, destroys internal _items array. +Fl_Tree_Item_Array::~Fl_Tree_Item_Array() { + clear(); +} + +/// Copy constructor. Makes new copy of array, with new instances of each item. +Fl_Tree_Item_Array::Fl_Tree_Item_Array(const Fl_Tree_Item_Array* o) { + _items = (Fl_Tree_Item**)malloc(o->_size * sizeof(Fl_Tree_Item*)); + _total = o->_total; + _size = o->_size; + _chunksize = o->_chunksize; + for ( int t=0; t_total; t++ ) { + _items[t] = new Fl_Tree_Item(o->_items[t]); + } +} + +/// Clear the entire array. +/// +/// Each item will be deleted (destructors will be called), +/// and the array will be cleared. total() will return 0. +/// +void Fl_Tree_Item_Array::clear() { + if ( _items ) { + for ( int t=0; t<_total; t++ ) { + delete _items[t]; + _items[t] = 0; + } + free((void*)_items); _items = 0; + } + _total = _size = 0; +} + +// Internal: Enlarge the items array. +// +// Adjusts size/items memory allocation as needed. +// Does NOT change total. +// +void Fl_Tree_Item_Array::enlarge(int count) { + int newtotal = _total + count; // new total + if ( newtotal >= _size ) { // more than we have allocated? + // Increase size of array + int newsize = _size + _chunksize; + Fl_Tree_Item **newitems = (Fl_Tree_Item**)malloc(newsize * sizeof(Fl_Tree_Item*)); + if ( _items ) { + // Copy old array -> new, delete old + memmove(newitems, _items, _size * sizeof(Fl_Tree_Item*)); + free((void*)_items); _items = 0; + } + // Adjust items/sizeitems + _items = newitems; + _size = newsize; + } +} + +/// Insert an item at index position \p pos. +/// +/// Handles enlarging array if needed, total increased by 1. +/// If \p pos == total(), an empty item is appended to the array. +/// +void Fl_Tree_Item_Array::insert(int pos, Fl_Tree_Item *new_item) { + enlarge(1); + // printf("*** POS=%d TOTAL-1=%d NITEMS=%d\n", pos, _total-1, (_total-pos)); + if ( pos <= (_total - 1) ) { // need to move memory around? + int nitems = _total - pos; + memmove(&_items[pos+1], &_items[pos], sizeof(Fl_Tree_Item*) * nitems); + } + _items[pos] = new_item; + _total++; +} + +/// Add an item* to the end of the array. +/// +/// Assumes the item was created with 'new', and will remain +/// allocated.. Fl_Tree_Item_Array will handle calling the +/// item's destructor when the array is cleared or the item remove()'ed. +/// +void Fl_Tree_Item_Array::add(Fl_Tree_Item *val) { + insert(_total, val); +} + +/// Remove the item at \param[in] index from the array. +/// +/// The item will be delete'd (if non-NULL), so its destructor will be called. +/// +void Fl_Tree_Item_Array::remove(int index) { + if ( _items[index] ) { // delete if non-zero + delete _items[index]; + } + _items[index] = 0; + for ( _total--; index<_total; index++ ) { + _items[index] = _items[index+1]; + } +} + +/// Remove the item from the array. +/// +/// \returns 0 if removed, or -1 if the item was not in the array. +/// +int Fl_Tree_Item_Array::remove(Fl_Tree_Item *item) { + for ( int t=0; t<_total; t++ ) { + if ( item == _items[t] ) { + remove(t); + return(0); + } + } + return(-1); +} + +// +// End of "$Id: Fl_Tree_Item_Array.cxx 6956 2009-12-08 08:06:44Z greg.ercolano $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Tree_Prefs.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Tree_Prefs.cxx new file mode 100644 index 000000000..f200c758f --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Tree_Prefs.cxx @@ -0,0 +1,170 @@ +// +// "$Id: Fl_Tree_Prefs.cxx 7672 2010-07-10 09:44:45Z matt $" +// + +#include +#include +#include +#include + +////////////////////// +// Fl_Tree_Prefs.cxx +////////////////////// +// +// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK +// Copyright (C) 2009 by Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +// INTERNAL: BUILT IN OPEN/STOW XPMS +// These can be replaced via prefs.openicon()/closeicon() +// +static const char *L_open_xpm[] = { +#ifdef __APPLE__ + "11 11 2 1", + ". c None", + "@ c #000000", + "...@.......", + "...@@......", + "...@@@.....", + "...@@@@....", + "...@@@@@...", + "...@@@@@@..", + "...@@@@@...", + "...@@@@....", + "...@@@.....", + "...@@......", + "...@......." +#else + "11 11 3 1", + ". c #fefefe", + "# c #444444", + "@ c #000000", + "###########", + "#.........#", + "#.........#", + "#....@....#", + "#....@....#", + "#..@@@@@..#", + "#....@....#", + "#....@....#", + "#.........#", + "#.........#", + "###########" +#endif +}; +static Fl_Pixmap L_openpixmap(L_open_xpm); + +static const char *L_close_xpm[] = { +#ifdef __APPLE__ + "11 11 2 1", + ". c None", + "@ c #000000", + "...........", + "...........", + "...........", + "...........", + "...........", + "@@@@@@@@@@@", + ".@@@@@@@@@.", + "..@@@@@@@..", + "...@@@@@...", + "....@@@....", + ".....@....." +#else + "11 11 3 1", + ". c #fefefe", + "# c #444444", + "@ c #000000", + "###########", + "#.........#", + "#.........#", + "#.........#", + "#.........#", + "#..@@@@@..#", + "#.........#", + "#.........#", + "#.........#", + "#.........#", + "###########" +#endif +}; +static Fl_Pixmap L_closepixmap(L_close_xpm); + +/// Sets the default icon to be used as the 'open' icon +/// when items are add()ed to the tree. +/// This overrides the built in default '[+]' icon. +/// +/// \param[in] val -- The new image, or zero to use the default [+] icon. +/// +void Fl_Tree_Prefs::openicon(Fl_Image *val) { + _openimage = val ? val : &L_openpixmap; +} + +/// Sets the icon to be used as the 'close' icon. +/// This overrides the built in default '[-]' icon. +/// +/// \param[in] val -- The new image, or zero to use the default [-] icon. +/// +void Fl_Tree_Prefs::closeicon(Fl_Image *val) { + _closeimage = val ? val : &L_closepixmap; +} + +/// Fl_Tree_Prefs constructor +Fl_Tree_Prefs::Fl_Tree_Prefs() { + _labelfont = FL_HELVETICA; + _labelsize = FL_NORMAL_SIZE; + _marginleft = 6; + _margintop = 3; + //_marginright = 3; + //_marginbottom = 3; + _openchild_marginbottom = 0; + _usericonmarginleft = 3; + _labelmarginleft = 3; + _linespacing = 0; + _fgcolor = FL_BLACK; + _bgcolor = FL_WHITE; + _selectcolor = FL_DARK_BLUE; + _inactivecolor = FL_GRAY; + _connectorcolor = Fl_Color(43); +#ifdef __APPLE__ + _connectorstyle = FL_TREE_CONNECTOR_NONE; +#else + _connectorstyle = FL_TREE_CONNECTOR_DOTTED; +#endif + _openimage = &L_openpixmap; + _closeimage = &L_closepixmap; + _userimage = 0; + _showcollapse = 1; + _showroot = 1; + _connectorwidth = 17; + _sortorder = FL_TREE_SORT_NONE; + _selectbox = FL_FLAT_BOX; + _selectmode = FL_TREE_SELECT_SINGLE; + // Let fltk's current 'scheme' affect defaults + if ( Fl::scheme() ) { + if ( strcmp(Fl::scheme(), "gtk+") == 0 ) { + _selectbox = _FL_GTK_THIN_UP_BOX; + } else if ( strcmp(Fl::scheme(), "plastic") == 0 ) { + _selectbox = _FL_PLASTIC_THIN_UP_BOX; + } + } +} + +// +// End of "$Id: Fl_Tree_Prefs.cxx 7672 2010-07-10 09:44:45Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Value_Input.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Value_Input.cxx index b8faa69db..a786204c1 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Value_Input.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Value_Input.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Value_Input.cxx 6664 2009-02-18 09:27:54Z AlbrechtS $" +// "$Id: Fl_Value_Input.cxx 7117 2010-02-20 21:14:47Z matt $" // // Value input widget for the Fast Light Tool Kit (FLTK). // @@ -100,8 +100,10 @@ int Fl_Value_Input::handle(int event) { if (value() != previous_value() || !Fl::event_is_click()) handle_release(); else { + Fl_Widget_Tracker wp(&input); input.handle(FL_PUSH); - input.handle(FL_RELEASE); + if (wp.exists()) + input.handle(FL_RELEASE); } return 1; case FL_FOCUS: @@ -124,7 +126,7 @@ Fl_Value_Input::Fl_Value_Input(int X, int Y, int W, int H, const char* l) : Fl_Valuator(X, Y, W, H, l), input(X, Y, W, H, 0) { soft_ = 0; if (input.parent()) // defeat automatic-add - ((Fl_Group*)input.parent())->remove(input); + input.parent()->remove(input); input.parent((Fl_Group *)this); // kludge! input.callback(input_cb, this); input.when(FL_WHEN_CHANGED); @@ -143,5 +145,5 @@ Fl_Value_Input::~Fl_Value_Input() { } // -// End of "$Id: Fl_Value_Input.cxx 6664 2009-02-18 09:27:54Z AlbrechtS $". +// End of "$Id: Fl_Value_Input.cxx 7117 2010-02-20 21:14:47Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Widget.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Widget.cxx index 97a4f5413..e05f0f503 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Widget.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Widget.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Widget.cxx 6716 2009-03-24 01:40:44Z fabien $" +// "$Id: Fl_Widget.cxx 7321 2010-03-23 17:37:51Z AlbrechtS $" // // Base widget class for the Fast Light Tool Kit (FLTK). // @@ -73,7 +73,34 @@ Fl_Widget *Fl::readqueue() { if (obj_tail >= QUEUE_SIZE) obj_tail = 0; return o; } - +/* + This static internal function removes all pending callbacks for a + specific widget from the default callback queue (Fl::readqueue()). + It is only called from Fl_Widget's destructor if the widget + doesn't have an own callback. + Note: There's no need to have this in the Fl:: namespace. +*/ +static void cleanup_readqueue(Fl_Widget *w) { + + if (obj_tail==obj_head) return; + + // Read the entire queue and copy over all valid entries. + // The new head will be determined after the last copied entry. + + int old_head = obj_head; // save newest entry + int entry = obj_tail; // oldest entry + obj_head = obj_tail; // new queue start + for (;;) { + Fl_Widget *o = obj_queue[entry++]; + if (entry >= QUEUE_SIZE) entry = 0; + if (o != w) { // valid entry + obj_queue[obj_head++] = o; + if (obj_head >= QUEUE_SIZE) obj_head = 0; + } // valid entry + if (entry == old_head) break; + } + return; +} //////////////////////////////////////////////////////////////// int Fl_Widget::handle(int) { @@ -94,6 +121,7 @@ Fl_Widget::Fl_Widget(int X, int Y, int W, int H, const char* L) { label_.font = FL_HELVETICA; label_.size = FL_NORMAL_SIZE; label_.color = FL_FOREGROUND_COLOR; + label_.align_ = FL_ALIGN_CENTER; tooltip_ = 0; callback_ = default_callback; user_data_ = 0; @@ -103,7 +131,6 @@ Fl_Widget::Fl_Widget(int X, int Y, int W, int H, const char* L) { box_ = FL_NO_BOX; color_ = FL_GRAY; color2_ = FL_GRAY; - align_ = FL_ALIGN_CENTER; when_ = FL_WHEN_RELEASE; parent_ = 0; @@ -150,6 +177,8 @@ Fl_Widget::~Fl_Widget() { #endif // DEBUG_DELETE parent_ = 0; // Don't throw focus to a parent widget. fl_throw_focus(this); + // remove stale entries from default callback queue (Fl::readqueue()) + if (callback_ == default_callback) cleanup_readqueue(this); } /** Draws a focus box for the widget at the given position and size */ @@ -303,13 +332,13 @@ Fl_Widget::copy_label(const char *a) { */ void Fl_Widget::do_callback(Fl_Widget* o,void* arg) { - Fl_Widget_Tracker wp(o); - callback_(o,arg); + Fl_Widget_Tracker wp(this); + callback_(o,arg); if (wp.deleted()) return; - if (callback_ != default_callback) + if (callback_ != default_callback) clear_changed(); } // -// End of "$Id: Fl_Widget.cxx 6716 2009-03-24 01:40:44Z fabien $". +// End of "$Id: Fl_Widget.cxx 7321 2010-03-23 17:37:51Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Window.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Window.cxx index 558a8d2e1..3f2786718 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Window.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Window.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Window.cxx 6905 2009-09-27 12:06:35Z matt $" +// "$Id: Fl_Window.cxx 7357 2010-03-29 14:10:54Z matt $" // // Window widget class for the Fast Light Tool Kit (FLTK). // @@ -31,6 +31,7 @@ // equivalent (but totally different) crap for MSWindows is in Fl_win32.cxx #include "config.h" #include +#include #include #include #include "flstring.h" @@ -110,7 +111,10 @@ void Fl_Window::draw() { draw_children(); #ifdef __APPLE_QUARTZ__ - if (!parent() && resizable() && (!size_range_set || minh!=maxh || minw!=maxw)) { + // on OS X, windows have no frame. To resize a window, we drag the lower right + // corner. This code draws a little ribbed triangle for dragging. + extern CGContextRef fl_gc; + if (fl_gc && !parent() && resizable() && (!size_range_set || minh!=maxh || minw!=maxw)) { int dx = Fl::box_dw(box())-Fl::box_dx(box()); int dy = Fl::box_dh(box())-Fl::box_dy(box()); if (dx<=0) dx = 1; @@ -151,9 +155,7 @@ void Fl_Window::copy_label(const char *a) { void Fl_Window::iconlabel(const char *iname) { - unsigned saveflags = flags(); label(label(), iname); - set_flag(saveflags); } // the Fl::atclose pointer is provided for back compatibility. You @@ -178,5 +180,5 @@ Fl_Window *Fl_Window::current() { // -// End of "$Id: Fl_Window.cxx 6905 2009-09-27 12:06:35Z matt $". +// End of "$Id: Fl_Window.cxx 7357 2010-03-29 14:10:54Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Window_iconize.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Window_iconize.cxx index 112f5512a..1caea9f97 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Window_iconize.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Window_iconize.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Window_iconize.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_Window_iconize.cxx 7351 2010-03-29 10:35:00Z matt $" // // Window minification code for the Fast Light Tool Kit (FLTK). // @@ -37,7 +37,7 @@ void Fl_Window::iconize() { #ifdef WIN32 ShowWindow(i->xid, SW_SHOWMINNOACTIVE); #elif defined(__APPLE__) - CollapseWindow( i->xid, true ); + MacCollapseWindow((Window)i->xid); #else XIconifyWindow(fl_display, i->xid, fl_screen); #endif @@ -45,5 +45,5 @@ void Fl_Window::iconize() { } // -// End of "$Id: Fl_Window_iconize.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_Window_iconize.cxx 7351 2010-03-29 10:35:00Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_add_idle.cxx b/plugins/zynaddsubfx/fltk/src/Fl_add_idle.cxx index 1d3d47d35..ac7caf355 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_add_idle.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_add_idle.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_add_idle.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_add_idle.cxx 7334 2010-03-25 14:37:46Z AlbrechtS $" // // Idle routine support for the Fast Light Tool Kit (FLTK). // @@ -66,7 +66,7 @@ static void call_idle() { FLTK will not recursively call the idle callback. */ -void Fl::add_idle(void (*cb)(void*), void* data) { +void Fl::add_idle(Fl_Idle_Handler cb, void* data) { idle_cb* p = freelist; if (p) freelist = p->next; else p = new idle_cb; @@ -86,7 +86,7 @@ void Fl::add_idle(void (*cb)(void*), void* data) { /** Returns true if the specified idle callback is currently installed. */ -int Fl::has_idle(void (*cb)(void*), void* data) { +int Fl::has_idle(Fl_Idle_Handler cb, void* data) { idle_cb* p = first; if (!p) return 0; for (;; p = p->next) { @@ -98,7 +98,7 @@ int Fl::has_idle(void (*cb)(void*), void* data) { /** Removes the specified idle callback, if it is installed. */ -void Fl::remove_idle(void (*cb)(void*), void* data) { +void Fl::remove_idle(Fl_Idle_Handler cb, void* data) { idle_cb* p = first; if (!p) return; idle_cb* l = last; @@ -119,5 +119,5 @@ void Fl::remove_idle(void (*cb)(void*), void* data) { } // -// End of "$Id: Fl_add_idle.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_add_idle.cxx 7334 2010-03-25 14:37:46Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_arg.cxx b/plugins/zynaddsubfx/fltk/src/Fl_arg.cxx index b2ed5b36c..1a9c36ecc 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_arg.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_arg.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_arg.cxx 6813 2009-07-01 07:32:14Z AlbrechtS $" +// "$Id: Fl_arg.cxx 7334 2010-03-25 14:37:46Z AlbrechtS $" // // Optional argument initialization code for the Fast Light Tool Kit (FLTK). // @@ -88,13 +88,6 @@ int Fl::arg(int argc, char **argv, int &i) { if (s[0] != '-' || s[1] == '-' || !s[1]) {return_i = 1; return 0;} s++; // point after the dash -#ifdef __APPLE__ - if (!strncmp(s, "psn", 3)) { - // Skip process serial number... - i++; - } - else -#endif // __APPLE__ if (fl_match(s, "iconic")) { fl_show_iconic = 1; i++; @@ -284,7 +277,7 @@ int Fl::arg(int argc, char **argv, int &i) { Fl::help pointer. */ -int Fl::args(int argc, char** argv, int& i, int (*cb)(int,char**,int&)) { +int Fl::args(int argc, char** argv, int& i, Fl_Args_Handler cb) { arg_called = 1; i = 1; // skip argv[0] while (i < argc) { @@ -538,5 +531,5 @@ int XParseGeometry(const char* string, int* x, int* y, #endif // ifdef WIN32 // -// End of "$Id: Fl_arg.cxx 6813 2009-07-01 07:32:14Z AlbrechtS $". +// End of "$Id: Fl_arg.cxx 7334 2010-03-25 14:37:46Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_compose.cxx b/plugins/zynaddsubfx/fltk/src/Fl_compose.cxx index e0f4eb9ca..dce2d11b7 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_compose.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_compose.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_compose.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_compose.cxx 7351 2010-03-29 10:35:00Z matt $" // // Character compose processing for the Fast Light Tool Kit (FLTK). // @@ -26,6 +26,7 @@ // #include +#include // // MRS: Uncomment the following define to get the original (pre-1.1.2) @@ -39,14 +40,9 @@ #ifdef __APPLE__ static const char* const compose_pairs = -":A*A,C'E~N:O:U'a`a^a:a~a*a,c'e`e" -"^e:e'i`i^i:i~n'o`o^o:o~o'u`u^u:u" -"+ o /c# SS* P|ssrOcOTM' : !=AE/O" -"oo+-<=>=Y=mudtSgPipiS a dgOmaeo/" -"? ! !!v-f ~~Dt<<>>.. `A~A~OOEoe" -"- --''``\"'\"`:-^V:y:Y//E=< > fifl" -"++..,,_\"%%^A^E'A:E`E'I^I:I`I'O^O" -"mc`O'U^U`U||^ ~^_ u . * , ~-; v "; +" ! % # $ y=| & : c a <<~ - r _ * +-2 3 ' u p . , 1 o >>141234? "//00A0 ... +"`A'A^A~A:A*AAE,C`E'E^E:E`I'I^I:I-D~N`O'O^O~O:Ox O/`U'U^U:U'YTHss" //00C0 ... +"`a'a^a~a:a*aae,c`e'e^e:e`i'i^i:i-d~n`o'o^o~o:o-:o/`u'u^u:u'yth:y";//00E0 ... #else diff --git a/plugins/zynaddsubfx/fltk/src/Fl_get_key_mac.cxx b/plugins/zynaddsubfx/fltk/src/Fl_get_key_mac.cxx index 12f19dc54..17617ad69 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_get_key_mac.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_get_key_mac.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_get_key_mac.cxx 6755 2009-04-12 13:48:03Z matt $" +// "$Id: Fl_get_key_mac.cxx 7615 2010-05-26 21:25:11Z manolo $" // // MacOS keyboard state routines for the Fast Light Tool Kit (FLTK). // @@ -87,6 +87,13 @@ int Fl::event_key(int k) { //: returns true, if that key is pressed right now int Fl::get_key(int k) { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + if(CGEventSourceKeyState != NULL) { + return (int)CGEventSourceKeyState(kCGEventSourceStateCombinedSessionState, fltk2mac(k) ); + } + else +#endif + { KeyMap foo; GetKeys(foo); #ifdef MAC_TEST_FOR_KEYCODES @@ -103,8 +110,9 @@ int Fl::get_key(int k) { } int i = fltk2mac(k); return (b[i>>3]>>(i&7))&1; + } } // -// End of "$Id: Fl_get_key_mac.cxx 6755 2009-04-12 13:48:03Z matt $". +// End of "$Id: Fl_get_key_mac.cxx 7615 2010-05-26 21:25:11Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_get_system_colors.cxx b/plugins/zynaddsubfx/fltk/src/Fl_get_system_colors.cxx index 938f82936..176fece6c 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_get_system_colors.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_get_system_colors.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_get_system_colors.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_get_system_colors.cxx 7352 2010-03-29 10:47:11Z matt $" // // System color support for the Fast Light Tool Kit (FLTK). // @@ -37,10 +37,6 @@ #include #include "tile.xpm" -#if defined(__APPLE__) && defined(__MWERKS__) -extern "C" int putenv(const char*); -#endif // __APPLE__ && __MWERKS__ - #if defined(WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__) // Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs // on Windows, which is supposed to be POSIX compliant... @@ -426,5 +422,5 @@ int Fl::reload_scheme() { // -// End of "$Id: Fl_get_system_colors.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_get_system_colors.cxx 7352 2010-03-29 10:47:11Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_grab.cxx b/plugins/zynaddsubfx/fltk/src/Fl_grab.cxx index 706cb3a64..8a609675d 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_grab.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_grab.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_grab.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_grab.cxx 7351 2010-03-29 10:35:00Z matt $" // // Grab/release code for the Fast Light Tool Kit (FLTK). // @@ -47,8 +47,8 @@ extern HWND fl_capture; #endif #ifdef __APPLE__ -// MacOS Carbon does not seem to have a mechanism to grab the mouse pointer -extern WindowRef fl_capture; +extern void MACsetkeywindow(void *nsw); +extern void *fl_capture; #endif void Fl::grab(Fl_Window* win) { @@ -58,8 +58,8 @@ void Fl::grab(Fl_Window* win) { SetActiveWindow(fl_capture = fl_xid(first_window())); SetCapture(fl_capture); #elif defined(__APPLE__) - fl_capture = fl_xid( first_window() ); - SetUserFocusWindow( fl_capture ); + fl_capture = Fl_X::i(first_window())->xid; + MACsetkeywindow(fl_capture); #else XGrabPointer(fl_display, fl_xid(first_window()), @@ -87,7 +87,6 @@ void Fl::grab(Fl_Window* win) { ReleaseCapture(); #elif defined(__APPLE__) fl_capture = 0; - SetUserFocusWindow( (WindowRef)kUserFocusAuto ); #else XUngrabKeyboard(fl_display, fl_event_time); XUngrabPointer(fl_display, fl_event_time); @@ -102,5 +101,5 @@ void Fl::grab(Fl_Window* win) { } // -// End of "$Id: Fl_grab.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_grab.cxx 7351 2010-03-29 10:35:00Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_mac.cxx b/plugins/zynaddsubfx/fltk/src/Fl_mac.cxx index 28541652c..82d9f6a65 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_mac.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_mac.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_mac.cxx 6905 2009-09-27 12:06:35Z matt $" +// "$Id: Fl_mac.cxx 7351 2010-03-29 10:35:00Z matt $" // // MacOS specific code for the Fast Light Tool Kit (FLTK). // @@ -44,7 +44,7 @@ // Quartz calls in the near future. // FIXME moving away from Carbon, I am replacing the Scrap manager calls with Pasteboard -// calls that support utf8 encoding. As soon as these unction haven proven working +// calls that support utf8 encoding. As soon as these function haven proven working // the Scrap manager calls should be removed #define USE_PASTEBOARD 1 @@ -2442,10 +2442,8 @@ void Fl_Window::resize(int X,int Y,int W,int H) { */ void Fl_Window::make_current() { -#ifdef __APPLE_QUARTZ__ OSStatus err; Fl_X::q_release_context(); -#endif if ( !fl_window_region ) fl_window_region = NewRgn(); fl_window = i->xid; @@ -2479,29 +2477,26 @@ void Fl_Window::make_current() DisposeRgn( r ); } -#ifdef __APPLE_QUARTZ__ err = QDBeginCGContext(GetWindowPort(i->xid), &i->gc); if (err!=noErr) fprintf(stderr, "Error %d in QDBeginCGContext\n", (int)err); fl_gc = i->gc; CGContextSaveGState(fl_gc); Fl_X::q_fill_context(); -#if defined(USE_CAIRO) && defined (__APPLE_QUARTZ__) +#if defined(USE_CAIRO) if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this); // capture gc changes automatically to update the cairo context adequately #endif -#endif fl_clip_region( 0 ); SetPortClipRegion( GetWindowPort(i->xid), fl_window_region ); -#if defined(__APPLE_QUARTZ__) && defined(USE_CAIRO) +#if defined(USE_CAIRO) // update the cairo_t context if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this); #endif } // helper function to manage the current CGContext fl_gc -#ifdef __APPLE_QUARTZ__ extern Fl_Color fl_color_; extern class Fl_Font_Descriptor *fl_fontsize; extern void fl_font(class Fl_Font_Descriptor*); @@ -2545,7 +2540,7 @@ void Fl_X::q_release_context(Fl_X *x) { fprintf(stderr, "Error %d in QDEndCGContext\n", (int)err); } fl_gc = 0; -#if defined(USE_CAIRO) && defined (__APPLE_QUARTZ__) +#if defined(USE_CAIRO) if (Fl::cairo_autolink_context()) Fl::cairo_make_current((Fl_Window*) 0); // capture gc changes automatically to update the cairo context adequately #endif } @@ -2569,8 +2564,6 @@ void Fl_X::q_end_image() { CGContextRestoreGState(fl_gc); } -#endif - //////////////////////////////////////////////////////////////// // Copy & Paste fltk implementation. //////////////////////////////////////////////////////////////// @@ -2873,5 +2866,5 @@ void MacUnmapWindow(Fl_Window *w, WindowPtr p) { #endif // FL_DOXYGEN // -// End of "$Id: Fl_mac.cxx 6905 2009-09-27 12:06:35Z matt $". +// End of "$Id: Fl_mac.cxx 7351 2010-03-29 10:35:00Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_win32.cxx b/plugins/zynaddsubfx/fltk/src/Fl_win32.cxx index a97a082da..5dfdb7aae 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_win32.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_win32.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_win32.cxx 6905 2009-09-27 12:06:35Z matt $" +// "$Id: Fl_win32.cxx 7659 2010-07-01 13:21:32Z manolo $" // // WIN32-specific code for the Fast Light Tool Kit (FLTK). // @@ -95,17 +95,22 @@ for async mode proper operation, not mentioning the side effects... */ +static Fl_GDI_Graphics_Driver fl_gdi_driver; +static Fl_Display_Device fl_gdi_display(&fl_gdi_driver); +FL_EXPORT Fl_Display_Device *fl_display_device = (Fl_Display_Device*)&fl_gdi_display; // does not change +FL_EXPORT Fl_Graphics_Driver *fl_graphics_driver = (Fl_Graphics_Driver*)&fl_gdi_driver; // the current target driver of graphics operations +FL_EXPORT Fl_Surface_Device *fl_surface = (Fl_Surface_Device*)fl_display_device; // the current target surface of graphics operations + // dynamic wsock dll handling api: #if defined(__CYGWIN__) && !defined(SOCKET) # define SOCKET int #endif typedef int (WINAPI* fl_wsk_select_f)(int, fd_set*, fd_set*, fd_set*, const struct timeval*); typedef int (WINAPI* fl_wsk_fd_is_set_f)(SOCKET, fd_set *); -typedef int (WINAPI* fl_wsk_async_select_f)(SOCKET,HWND,u_int,long); + static HMODULE s_wsock_mod = 0; static fl_wsk_select_f s_wsock_select=0; static fl_wsk_fd_is_set_f fl_wsk_fd_is_set=0; -static fl_wsk_async_select_f fl_wsk_async_select=0; static HMODULE get_wsock_mod() { if (!s_wsock_mod) { @@ -114,7 +119,6 @@ static HMODULE get_wsock_mod() { Fl::fatal("FLTK Lib Error: %s file not found! Please check your winsock dll accessibility.\n",WSCK_DLL_NAME); s_wsock_select = (fl_wsk_select_f) GetProcAddress(s_wsock_mod, "select"); fl_wsk_fd_is_set = (fl_wsk_fd_is_set_f) GetProcAddress(s_wsock_mod, "__WSAFDIsSet"); - fl_wsk_async_select = (fl_wsk_async_select_f) GetProcAddress(s_wsock_mod, "WSAAsyncSelect"); } return s_wsock_mod; } @@ -229,14 +233,18 @@ static Fl_Window *track_mouse_win=0; // current TrackMouseEvent() window // // Microsoft provides the Berkeley select() call and an asynchronous // select function that sends a WIN32 message when the select condition -// exists... +// exists. However, we don't try to use the asynchronous WSAAsyncSelect() +// any more for good reasons (see above). +// +// A.S. Dec 2009: We got reports that current winsock2.h files define +// POLLIN, POLLOUT, and POLLERR with conflicting values WRT what we +// used before (STR #2301). Therefore we must not use these values +// for our internal purposes, but use FL_READ, FL_WRITE, and +// FL_EXCEPT, as defined for use in Fl::add_fd(). +// static int maxfd = 0; static fd_set fdsets[3]; -# define POLLIN 1 -# define POLLOUT 4 -# define POLLERR 8 - #if !defined(__GNUC__) || __GNUC__ >= 3 extern IDropTarget *flIDropTarget; #endif // !__GNUC__ || __GNUC__ >= 3 @@ -292,14 +300,14 @@ void Fl::add_fd(int n, int events, void (*cb)(int, void*), void *v) { fd[i].cb = cb; fd[i].arg = v; - if (events & POLLIN) FD_SET((unsigned)n, &fdsets[0]); - if (events & POLLOUT) FD_SET((unsigned)n, &fdsets[1]); - if (events & POLLERR) FD_SET((unsigned)n, &fdsets[2]); + if (events & FL_READ) FD_SET((unsigned)n, &fdsets[0]); + if (events & FL_WRITE) FD_SET((unsigned)n, &fdsets[1]); + if (events & FL_EXCEPT) FD_SET((unsigned)n, &fdsets[2]); if (n > maxfd) maxfd = n; } void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) { - Fl::add_fd(fd, POLLIN, cb, v); + Fl::add_fd(fd, FL_READ, cb, v); } void Fl::remove_fd(int n, int events) { @@ -318,9 +326,9 @@ void Fl::remove_fd(int n, int events) { } nfds = j; - if (events & POLLIN) FD_CLR(unsigned(n), &fdsets[0]); - if (events & POLLOUT) FD_CLR(unsigned(n), &fdsets[1]); - if (events & POLLERR) FD_CLR(unsigned(n), &fdsets[2]); + if (events & FL_READ) FD_CLR(unsigned(n), &fdsets[0]); + if (events & FL_WRITE) FD_CLR(unsigned(n), &fdsets[1]); + if (events & FL_EXCEPT) FD_CLR(unsigned(n), &fdsets[2]); } void Fl::remove_fd(int n) { @@ -374,9 +382,9 @@ int fl_wait(double time_to_wait) { for (int i = 0; i < nfds; i ++) { SOCKET f = fd[i].fd; short revents = 0; - if (fl_wsk_fd_is_set(f, &fdt[0])) revents |= POLLIN; - if (fl_wsk_fd_is_set(f, &fdt[1])) revents |= POLLOUT; - if (fl_wsk_fd_is_set(f, &fdt[2])) revents |= POLLERR; + if (fl_wsk_fd_is_set(f, &fdt[0])) revents |= FL_READ; + if (fl_wsk_fd_is_set(f, &fdt[1])) revents |= FL_WRITE; + if (fl_wsk_fd_is_set(f, &fdt[2])) revents |= FL_EXCEPT; if (fd[i].events & revents) fd[i].cb(f, fd[i].arg); } time_to_wait = 0.0; // just peek for any messages @@ -1292,7 +1300,7 @@ void Fl_Window::resize(int X,int Y,int W,int H) { int resize_from_program = (this != resize_bug_fix); if (!resize_from_program) resize_bug_fix = 0; if (X != x() || Y != y()) { - set_flag(FORCE_POSITION); + force_position(1); } else { if (!is_a_resize) return; flags |= SWP_NOMOVE; @@ -1474,7 +1482,7 @@ Fl_X* Fl_X::make(Fl_Window* w) { wp += 2*bx; hp += 2*by+bt; } - if (!(w->flags() & Fl_Widget::FORCE_POSITION)) { + if (!w->force_position()) { xp = yp = CW_USEDEFAULT; } else { if (!Fl::grab()) { @@ -1775,6 +1783,10 @@ void Fl_Window::show() { if (!fl_capture) BringWindowToTop(i->xid); //ShowWindow(i->xid,fl_capture?SW_SHOWNOACTIVATE:SW_RESTORE); } +#ifdef USE_PRINT_BUTTON +void preparePrintFront(void); +preparePrintFront(); +#endif } Fl_Window *Fl_Window::current_; @@ -1913,8 +1925,69 @@ void fl_cleanup_dc_list(void) { // clean up the list t = win_DC_list; } while(t); } + +Fl_Region XRectangleRegion(int x, int y, int w, int h) { + if (Fl_Surface_Device::surface()->type() == Fl_Display_Device::device_type) return CreateRectRgn(x,y,x+w,y+h); + // because rotation may apply, the rectangle becomes a polygon in device coords + POINT pt[4] = { {x, y}, {x + w, y}, {x + w, y + h}, {x, y + h} }; + LPtoDP(fl_gc, pt, 4); + return CreatePolygonRgn(pt, 4, ALTERNATE); +} + +#ifdef USE_PRINT_BUTTON +// to test the Fl_Printer class creating a "Print front window" button in a separate window +// contains also preparePrintFront call above +#include +#include +void printFront(Fl_Widget *o, void *data) +{ + Fl_Printer printer; + o->window()->hide(); + Fl_Window *win = Fl::first_window(); + if(!win) return; + int w, h; + if( printer.start_job(1) ) { o->window()->show(); return; } + if( printer.start_page() ) { o->window()->show(); return; } + printer.printable_rect(&w,&h); + // scale the printer device so that the window fits on the page + float scale = 1; + if (win->w() > w || win->h() > h) { + scale = (float)w/win->w(); + if ((float)h/win->h() < scale) scale = (float)h/win->h(); + printer.scale(scale, scale); + } +// #define ROTATE 20.0 +#ifdef ROTATE + printer.scale(scale * 0.8, scale * 0.8); + printer.printable_rect(&w, &h); + printer.origin(w/2, h/2 ); + printer.rotate(ROTATE); + printer.print_widget( win, - win->w()/2, - win->h()/2 ); + //printer.print_window_part( win, 0,0, win->w(), win->h(), - win->w()/2, - win->h()/2 ); +#else + printer.print_widget( win ); + //printer.print_window_part( win, 0,0, win->w(), win->h() ); +#endif + printer.end_page(); + printer.end_job(); + o->window()->show(); +} + +void preparePrintFront(void) +{ + static BOOL first=TRUE; + if(!first) return; + first=FALSE; + static Fl_Window w(0,0,120,30); + static Fl_Button b(0,0,w.w(),w.h(), "Print front window"); + b.callback(printFront); + w.end(); + w.show(); +} +#endif // USE_PRINT_BUTTON + #endif // FL_DOXYGEN // -// End of "$Id: Fl_win32.cxx 6905 2009-09-27 12:06:35Z matt $". +// End of "$Id: Fl_win32.cxx 7659 2010-07-01 13:21:32Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_x.cxx b/plugins/zynaddsubfx/fltk/src/Fl_x.cxx index 468333831..4e9cebc5e 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_x.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_x.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_x.cxx 6905 2009-09-27 12:06:35Z matt $" +// "$Id: Fl_x.cxx 7659 2010-07-01 13:21:32Z manolo $" // // X specific code for the Fast Light Tool Kit (FLTK). // @@ -51,6 +51,12 @@ # include # include +static Fl_Xlib_Graphics_Driver fl_xlib_driver; +static Fl_Display_Device fl_xlib_display(&fl_xlib_driver); +FL_EXPORT Fl_Display_Device *fl_display_device = (Fl_Display_Device*)&fl_xlib_display; // does not change +FL_EXPORT Fl_Graphics_Driver *fl_graphics_driver = (Fl_Graphics_Driver*)&fl_xlib_driver; // the current target device of graphics operations +FL_EXPORT Fl_Surface_Device *fl_surface = (Fl_Surface_Device*)fl_display_device; // the current target surface of graphics operations + //////////////////////////////////////////////////////////////// // interface to poll/select call: @@ -132,7 +138,9 @@ void Fl::add_fd(int n, void (*cb)(int, void*), void* v) { void Fl::remove_fd(int n, int events) { int i,j; +# if !USE_POLL maxfd = -1; // recalculate maxfd on the fly +# endif for (i=j=0; i maxfd) maxfd = fd[i].fd; +# endif // move it down in the array if necessary: if (jtype == KeyPress && - event->xkey.keycode == ((XKeyEvent*)previous)->keycode && - event->xkey.time == ((XKeyEvent*)previous)->time; - } -} - //////////////////////////////////////////////////////////////// static char unknown[] = ""; @@ -1173,11 +1172,35 @@ int fl_handle(const XEvent& thisevent) // down, probably due to some back compatibility problem. Fortunately // we can detect this because the repeating KeyPress event is in // the queue, get it and execute it instead: - XEvent temp; - if (XCheckIfEvent(fl_display,&temp,fake_keyup_test,(char*)(&xevent))){ - xevent = temp; - goto KEYPRESS; + + // Bool XkbSetDetectableAutorepeat ( display, detectable, supported_rtrn ) + // Display * display ; + // Bool detectable ; + // Bool * supported_rtrn ; + // ...would be the easy way to corrct this isuue. Unfortunatly, this call is also + // broken on many Unix distros including Ubuntu and Solaris (as of Dec 2009) + + // Bogus KeyUp events are generated by repeated KeyDown events. One + // neccessary condition is an identical key event pending right after + // the bogus KeyUp. + // The new code introduced Dec 2009 differs in that it only check the very + // next event in the queue, not the entire queue of events. + // This function wrongly detects a repeat key if a software keyboard + // sends a burst of events containing two consecutive equal keys. However, + // in every non-gaming situation, this is no problem because both KeyPress + // events will cause the expected behavior. + XEvent peekevent; + if (XPending(fl_display)) { + XPeekEvent(fl_display, &peekevent); + if ( (peekevent.type == KeyPress) // must be a KeyPress event + && (peekevent.xkey.keycode == xevent.xkey.keycode) // must be the same key + && (peekevent.xkey.time == xevent.xkey.time) // must be sent at the exact same time + ) { + XNextEvent(fl_display, &xevent); + goto KEYPRESS; + } } + event = FL_KEYUP; fl_key_vector[keycode/8] &= ~(1 << (keycode%8)); // keyup events just get the unshifted keysym: @@ -1567,6 +1590,13 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap) XFree(hints); } + // set the window type for menu and tooltip windows to avoid animations (compiz) + if (win->menu_window() || win->tooltip_window()) { + Atom net_wm_type = XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE", False); + Atom net_wm_type_kind = XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE_MENU", False); + XChangeProperty(fl_display, xp->xid, net_wm_type, XA_ATOM, 32, PropModeReplace, (unsigned char*)&net_wm_type_kind, 1); + } + XMapWindow(fl_display, xp->xid); if (showit) { win->set_visible(); @@ -1716,6 +1746,10 @@ void Fl_Window::show() { } else { XMapRaised(fl_display, i->xid); } +#ifdef USE_PRINT_BUTTON +void preparePrintFront(void); +preparePrintFront(); +#endif } Window fl_window; @@ -1738,8 +1772,62 @@ void Fl_Window::make_current() { } +#ifdef USE_PRINT_BUTTON +// to test the Fl_Printer class creating a "Print front window" button in a separate window +// contains also preparePrintFront call above +#include +#include +void printFront(Fl_Widget *o, void *data) +{ + Fl_Printer printer; + o->window()->hide(); + Fl_Window *win = Fl::first_window(); + if(!win) return; + int w, h; + if( printer.start_job(1) ) { o->window()->show(); return; } + if( printer.start_page() ) { o->window()->show(); return; } + printer.printable_rect(&w,&h); + // scale the printer device so that the window fits on the page + float scale = 1; + if (win->w() > w || win->h() > h) { + scale = (float)w/win->w(); + if ((float)h/win->h() < scale) scale = (float)h/win->h(); + printer.scale(scale, scale); + } + +// #define ROTATE 20.0 +#ifdef ROTATE + printer.scale(scale * 0.8, scale * 0.8); + printer.printable_rect(&w, &h); + printer.origin(w/2, h/2 ); + printer.rotate(ROTATE); + printer.print_widget( win, - win->w()/2, - win->h()/2 ); + //printer.print_window_part( win, 0,0, win->w(), win->h(), - win->w()/2, - win->h()/2 ); +#else + printer.print_widget( win ); + //printer.print_window_part( win, 0,0,win->w(), win->h() ); +#endif + + printer.end_page(); + printer.end_job(); + o->window()->show(); +} + +void preparePrintFront(void) +{ + static int first=1; + if(!first) return; + first=0; + static Fl_Window w(0,0,150,30); + static Fl_Button b(0,0,w.w(),w.h(), "Print front window"); + b.callback(printFront); + w.end(); + w.show(); +} +#endif // USE_PRINT_BUTTON + #endif // -// End of "$Id: Fl_x.cxx 6905 2009-09-27 12:06:35Z matt $". +// End of "$Id: Fl_x.cxx 7659 2010-07-01 13:21:32Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/aimm.h b/plugins/zynaddsubfx/fltk/src/aimm.h index 2acd5d96f..64ed66fa5 100644 --- a/plugins/zynaddsubfx/fltk/src/aimm.h +++ b/plugins/zynaddsubfx/fltk/src/aimm.h @@ -1,3 +1,6 @@ +// +// "$Id: aimm.h 6943 2009-11-18 12:43:21Z AlbrechtS $" +// // Standard dialog header file for the UTF-8 Fast Light Tool Kit (FLTK-UTF8). // // Copyright 2009 by Bill Spitzak and others. @@ -423,6 +426,6 @@ extern "C" __declspec(dllimport) long __stdcall CoCreateInstance(const GUID & rc #endif -/* - * End of "$Id$". - */ +// +// End of "$Id: aimm.h 6943 2009-11-18 12:43:21Z AlbrechtS $". +// diff --git a/plugins/zynaddsubfx/fltk/src/filename_absolute.cxx b/plugins/zynaddsubfx/fltk/src/filename_absolute.cxx index 3423f1e10..35a5fc7a0 100644 --- a/plugins/zynaddsubfx/fltk/src/filename_absolute.cxx +++ b/plugins/zynaddsubfx/fltk/src/filename_absolute.cxx @@ -1,5 +1,5 @@ // -// "$Id: filename_absolute.cxx 6691 2009-03-15 21:16:34Z AlbrechtS $" +// "$Id: filename_absolute.cxx 6986 2010-01-01 18:30:49Z greg.ercolano $" // // Filename expansion routines for the Fast Light Tool Kit (FLTK). // @@ -48,12 +48,19 @@ inline int isdirsep(char c) {return c=='/' || c=='\\';} #define isdirsep(c) ((c)=='/') #endif -/** - * Makes a filename absolute from a relative filename. - * \param[out] to resulting absolute filename - * \param[in] tolen size of the absolute filename buffer - * \param[in] from relative filename - * \return 0 if no change, non zero otherwise +/** Makes a filename absolute from a relative filename. + \code + #include + [..] + chdir("/var/tmp"); + fl_filename_absolute(out, sizeof(out), "foo.txt"); // out="/var/tmp/foo.txt" + fl_filename_absolute(out, sizeof(out), "./foo.txt"); // out="/var/tmp/foo.txt" + fl_filename_absolute(out, sizeof(out), "../log/messages"); // out="/var/log/messages" + \endcode + \param[out] to resulting absolute filename + \param[in] tolen size of the absolute filename buffer + \param[in] from relative filename + \return 0 if no change, non zero otherwise */ int fl_filename_absolute(char *to, int tolen, const char *from) { if (isdirsep(*from) || *from == '|' @@ -108,12 +115,23 @@ int fl_filename_absolute(char *to, int tolen, const char *from) { return 1; } -/** - * Makes a filename relative to the current working directory. - * \param[out] to resulting relative filename - * \param[in] tolen size of the relative filename buffer - * \param[in] from absolute filename - * \return 0 if no change, non zero otherwise +/** Makes a filename relative to the current working directory. + \code + #include + [..] + chdir("/var/tmp/somedir"); // set cwd to /var/tmp/somedir + [..] + char out[1024]; + fl_filename_relative(out, sizeof(out), "/var/tmp/somedir/foo.txt"); // out="foo.txt", return=1 + fl_filename_relative(out, sizeof(out), "/var/tmp/foo.txt"); // out="../foo.txt", return=1 + fl_filename_relative(out, sizeof(out), "foo.txt"); // out="foo.txt", return=0 (no change) + fl_filename_relative(out, sizeof(out), "./foo.txt"); // out="./foo.txt", return=0 (no change) + fl_filename_relative(out, sizeof(out), "../foo.txt"); // out="../foo.txt", return=0 (no change) + \endcode + \param[out] to resulting relative filename + \param[in] tolen size of the relative filename buffer + \param[in] from absolute filename + \return 0 if no change, non zero otherwise */ int // O - 0 if no change, 1 if changed fl_filename_relative(char *to, // O - Relative filename @@ -214,5 +232,5 @@ fl_filename_relative(char *to, // O - Relative filename // -// End of "$Id: filename_absolute.cxx 6691 2009-03-15 21:16:34Z AlbrechtS $". +// End of "$Id: filename_absolute.cxx 6986 2010-01-01 18:30:49Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/src/filename_expand.cxx b/plugins/zynaddsubfx/fltk/src/filename_expand.cxx index 50b6ebbfe..7fc5939c9 100644 --- a/plugins/zynaddsubfx/fltk/src/filename_expand.cxx +++ b/plugins/zynaddsubfx/fltk/src/filename_expand.cxx @@ -1,5 +1,5 @@ // -// "$Id: filename_expand.cxx 6641 2009-01-20 11:10:29Z fabien $" +// "$Id: filename_expand.cxx 6986 2010-01-01 18:30:49Z greg.ercolano $" // // Filename expansion routines for the Fast Light Tool Kit (FLTK). // @@ -47,12 +47,27 @@ static inline int isdirsep(char c) {return c=='/' || c=='\\';} #define isdirsep(c) ((c)=='/') #endif -/** - * Expands a filename coontaining shell variables. - * \param[out] to resulting expanded filename - * \param[in] tolen size of the expanded filename buffer - * \param[in] from filename containing shell variables - * \return 0 if no change, non zero otherwise +/** Expands a filename containing shell variables and tilde (~). + Currently handles these variants: + \code + "~username" // if 'username' does not exist, result will be unchanged + "~/file" + "$VARNAME" // does NOT handle ${VARNAME} + \endcode + + \b Examples: + \code + #include + [..] + putenv("TMPDIR=/var/tmp"); + fl_filename_expand(out, sizeof(out), "~fred/.cshrc"); // out="/usr/fred/.cshrc" + fl_filename_expand(out, sizeof(out), "~/.cshrc"); // out="/usr//.cshrc" + fl_filename_expand(out, sizeof(out), "$TMPDIR/foo.txt"); // out="/var/tmp/foo.txt" + \endcode + \param[out] to resulting expanded filename + \param[in] tolen size of the expanded filename buffer + \param[in] from filename containing shell variables + \return 0 if no change, non zero otherwise */ int fl_filename_expand(char *to,int tolen, const char *from) { @@ -115,5 +130,5 @@ int fl_filename_expand(char *to,int tolen, const char *from) { // -// End of "$Id: filename_expand.cxx 6641 2009-01-20 11:10:29Z fabien $". +// End of "$Id: filename_expand.cxx 6986 2010-01-01 18:30:49Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/src/filename_ext.cxx b/plugins/zynaddsubfx/fltk/src/filename_ext.cxx index d583d8127..174fe5266 100644 --- a/plugins/zynaddsubfx/fltk/src/filename_ext.cxx +++ b/plugins/zynaddsubfx/fltk/src/filename_ext.cxx @@ -1,5 +1,5 @@ // -// "$Id: filename_ext.cxx 6641 2009-01-20 11:10:29Z fabien $" +// "$Id: filename_ext.cxx 6986 2010-01-01 18:30:49Z greg.ercolano $" // // Filename extension routines for the Fast Light Tool Kit (FLTK). // @@ -29,8 +29,14 @@ #include -/** - Gets the extensions of a filename +/** Gets the extensions of a filename. + \code + #include + [..] + const char *out; + out = fl_filename_ext("/some/path/foo.txt"); // result: ".txt" + out = fl_filename_ext("/some/path/foo"); // result: NULL + \endcode \param[in] buf the filename to be parsed \return a pointer to the extension (including '.') if any or NULL otherwise */ @@ -48,5 +54,5 @@ const char *fl_filename_ext(const char *buf) { } // -// End of "$Id: filename_ext.cxx 6641 2009-01-20 11:10:29Z fabien $". +// End of "$Id: filename_ext.cxx 6986 2010-01-01 18:30:49Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/src/filename_isdir.cxx b/plugins/zynaddsubfx/fltk/src/filename_isdir.cxx index 5d62dcb57..a17bc19d5 100644 --- a/plugins/zynaddsubfx/fltk/src/filename_isdir.cxx +++ b/plugins/zynaddsubfx/fltk/src/filename_isdir.cxx @@ -1,5 +1,5 @@ // -// "$Id: filename_isdir.cxx 6641 2009-01-20 11:10:29Z fabien $" +// "$Id: filename_isdir.cxx 6986 2010-01-01 18:30:49Z greg.ercolano $" // // Directory detection routines for the Fast Light Tool Kit (FLTK). // @@ -48,7 +48,13 @@ int _fl_filename_isdir_quick(const char* n) { } /** - Determines if a file exists and is a directory from its filename + Determines if a file exists and is a directory from its filename. + \code + #include + [..] + fl_filename_isdir("/etc"); // returns non-zero + fl_filename_isdir("/etc/hosts"); // returns 0 + \endcode \param[in] n the filename to parse \return non zero if file exists and is a directory, zero otherwise */ @@ -93,5 +99,5 @@ int fl_filename_isdir(const char* n) { } // -// End of "$Id: filename_isdir.cxx 6641 2009-01-20 11:10:29Z fabien $". +// End of "$Id: filename_isdir.cxx 6986 2010-01-01 18:30:49Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/src/filename_list.cxx b/plugins/zynaddsubfx/fltk/src/filename_list.cxx index 3bb65ddeb..b863c674d 100644 --- a/plugins/zynaddsubfx/fltk/src/filename_list.cxx +++ b/plugins/zynaddsubfx/fltk/src/filename_list.cxx @@ -1,5 +1,5 @@ // -// "$Id: filename_list.cxx 6833 2009-07-23 22:51:56Z AlbrechtS $" +// "$Id: filename_list.cxx 6986 2010-01-01 18:30:49Z greg.ercolano $" // // Filename list routines for the Fast Light Tool Kit (FLTK). // @@ -58,6 +58,12 @@ int fl_casealphasort(struct dirent **a, struct dirent **b) { The number of entries is given as a return value. If there is an error reading the directory a number less than zero is returned, and errno has the reason; errno does not work under WIN32. + + \b Include: + \code + #include + \endcode + \param[in] d the name of the directory to list. It does not matter if it has a trailing slash. \param[out] list table containing the resulting directory listing \param[in] sort sorting functor: @@ -77,7 +83,7 @@ int fl_filename_list(const char *d, dirent ***list, Fl_File_Sort_F *sort) { #ifndef HAVE_SCANDIR int n = scandir(d, list, 0, sort); -#elif defined(__hpux) || defined(__CYGWIN__) || (__GLIBC__ >= 2 && __GLIBC_MINOR__ >= 10 ) +#elif defined(HAVE_SCANDIR_POSIX) // HP-UX, Cygwin and POSIX (2008) define the comparison function like this: int n = scandir(d, list, 0, (int(*)(const dirent **, const dirent **))sort); #elif defined(__osf__) @@ -126,5 +132,5 @@ int fl_filename_list(const char *d, dirent ***list, } // -// End of "$Id: filename_list.cxx 6833 2009-07-23 22:51:56Z AlbrechtS $". +// End of "$Id: filename_list.cxx 6986 2010-01-01 18:30:49Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/src/filename_match.cxx b/plugins/zynaddsubfx/fltk/src/filename_match.cxx index d61f8233b..1f3d729f0 100644 --- a/plugins/zynaddsubfx/fltk/src/filename_match.cxx +++ b/plugins/zynaddsubfx/fltk/src/filename_match.cxx @@ -1,5 +1,5 @@ // -// "$Id: filename_match.cxx 6716 2009-03-24 01:40:44Z fabien $" +// "$Id: filename_match.cxx 7162 2010-02-26 21:10:46Z matt $" // // Pattern matching routines for the Fast Light Tool Kit (FLTK). // @@ -40,6 +40,12 @@ - {X|Y|Z} or {X,Y,Z} matches any one of the subexpressions literally. - \\x quotes the character x so it has no special meaning. - x all other characters must be matched exactly. + + \b Include: + \code + #include + \endcode + \param[in] s the string to check for a match \param[in] p the string pattern \return non zero if the string matches the pattern @@ -108,6 +114,7 @@ int fl_filename_match(const char *s, const char *p) { case '\\': // quote next character if (*p) p++; + /* FALLTHROUGH */ default: if (tolower(*s) != tolower(*(p-1))) return 0; s++; @@ -117,5 +124,5 @@ int fl_filename_match(const char *s, const char *p) { } // -// End of "$Id: filename_match.cxx 6716 2009-03-24 01:40:44Z fabien $". +// End of "$Id: filename_match.cxx 7162 2010-02-26 21:10:46Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/filename_setext.cxx b/plugins/zynaddsubfx/fltk/src/filename_setext.cxx index 9bf975990..7dc12cc61 100644 --- a/plugins/zynaddsubfx/fltk/src/filename_setext.cxx +++ b/plugins/zynaddsubfx/fltk/src/filename_setext.cxx @@ -1,5 +1,5 @@ // -// "$Id: filename_setext.cxx 6716 2009-03-24 01:40:44Z fabien $" +// "$Id: filename_setext.cxx 6986 2010-01-01 18:30:49Z greg.ercolano $" // // Filename extension routines for the Fast Light Tool Kit (FLTK). // @@ -26,14 +26,24 @@ // // Replace .ext with new extension -// If no . in name, append new extension -// If new extension is null, act like it is "" #include #include "flstring.h" /** - Replaces the extension in \p buf of max. size \p buflen with the extension in \p ext. + Replaces the extension in \p buf of max.
+ size \p buflen with the extension in \p ext.
+ If there's no '.' in \p buf, \p ext is appended.
+ If \p ext is NULL, behaves as if it were an empty string (""). + + \b Example + \code + #include + [..] + char buf[1024] = "/path/myfile.cxx"; + fl_filename_setext(buf, sizeof(buf), ".txt"); // buf[] becomes "/path/myfile.txt" + \endcode + \return buf itself for calling convenience. */ char *fl_filename_setext(char *buf, int buflen, const char *ext) { @@ -46,5 +56,5 @@ char *fl_filename_setext(char *buf, int buflen, const char *ext) { // -// End of "$Id: filename_setext.cxx 6716 2009-03-24 01:40:44Z fabien $". +// End of "$Id: filename_setext.cxx 6986 2010-01-01 18:30:49Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_arc.cxx b/plugins/zynaddsubfx/fltk/src/fl_arc.cxx index 8ad8a23e0..273a39e5d 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_arc.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_arc.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_arc.cxx 6716 2009-03-24 01:40:44Z fabien $" +// "$Id: fl_arc.cxx 7617 2010-05-27 17:20:18Z manolo $" // // Arc functions for the Fast Light Tool Kit (FLTK). // @@ -43,15 +43,7 @@ static double _fl_hypot(double x, double y) { return sqrt(x*x + y*y); } -/** - Add a series of points to the current path on the arc of a circle; you - can get elliptical paths by using scale and rotate before calling fl_arc(). - \param[in] x,y,r center and radius of circular arc - \param[in] start,end angles of start and end of arc measured in degrees - counter-clockwise from 3 o'clock. If \p end is less than \p start - then it draws the arc in a clockwise direction. -*/ -void fl_arc(double x, double y, double r, double start, double end) { +void Fl_Graphics_Driver::arc(double x, double y, double r, double start, double end) { // draw start point accurately: @@ -95,5 +87,5 @@ void fl_circle(double x,double y,double r) { #endif // -// End of "$Id: fl_arc.cxx 6716 2009-03-24 01:40:44Z fabien $". +// End of "$Id: fl_arc.cxx 7617 2010-05-27 17:20:18Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_arci.cxx b/plugins/zynaddsubfx/fltk/src/fl_arci.cxx index ea93b5f60..3327d2d0e 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_arci.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_arci.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_arci.cxx 6716 2009-03-24 01:40:44Z fabien $" +// "$Id: fl_arci.cxx 7617 2010-05-27 17:20:18Z manolo $" // // Arc (integer) drawing functions for the Fast Light Tool Kit (FLTK). // @@ -47,29 +47,7 @@ #endif #include -/** - Draw ellipse sections using integer coordinates. - - These functions match the rather limited circle drawing code provided by X - and WIN32. The advantage over using fl_arc with floating point coordinates - is that they are faster because they often use the hardware, and they draw - much nicer small circles, since the small sizes are often hard-coded bitmaps. - - If a complete circle is drawn it will fit inside the passed bounding box. - The two angles are measured in degrees counterclockwise from 3 o'clock and - are the starting and ending angle of the arc, \p a2 must be greater or equal - to \p a1. - - fl_arc() draws a series of lines to approximate the arc. Notice that the - integer version of fl_arc() has a different number of arguments than the - double version fl_arc(double x, double y, double r, double start, double a) - - \param[in] x,y,w,h bounding box of complete circle - \param[in] a1,a2 start and end angles of arc measured in degrees - counter-clockwise from 3 o'clock. \p a2 must be greater - than or equal to \p a1. -*/ -void fl_arc(int x,int y,int w,int h,double a1,double a2) { +void Fl_Graphics_Driver::arc(int x,int y,int w,int h,double a1,double a2) { if (w <= 0 || h <= 0) return; #if defined(USE_X11) @@ -86,6 +64,7 @@ void fl_arc(int x,int y,int w,int h,double a1,double a2) { #elif defined(__APPLE_QUARTZ__) a1 = (-a1)/180.0f*M_PI; a2 = (-a2)/180.0f*M_PI; float cx = x + 0.5f*w - 0.5f, cy = y + 0.5f*h - 0.5f; + CGContextSetShouldAntialias(fl_gc, true); if (w!=h) { CGContextSaveGState(fl_gc); CGContextTranslateCTM(fl_gc, cx, cy); @@ -97,24 +76,13 @@ void fl_arc(int x,int y,int w,int h,double a1,double a2) { CGContextAddArc(fl_gc, cx, cy, r, a1, a2, 1); } CGContextStrokePath(fl_gc); + CGContextSetShouldAntialias(fl_gc, false); #else # error unsupported platform #endif } -/** - Draw filled ellipse sections using integer coordinates. - - Like fl_arc(), but fl_pie() draws a filled-in pie slice. - This slice may extend outside the line drawn by fl_arc(); - to avoid this use w - 1 and h - 1. - - \param[in] x,y,w,h bounding box of complete circle - \param[in] a1,a2 start and end angles of arc measured in degrees - counter-clockwise from 3 o'clock. \p a2 must be greater - than or equal to \p a1. -*/ -void fl_pie(int x,int y,int w,int h,double a1,double a2) { +void Fl_Graphics_Driver::pie(int x,int y,int w,int h,double a1,double a2) { if (w <= 0 || h <= 0) return; #if defined(USE_X11) @@ -136,6 +104,7 @@ void fl_pie(int x,int y,int w,int h,double a1,double a2) { #elif defined(__APPLE_QUARTZ__) a1 = (-a1)/180.0f*M_PI; a2 = (-a2)/180.0f*M_PI; float cx = x + 0.5f*w - 0.5f, cy = y + 0.5f*h - 0.5f; + CGContextSetShouldAntialias(fl_gc, true); if (w!=h) { CGContextSaveGState(fl_gc); CGContextTranslateCTM(fl_gc, cx, cy); @@ -151,11 +120,12 @@ void fl_pie(int x,int y,int w,int h,double a1,double a2) { CGContextClosePath(fl_gc); } CGContextFillPath(fl_gc); + CGContextSetShouldAntialias(fl_gc, false); #else # error unsupported platform #endif } // -// End of "$Id: fl_arci.cxx 6716 2009-03-24 01:40:44Z fabien $". +// End of "$Id: fl_arci.cxx 7617 2010-05-27 17:20:18Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_ask.cxx b/plugins/zynaddsubfx/fltk/src/fl_ask.cxx index 0abb379ad..f7350dd33 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_ask.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_ask.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_ask.cxx 6869 2009-09-13 21:57:46Z AlbrechtS $" +// "$Id: fl_ask.cxx 7370 2010-03-30 19:44:50Z AlbrechtS $" // // Standard dialog functions for the Fast Light Tool Kit (FLTK). // @@ -47,17 +47,30 @@ #include #include +#ifdef __APPLE__ +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +# include +# endif +#endif + static Fl_Window *message_form; static Fl_Box *message; static Fl_Box *icon; static Fl_Button *button[3]; static Fl_Input *input; +static int ret_val; static const char *iconlabel = "?"; Fl_Font fl_message_font_ = FL_HELVETICA; Fl_Fontsize fl_message_size_ = 14; static char avoidRecursion = 0; +// sets the global return value (ret_val) and closes the window +static void button_cb(Fl_Widget *bt, void *val) { + ret_val = (int)(long)val; + message_form->hide(); +} + static Fl_Window *makeform() { if (message_form) { message_form->size(410,103); @@ -81,13 +94,16 @@ static Fl_Window *makeform() { o->color(FL_WHITE); o->labelcolor(FL_BLUE); } - button[0] = new Fl_Button(310, 70, 90, 23); + // create the buttons (right to left) + for (int b=0, x=310; b<3; b++, x -= 100) { + if (b==1) + button[b] = new Fl_Return_Button(x, 70, 90, 23); + else + button[b] = new Fl_Button(x, 70, 90, 23); + button[b]->align(FL_ALIGN_INSIDE|FL_ALIGN_WRAP); + button[b]->callback(button_cb,(void *)b); + } button[0]->shortcut(FL_Escape); - button[0]->align(FL_ALIGN_INSIDE|FL_ALIGN_WRAP); - button[1] = new Fl_Return_Button(210, 70, 90, 23); - button[1]->align(FL_ALIGN_INSIDE|FL_ALIGN_WRAP); - button[2] = new Fl_Button(110, 70, 90, 23); - button[2]->align(FL_ALIGN_INSIDE|FL_ALIGN_WRAP); w->resizable(new Fl_Box(60,10,110-60,27)); w->end(); w->set_modal(); @@ -212,31 +228,22 @@ static int innards(const char* fmt, va_list ap, else button[0]->shortcut(FL_Escape); - message_form->show(); - // deactivate Fl::grab(), because it is incompatible with Fl::readqueue() + // deactivate Fl::grab(), because it is incompatible with modal windows Fl_Window* g = Fl::grab(); if (g) Fl::grab(0); - int r = 0; - for (;;) { - Fl_Widget *o = Fl::readqueue(); - if (!o) Fl::wait(); - else if (o == button[0]) {r = 0; break;} - else if (o == button[1]) {r = 1; break;} - else if (o == button[2]) {r = 2; break;} - else if (o == message_form) {r = 0; break;} - } + message_form->show(); + while (message_form->shown()) Fl::wait(); if (g) // regrab the previous popup menu, if there was one Fl::grab(g); - message_form->hide(); icon->label(prev_icon_label); avoidRecursion = 0; - return r; + return ret_val; } /** \addtogroup group_comdlg @{ */ - + // pointers you can use to change FLTK to a foreign language: const char* fl_no = "No"; ///< string pointer used in common dialogs, you can change it to a foreign language const char* fl_yes= "Yes"; ///< string pointer used in common dialogs, you can change it to a foreign language @@ -273,7 +280,26 @@ void fl_beep(int type) { switch (type) { case FL_BEEP_DEFAULT : case FL_BEEP_ERROR : - SysBeep(30); + // How Apple is not any better than Microsoft: + /* MacOS 8 */ // SysBeep(30); + /* OS X 10.1 */ // AlertSoundPlay(); + /* OS X 10.5 */ // AudioServicesPlayAlertSound(kUserPreferredAlert); + /* OS X 10.6 */ // AudioServicesPlayAlertSound(kSystemSoundID_UserPreferredAlert); +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if (AudioServicesPlayAlertSound!=0L) +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + AudioServicesPlayAlertSound(kSystemSoundID_UserPreferredAlert); +# else + AudioServicesPlayAlertSound(kUserPreferredAlert); +# endif + else +# endif +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 + AlertSoundPlay(); +#else + { + } +#endif break; default : break; @@ -460,5 +486,5 @@ const char *fl_password(const char *fmt, const char *defstr, ...) { /** @} */ // -// End of "$Id: fl_ask.cxx 6869 2009-09-13 21:57:46Z AlbrechtS $". +// End of "$Id: fl_ask.cxx 7370 2010-03-30 19:44:50Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_boxtype.cxx b/plugins/zynaddsubfx/fltk/src/fl_boxtype.cxx index 6f8222ee0..6a1b76199 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_boxtype.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_boxtype.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_boxtype.cxx 6902 2009-09-27 11:06:56Z matt $" +// "$Id: fl_boxtype.cxx 7469 2010-04-07 23:17:33Z matt $" // // Box drawing code for the Fast Light Tool Kit (FLTK). // @@ -399,14 +399,19 @@ void fl_draw_box(Fl_Boxtype t, int x, int y, int w, int h, Fl_Color c) { //extern Fl_Widget *fl_boxcheat; // hack set by Fl_Window.cxx /** Draws the widget box according its box style */ void Fl_Widget::draw_box() const { - int t = box_; - if (!t) return; -// if (this == fl_boxcheat) { -// fl_boxcheat = 0; -// if (t == FL_FLAT_BOX) return; -// t += 2; // convert box to frame -// } - draw_box((Fl_Boxtype)t, x_, y_, w_, h_, color_); + if (box_) draw_box((Fl_Boxtype)box_, x_, y_, w_, h_, color_); + draw_backdrop(); +} +/** If FL_ALIGN_IMAGE_BACKDROP is set, the image or deimage will be drawn */ +void Fl_Widget::draw_backdrop() const { + if (align() & FL_ALIGN_IMAGE_BACKDROP) { + const Fl_Image *img = image(); + // if there is no image, we will not draw the deimage either + if (img && deimage() && !active_r()) + img = deimage(); + if (img) + ((Fl_Image*)img)->draw(x_+(w_-img->w())/2, y_+(h_-img->h())/2); + } } /** Draws a box of type t, of color c at the widget's position and size. */ void Fl_Widget::draw_box(Fl_Boxtype t, Fl_Color c) const { @@ -420,5 +425,5 @@ void Fl_Widget::draw_box(Fl_Boxtype t, int X, int Y, int W, int H, Fl_Color c) c } // -// End of "$Id: fl_boxtype.cxx 6902 2009-09-27 11:06:56Z matt $". +// End of "$Id: fl_boxtype.cxx 7469 2010-04-07 23:17:33Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_call_main.c b/plugins/zynaddsubfx/fltk/src/fl_call_main.c index b43c53c2a..2ed215037 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_call_main.c +++ b/plugins/zynaddsubfx/fltk/src/fl_call_main.c @@ -1,5 +1,5 @@ /* - * "$Id: fl_call_main.c 6680 2009-03-14 02:11:31Z greg.ercolano $" + * "$Id: fl_call_main.c 7352 2010-03-29 10:47:11Z matt $" * * Copyright 1998-2009 by Bill Spitzak and others. * @@ -51,11 +51,7 @@ # include # include # include -#include - -# ifdef __MWERKS__ -# include -# endif +# include extern int main(int, char *[]); @@ -142,6 +138,6 @@ static void dummy(void) {} #endif /* WIN32 && !FL_DLL && !__GNUC__ */ /* - * End of "$Id: fl_call_main.c 6680 2009-03-14 02:11:31Z greg.ercolano $". + * End of "$Id: fl_call_main.c 7352 2010-03-29 10:47:11Z matt $". */ diff --git a/plugins/zynaddsubfx/fltk/src/fl_color.cxx b/plugins/zynaddsubfx/fltk/src/fl_color.cxx index c1d182227..5946976ce 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_color.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_color.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_color.cxx 6813 2009-07-01 07:32:14Z AlbrechtS $" +// "$Id: fl_color.cxx 7617 2010-05-27 17:20:18Z manolo $" // // Color functions for the Fast Light Tool Kit (FLTK). // @@ -124,6 +124,26 @@ Fl_XColor fl_xmap[1][256]; # define fl_overlay 0 # endif +/** Current color for drawing operations */ +Fl_Color fl_color_; + +void Fl_Graphics_Driver::color(Fl_Color i) { + if (i & 0xffffff00) { + unsigned rgb = (unsigned)i; + fl_color((uchar)(rgb >> 24), (uchar)(rgb >> 16), (uchar)(rgb >> 8)); + } else { + fl_color_ = i; + if(!fl_gc) return; // don't get a default gc if current window is not yet created/valid + XSetForeground(fl_display, fl_gc, fl_xpixel(i)); + } +} + +void Fl_Graphics_Driver::color(uchar r,uchar g,uchar b) { + fl_color_ = fl_rgb_color(r, g, b); + if(!fl_gc) return; // don't get a default gc if current window is not yet created/valid + XSetForeground(fl_display, fl_gc, fl_xpixel(r,g,b)); +} + /** \addtogroup fl_attributes @{ */ //////////////////////////////////////////////////////////////// @@ -161,22 +181,6 @@ ulong fl_xpixel(uchar r,uchar g,uchar b) { ) >> fl_extrashift; } -/** - Set the color for all subsequent drawing operations. - The closest possible match to the RGB color is used. - The RGB color is used directly on TrueColor displays. - For colormap visuals the nearest index in the gray - ramp or color cube is used. - If no valid graphical context (fl_gc) is available, - the foreground is not set for the current window. - \param[in] r,g,b color components -*/ -void fl_color(uchar r,uchar g,uchar b) { - fl_color_ = fl_rgb_color(r, g, b); - if(!fl_gc) return; // don't get a default gc if current window is not yet created/valid - XSetForeground(fl_display, fl_gc, fl_xpixel(r,g,b)); -} - //////////////////////////////////////////////////////////////// // Get a color out of the fltk colormap. Again for truecolor // visuals this is easy. For colormap this actually tries to allocate @@ -316,29 +320,6 @@ ulong fl_xpixel(Fl_Color i) { # endif } -/** Current color for drawing operations */ -Fl_Color fl_color_; - -/** - Sets the color for all subsequent drawing operations. - For colormapped displays, a color cell will be allocated out of - \p fl_colormap the first time you use a color. If the colormap fills up - then a least-squares algorithm is used to find the closest color. - If no valid graphical context (fl_gc) is available, - the foreground is not set for the current window. - \param[in] i color -*/ -void fl_color(Fl_Color i) { - if (i & 0xffffff00) { - unsigned rgb = (unsigned)i; - fl_color((uchar)(rgb >> 24), (uchar)(rgb >> 16), (uchar)(rgb >> 8)); - } else { - fl_color_ = i; - if(!fl_gc) return; // don't get a default gc if current window is not yet created/valid - XSetForeground(fl_display, fl_gc, fl_xpixel(i)); - } -} - /** Free color \p i if used, and clear mapping table entry. \param[in] i color index @@ -484,5 +465,5 @@ Fl_Color fl_contrast(Fl_Color fg, Fl_Color bg) { @} */ // -// End of "$Id: fl_color.cxx 6813 2009-07-01 07:32:14Z AlbrechtS $". +// End of "$Id: fl_color.cxx 7617 2010-05-27 17:20:18Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_color_mac.cxx b/plugins/zynaddsubfx/fltk/src/fl_color_mac.cxx index a23d7af86..def0ae400 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_color_mac.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_color_mac.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_color_mac.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: fl_color_mac.cxx 7617 2010-05-27 17:20:18Z manolo $" // // MacOS color functions for the Fast Light Tool Kit (FLTK). // @@ -49,7 +49,7 @@ Fl_XMap* fl_current_xmap; Fl_Color fl_color_; -void fl_color(Fl_Color i) { +void Fl_Graphics_Driver::color(Fl_Color i) { fl_color_ = i; int index; uchar r, g, b; @@ -66,29 +66,21 @@ void fl_color(Fl_Color i) { g = c>>16; b = c>> 8; } -#if defined(__APPLE_QUARTZ__) if (!fl_gc) return; // no context yet? We will assign the color later. float fr = r/255.0f; float fg = g/255.0f; float fb = b/255.0f; CGContextSetRGBFillColor(fl_gc, fr, fg, fb, 1.0f); CGContextSetRGBStrokeColor(fl_gc, fr, fg, fb, 1.0f); -#else -# error : neither Quickdraw nor Quartz defined -#endif } -void fl_color(uchar r, uchar g, uchar b) { +void Fl_Graphics_Driver::color(uchar r, uchar g, uchar b) { fl_color_ = fl_rgb_color(r, g, b); -#if defined(__APPLE_QUARTZ__) float fr = r/255.0f; float fg = g/255.0f; float fb = b/255.0f; CGContextSetRGBFillColor(fl_gc, fr, fg, fb, 1.0f); CGContextSetRGBStrokeColor(fl_gc, fr, fg, fb, 1.0f); -#else -# error : Quartz not defined -#endif } void Fl::set_color(Fl_Color i, unsigned c) { @@ -98,5 +90,5 @@ void Fl::set_color(Fl_Color i, unsigned c) { } // -// End of "$Id: fl_color_mac.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: fl_color_mac.cxx 7617 2010-05-27 17:20:18Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_color_win32.cxx b/plugins/zynaddsubfx/fltk/src/fl_color_win32.cxx index 48ce3a9fe..1aab0d77b 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_color_win32.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_color_win32.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_color_win32.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: fl_color_win32.cxx 7617 2010-05-27 17:20:18Z manolo $" // // WIN32 color functions for the Fast Light Tool Kit (FLTK). // @@ -94,7 +94,7 @@ static void set_xmap(Fl_XMap& xmap, COLORREF c) { Fl_Color fl_color_; -void fl_color(Fl_Color i) { +void Fl_Graphics_Driver::color(Fl_Color i) { if (i & 0xffffff00) { unsigned rgb = (unsigned)i; fl_color((uchar)(rgb >> 24), (uchar)(rgb >> 16), (uchar)(rgb >> 8)); @@ -118,7 +118,7 @@ void fl_color(Fl_Color i) { } } -void fl_color(uchar r, uchar g, uchar b) { +void Fl_Graphics_Driver::color(uchar r, uchar g, uchar b) { static Fl_XMap xmap; COLORREF c = RGB(r,g,b); fl_color_ = fl_rgb_color(r, g, b); @@ -250,5 +250,5 @@ fl_select_palette(void) #endif // -// End of "$Id: fl_color_win32.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: fl_color_win32.cxx 7617 2010-05-27 17:20:18Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_cursor.cxx b/plugins/zynaddsubfx/fltk/src/fl_cursor.cxx index 03feb04db..2d454359c 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_cursor.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_cursor.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_cursor.cxx 6690 2009-03-15 20:52:46Z engelsman $" +// "$Id: fl_cursor.cxx 7351 2010-03-29 10:35:00Z matt $" // // Mouse cursor support for the Fast Light Tool Kit (FLTK). // @@ -134,115 +134,107 @@ void Fl_Window::cursor(Fl_Cursor c, Fl_Color c1, Fl_Color c2) { # error "Either __LITTLE_ENDIAN__ or __BIG_ENDIAN__ must be defined" #endif -static Cursor crsrHAND = -{ - { E(0x0600), E(0x0900), E(0x0900), E(0x0900), E(0x09C0), E(0x0938), E(0x6926), E(0x9805), - E(0x8801), E(0x4801), E(0x2002), E(0x2002), E(0x1004), E(0x0804), E(0x0408), E(0x0408) }, - { E(0x0600), E(0x0F00), E(0x0F00), E(0x0F00), E(0x0FC0), E(0x0FF8), E(0x6FFE), E(0xFFFF), - E(0xFFFF), E(0x7FFF), E(0x3FFE), E(0x3FFE), E(0x1FFC), E(0x0FFC), E(0x07F8), E(0x07F8) }, - { 1, 5 } // Hotspot: ( y, x ) -}, *crsrHANDptr = &crsrHAND; -static Cursor crsrHELP = -{ - { E(0x0000), E(0x4000), E(0x6000), E(0x7000), E(0x783C), E(0x7C7E), E(0x7E66), E(0x7F06), - E(0x7F8C), E(0x7C18), E(0x6C18), E(0x4600), E(0x0618), E(0x0318), E(0x0300), E(0x0000) }, - { E(0xC000), E(0xE000), E(0xF000), E(0xF83C), E(0xFC7E), E(0xFEFF), E(0xFFFF), E(0xFFFF), - E(0xFFFE), E(0xFFFC), E(0xFE3C), E(0xEF3C), E(0xCF3C), E(0x07BC), E(0x0798), E(0x0380) }, - { 1, 1 } -}, *crsrHELPptr = &crsrHELP; -static Cursor crsrMOVE = -{ - { E(0x0000), E(0x0180), E(0x03C0), E(0x07E0), E(0x07E0), E(0x1998), E(0x399C), E(0x7FFE), - E(0x7FFE), E(0x399C), E(0x1998), E(0x07E0), E(0x07E0), E(0x03C0), E(0x0180), E(0x0000) }, - { E(0x0180), E(0x03C0), E(0x07E0), E(0x0FF0), E(0x1FF8), E(0x3FFC), E(0x7FFE), E(0xFFFF), - E(0xFFFF), E(0x7FFE), E(0x3FFC), E(0x1FF8), E(0x0FF0), E(0x07E0), E(0x03C0), E(0x0180) }, - { 8, 8 } -}, *crsrMOVEptr = &crsrMOVE; -static Cursor crsrNS = -{ - { E(0x0000), E(0x0180), E(0x03C0), E(0x07E0), E(0x0FF0), E(0x0180), E(0x0180), E(0x0180), - E(0x0180), E(0x0180), E(0x0180), E(0x0FF0), E(0x07E0), E(0x03C0), E(0x0180), E(0x0000) }, - { E(0x0180), E(0x03C0), E(0x07E0), E(0x0FF0), E(0x1FF8), E(0x1FF8), E(0x03C0), E(0x03C0), - E(0x03C0), E(0x03C0), E(0x1FF8), E(0x1FF8), E(0x0FF0), E(0x07E0), E(0x03C0), E(0x0180) }, - { 8, 8 } -}, *crsrNSptr = &crsrNS; -static Cursor crsrWE = -{ - { E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0810), E(0x1818), E(0x381C), E(0x7FFE), - E(0x7FFE), E(0x381C), E(0x1818), E(0x0810), E(0x0000), E(0x0000), E(0x0000), E(0x0000) }, - { E(0x0000), E(0x0000), E(0x0000), E(0x0C30), E(0x1C38), E(0x3C3C), E(0x7FFE), E(0xFFFF), - E(0xFFFF), E(0x7FFE), E(0x3C3C), E(0x1C38), E(0x0C30), E(0x0000), E(0x0000), E(0x0000) }, - { 8, 8 } -}, *crsrWEptr = &crsrWE; -static Cursor crsrNWSE = -{ - { E(0x0000), E(0x7E00), E(0x7C00), E(0x7800), E(0x7C00), E(0x6E00), E(0x4710), E(0x03B0), - E(0x01F0), E(0x00F0), E(0x01F0), E(0x03F0), E(0x0000), E(0x0000), E(0x0000), E(0x0000) }, - { E(0xFF00), E(0xFF00), E(0xFE00), E(0xFC00), E(0xFE00), E(0xFF18), E(0xEFB8), E(0xC7F8), - E(0x03F8), E(0x01F8), E(0x03F8), E(0x07F8), E(0x07F8), E(0x0000), E(0x0000), E(0x0000) }, - { 8, 8 } -}, *crsrNWSEptr = &crsrNWSE; -static Cursor crsrNESW = -{ - { E(0x0000), E(0x03F0), E(0x01F0), E(0x00F0), E(0x01F0), E(0x03B0), E(0x4710), E(0x6E00), - E(0x7C00), E(0x7800), E(0x7C00), E(0x7E00), E(0x0000), E(0x0000), E(0x0000), E(0x0000) }, - { E(0x07F8), E(0x07F8), E(0x03F8), E(0x01F8), E(0x03F8), E(0xC7F8), E(0xEFB8), E(0xFF18), - E(0xFE00), E(0xFC00), E(0xFE00), E(0xFF00), E(0xFF00), E(0x0000), E(0x0000), E(0x0000) }, - { 8, 8 } -}, *crsrNESWptr = &crsrNESW; -static Cursor crsrNONE = -{ - { E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), - E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000) }, - { E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), - E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000) }, - { 0, 0 } -}, *crsrNONEptr = &crsrNONE; -static Cursor crsrARROW = -{ - { E(0x0000), E(0x4000), E(0x6000), E(0x7000), E(0x7800), E(0x7C00), E(0x7E00), E(0x7F00), - E(0x7F80), E(0x7C00), E(0x6C00), E(0x4600), E(0x0600), E(0x0300), E(0x0300), E(0x0000) }, - { E(0xC000), E(0xE000), E(0xF000), E(0xF800), E(0xFC00), E(0xFE00), E(0xFF00), E(0xFF80), - E(0xFFC0), E(0xFFC0), E(0xFE00), E(0xEF00), E(0xCF00), E(0x0780), E(0x0780), E(0x0380) }, - { 1, 1 } -}, *crsrARROWptr = &crsrARROW; +extern void *MACSetCursor(Fl_Cursor c); +extern Fl_Offscreen fl_create_offscreen_with_alpha(int w, int h); -#undef E + +CGContextRef CreateHelpImage(void) +{ + int w = 20, h = 20; + Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h); + fl_begin_offscreen(off); + CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); + fl_rectf(0,0,w,h); + fl_color(FL_BLACK); + fl_font(FL_COURIER_BOLD, 20); + fl_draw("?", 1, h-1); + fl_end_offscreen(); + return (CGContextRef)off; +} + +CGContextRef CreateNoneImage(void) +{ + int w = 20, h = 20; + Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h); + fl_begin_offscreen(off); + CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); + fl_rectf(0,0,w,h); + fl_end_offscreen(); + return (CGContextRef)off; +} + +CGContextRef CreateWatchImage(void) +{ + int w, h, r = 5; + w = 2*r+6; + h = 4*r; + Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h); + fl_begin_offscreen(off); + CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); + fl_rectf(0,0,w,h); + CGContextTranslateCTM( (CGContextRef)off, w/2, h/2); + fl_color(FL_WHITE); + fl_circle(0, 0, r+1); + fl_color(FL_BLACK); + fl_rectf(-r*0.7, -r*1.7, 1.4*r, 3.4*r); + fl_rectf(r-1, -1, 3, 3); + fl_color(FL_WHITE); + fl_pie(-r, -r, 2*r, 2*r, 0, 360); + fl_color(FL_BLACK); + fl_circle(0,0,r); + fl_xyline(0, 0, -r*.7); + fl_xyline(0, 0, 0, -r*.7); + fl_end_offscreen(); + return (CGContextRef)off; +} + +CGContextRef CreateNESWImage(void) +{ + int c = 7, r = 2*c; + int w = r, h = r; + Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h); + fl_begin_offscreen(off); + CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); + fl_rectf(0,0,w,h); + CGContextTranslateCTM( (CGContextRef)off, 0, h); + CGContextScaleCTM( (CGContextRef)off, 1, -1); + fl_color(FL_BLACK); + fl_polygon(0, 0, c, 0, 0, c); + fl_polygon(r, r, r, r-c, r-c, r); + fl_line_style(FL_SOLID, 2, 0); + fl_line(0,1, r,r+1); + fl_line_style(FL_SOLID, 0, 0); + fl_end_offscreen(); + return (CGContextRef)off; +} + +CGContextRef CreateNWSEImage(void) +{ + int c = 7, r = 2*c; + int w = r, h = r; + Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h); + fl_begin_offscreen(off); + CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0); + fl_rectf(0,0,w,h); + CGContextTranslateCTM( (CGContextRef)off, 0, h); + CGContextScaleCTM( (CGContextRef)off, 1, -1); + fl_color(FL_BLACK); + fl_polygon(r-1, 0, r-1, c, r-1-c, 0); + fl_polygon(-1, r, c-1, r, -1, r-c); + fl_line_style(FL_SOLID, 2, 0); + fl_line(r-1,1, -1,r+1); + fl_line_style(FL_SOLID, 0, 0); + fl_end_offscreen(); + return (CGContextRef)off; +} void Fl_Window::cursor(Fl_Cursor c, Fl_Color, Fl_Color) { if (c == FL_CURSOR_DEFAULT) { c = cursor_default; } - CursHandle icrsr = fl_default_cursor; - switch (c) { - case FL_CURSOR_CROSS: icrsr = GetCursor( crossCursor ); break; - case FL_CURSOR_WAIT: icrsr = GetCursor( watchCursor ); break; - case FL_CURSOR_INSERT: icrsr = GetCursor( iBeamCursor ); break; - case FL_CURSOR_N: - case FL_CURSOR_S: - case FL_CURSOR_NS: icrsr = &crsrNSptr; break; - case FL_CURSOR_HELP: icrsr = &crsrHELPptr; break; - case FL_CURSOR_HAND: icrsr = &crsrHANDptr; break; - case FL_CURSOR_MOVE: icrsr = &crsrMOVEptr; break; - case FL_CURSOR_NE: - case FL_CURSOR_SW: - case FL_CURSOR_NESW: icrsr = &crsrNESWptr; break; - case FL_CURSOR_E: - case FL_CURSOR_W: - case FL_CURSOR_WE: icrsr = &crsrWEptr; break; - case FL_CURSOR_SE: - case FL_CURSOR_NW: - case FL_CURSOR_NWSE: icrsr = &crsrNWSEptr; break; - case FL_CURSOR_NONE: icrsr = &crsrNONEptr; break; - case FL_CURSOR_ARROW: icrsr = &crsrARROWptr; break; - case FL_CURSOR_DEFAULT: - default: break; - } - if (icrsr) { // make sure we have a non null icrsr before updating cursor state - SetCursor( *icrsr ); - if (i) { - i->cursor = icrsr; - } + void *cursor = MACSetCursor( c ); + if (i) { + i->cursor = cursor; } } @@ -341,5 +333,5 @@ void Fl_Window::cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) { #endif // -// End of "$Id: fl_cursor.cxx 6690 2009-03-15 20:52:46Z engelsman $". +// End of "$Id: fl_cursor.cxx 7351 2010-03-29 10:35:00Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_curve.cxx b/plugins/zynaddsubfx/fltk/src/fl_curve.cxx index a88146a66..029c05f48 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_curve.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_curve.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_curve.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: fl_curve.cxx 7617 2010-05-27 17:20:18Z manolo $" // // Bezier curve functions for the Fast Light Tool Kit (FLTK). // @@ -38,15 +38,7 @@ #include #include -/** - Add a series of points on a Bezier curve to the path. - The curve ends (and two of the points) are at X0,Y0 and X3,Y3. - \param[in] X0,Y0 curve start point - \param[in] X1,Y1 curve control point - \param[in] X2,Y2 curve control point - \param[in] X3,Y3 curve end point -*/ -void fl_curve(double X0, double Y0, +void Fl_Graphics_Driver::curve(double X0, double Y0, double X1, double Y1, double X2, double Y2, double X3, double Y3) { @@ -114,5 +106,5 @@ void fl_curve(double X0, double Y0, } // -// End of "$Id: fl_curve.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: fl_curve.cxx 7617 2010-05-27 17:20:18Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_dnd_mac.cxx b/plugins/zynaddsubfx/fltk/src/fl_dnd_mac.cxx index 3312185d9..032750412 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_dnd_mac.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_dnd_mac.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_dnd_mac.cxx 6755 2009-04-12 13:48:03Z matt $" +// "$Id: fl_dnd_mac.cxx 7563 2010-04-28 03:15:47Z greg.ercolano $" // // Drag & Drop code for the Fast Light Tool Kit (FLTK). // @@ -20,7 +20,9 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 // USA. // -// Please report all bugs and problems to "fltk-bugs@fltk.org +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php // This file contains MacOS-specific code for fltk which is always linked // in. Search other files for "__APPLE__" or filenames ending in _mac.cxx @@ -46,45 +48,11 @@ extern int fl_selection_length; */ int Fl::dnd() { - OSErr result; - DragReference dragRef; - result = NewDrag( &dragRef ); - if ( result != noErr ) return false; - - result = AddDragItemFlavor( dragRef, 1, 'utf8', fl_selection_buffer, fl_selection_length, 0 ); - if ( result != noErr ) { DisposeDrag( dragRef ); return false; } - - Point mp; - GetMouse(&mp); - LocalToGlobal( &mp ); - RgnHandle region = NewRgn(); - SetRectRgn( region, mp.h-10, mp.v-10, mp.h+10, mp.v+10 ); - RgnHandle r2 = NewRgn(); - SetRectRgn( r2, mp.h-8, mp.v-8, mp.h+8, mp.v+8 ); - DiffRgn( region, r2, region ); - DisposeRgn( r2 ); - - EventRecord event; - ConvertEventRefToEventRecord( fl_os_event, &event ); - result = TrackDrag( dragRef, &event, region ); - - Fl_Widget *w = Fl::pushed(); - if ( w ) - { - int old_event = Fl::e_number; - w->handle(Fl::e_number = FL_RELEASE); - Fl::e_number = old_event; - Fl::pushed( 0 ); - } - - if ( result != noErr ) { DisposeRgn( region ); DisposeDrag( dragRef ); return false; } - - DisposeRgn( region ); - DisposeDrag( dragRef ); - return true; + extern int MACpreparedrag(void); + return MACpreparedrag(); } // -// End of "$Id: fl_dnd_mac.cxx 6755 2009-04-12 13:48:03Z matt $". +// End of "$Id: fl_dnd_mac.cxx 7563 2010-04-28 03:15:47Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_dnd_win32.cxx b/plugins/zynaddsubfx/fltk/src/fl_dnd_win32.cxx index 133bb7ae6..84a75b2d2 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_dnd_win32.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_dnd_win32.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_dnd_win32.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: fl_dnd_win32.cxx 7563 2010-04-28 03:15:47Z greg.ercolano $" // // Drag & Drop code for the Fast Light Tool Kit (FLTK). // @@ -20,7 +20,9 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 // USA. // -// Please report all bugs and problems to "fltk-bugs@fltk.org +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php // This file contains win32-specific code for fltk which is always linked // in. Search other files for "WIN32" or filenames ending in _win32.cxx @@ -527,5 +529,5 @@ int Fl::dnd() // -// End of "$Id: fl_dnd_win32.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: fl_dnd_win32.cxx 7563 2010-04-28 03:15:47Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_draw.cxx b/plugins/zynaddsubfx/fltk/src/fl_draw.cxx index 5d8e57475..129a74406 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_draw.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_draw.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_draw.cxx 6845 2009-08-28 20:14:41Z greg.ercolano $" +// "$Id: fl_draw.cxx 7502 2010-04-14 13:21:10Z manolo $" // // Label drawing code for the Fast Light Tool Kit (FLTK). // @@ -186,7 +186,8 @@ void fl_draw( int x, int y, int w, int h, // bounding box Fl_Align align, void (*callthis)(const char*,int,int,int), - Fl_Image* img, int draw_symbols) { + Fl_Image* img, int draw_symbols) +{ const char* p; const char* e; char buf[MAXBUF]; @@ -198,6 +199,9 @@ void fl_draw( int lines; double width; + // if the image is set as a backdrop, ignore it here + if (img && (align & FL_ALIGN_IMAGE_BACKDROP)) img = 0; + symbol[0][0] = '\0'; symwidth[0] = 0; @@ -222,29 +226,36 @@ void fl_draw( } symtotal = symwidth[0] + symwidth[1]; + + int strw = 0; + int strh; if (str) { - for (p = str, lines=0; p;) { + for (p = str, lines=0; p;) { e = fl_expand_text(p, buf, MAXBUF, w - symtotal, buflen, width, - align&FL_ALIGN_WRAP, draw_symbols); - lines++; - if (!*e || (*e == '@' && e[1] != '@' && draw_symbols)) break; - p = e; - } + align&FL_ALIGN_WRAP, draw_symbols); + if (strwh() : 0; + int imgvert = ((align&FL_ALIGN_IMAGE_NEXT_TO_TEXT)==0); + int imgh = img && imgvert ? img->h() : 0; + int imgw[2] = {0, 0}; symoffset = 0; @@ -253,7 +264,7 @@ void fl_draw( else ypos = y+(h-lines*height-imgh)/2+height; // draw the image unless the "text over image" alignment flag is set... - if (img && !(align & FL_ALIGN_TEXT_OVER_IMAGE)) { + if (img && imgvert && !(align & FL_ALIGN_TEXT_OVER_IMAGE)) { if (img->w() > symoffset) symoffset = img->w(); if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0]; @@ -264,6 +275,26 @@ void fl_draw( ypos += img->h(); } + // draw the image to the side of the text + if (img && !imgvert /* && (align & !FL_ALIGN_TEXT_NEXT_TO_IMAGE)*/ ) { + if (align & FL_ALIGN_TEXT_OVER_IMAGE) { // image is right of text + imgw[1] = img->w(); + if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0] + strw + 1; + else if (align & FL_ALIGN_RIGHT) xpos = x + w - symwidth[1] - imgw[1] + 1; + else xpos = x + (w - strw - symtotal - imgw[1]) / 2 + symwidth[0] + strw + 1; + } else { // image is to the left of the text + imgw[0] = img->w(); + if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0] - 1; + else if (align & FL_ALIGN_RIGHT) xpos = x + w - symwidth[1] - strw - imgw[0] - 1; + else xpos = x + (w - strw - symtotal - imgw[0]) / 2 - 1; + } + int yimg = ypos - height; + if (align & FL_ALIGN_TOP) ; + else if (align & FL_ALIGN_BOTTOM) yimg += strh - img->h() - 1; + else yimg += (strh - img->h() - 1) / 2; + img->draw(xpos, yimg); + } + // now draw all the lines: if (str) { int desc = fl_descent(); @@ -274,9 +305,9 @@ void fl_draw( if (width > symoffset) symoffset = (int)(width + 0.5); - if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0]; - else if (align & FL_ALIGN_RIGHT) xpos = x + w - (int)(width + .5) - symwidth[1]; - else xpos = x + (w - (int)(width + .5) - symtotal) / 2 + symwidth[0]; + if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0] + imgw[0]; + else if (align & FL_ALIGN_RIGHT) xpos = x + w - (int)(width + .5) - symwidth[1] - imgw[1]; + else xpos = x + (w - (int)(width + .5) - symtotal - imgw[0] - imgw[1]) / 2 + symwidth[0] + imgw[0]; callthis(buf,buflen,xpos,ypos-desc); @@ -289,7 +320,7 @@ void fl_draw( } // draw the image if the "text over image" alignment flag is set... - if (img && (align & FL_ALIGN_TEXT_OVER_IMAGE)) { + if (img && imgvert && (align & FL_ALIGN_TEXT_OVER_IMAGE)) { if (img->w() > symoffset) symoffset = img->w(); if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0]; @@ -346,12 +377,15 @@ void fl_draw( int x, int y, int w, int h, Fl_Align align, Fl_Image* img, - int draw_symbols) { + int draw_symbols) +{ if ((!str || !*str) && !img) return; if (w && h && !fl_not_clipped(x, y, w, h) && (align & FL_ALIGN_INSIDE)) return; - if (align & FL_ALIGN_CLIP) fl_push_clip(x, y, w, h); + if (align & FL_ALIGN_CLIP) + fl_push_clip(x, y, w, h); fl_draw(str, x, y, w, h, align, fl_draw, img, draw_symbols); - if (align & FL_ALIGN_CLIP) fl_pop_clip(); + if (align & FL_ALIGN_CLIP) + fl_pop_clip(); } /** @@ -448,5 +482,5 @@ int fl_height(int font, int size) { } // -// End of "$Id: fl_draw.cxx 6845 2009-08-28 20:14:41Z greg.ercolano $". +// End of "$Id: fl_draw.cxx 7502 2010-04-14 13:21:10Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_draw_image.cxx b/plugins/zynaddsubfx/fltk/src/fl_draw_image.cxx index 0205ca138..cf527140d 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_draw_image.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_draw_image.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_draw_image.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: fl_draw_image.cxx 7617 2010-05-27 17:20:18Z manolo $" // // Image drawing routines for the Fast Light Tool Kit (FLTK). // @@ -543,17 +543,17 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, } } -void fl_draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){ +void Fl_Graphics_Driver::draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){ innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0); } -void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, +void Fl_Graphics_Driver::draw_image(Fl_Draw_Image_Cb cb, void* data, int x, int y, int w, int h,int d) { innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data); } -void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){ +void Fl_Graphics_Driver::draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){ innards(buf,x,y,w,h,d,l,1,0,0); } -void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, +void Fl_Graphics_Driver::draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int x, int y, int w, int h,int d) { innards(0,x,y,w,h,d,0,1,cb,data); } @@ -572,5 +572,5 @@ void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { #endif // -// End of "$Id: fl_draw_image.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: fl_draw_image.cxx 7617 2010-05-27 17:20:18Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_draw_image_mac.cxx b/plugins/zynaddsubfx/fltk/src/fl_draw_image_mac.cxx index cb8ca0b6f..0dc5e25b2 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_draw_image_mac.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_draw_image_mac.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_draw_image_mac.cxx 6765 2009-04-15 08:35:28Z matt $" +// "$Id: fl_draw_image_mac.cxx 7617 2010-05-27 17:20:18Z manolo $" // // MacOS image drawing code for the Fast Light Tool Kit (FLTK). // @@ -34,6 +34,11 @@ #define MAXBUFFER 0x40000 // 256k +static void dataReleaseCB(void *info, const void *data, size_t size) +{ + delete[] (uchar *)data; +} + /** * draw an image based on the input parameters * @@ -56,7 +61,6 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, { if (!linedelta) linedelta = W*delta; -#if defined(__APPLE_QUARTZ__) const void *array = buf; uchar *tmpBuf = 0; if (cb) { @@ -73,7 +77,17 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, lut = CGColorSpaceCreateDeviceGray(); else lut = CGColorSpaceCreateDeviceRGB(); - CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, linedelta*H, 0L); + // a release callback is necessary when the fl_gc is a print context because the image data + // must be kept until the page is closed. Thus tmpBuf can't be deleted here. It's too early. +#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 + typedef void (*CGDataProviderReleaseDataCallback) ( + void *info, + const void *data, + size_t size + ); +#endif + CGDataProviderReleaseDataCallback releaseCB = ( cb ? dataReleaseCB : NULL); + CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, linedelta*H, releaseCB); CGImageRef img = CGImageCreate( W, H, 8, 8*delta, linedelta, //lut, delta&1?kCGImageAlphaNone:kCGImageAlphaNoneSkipLast, lut, delta&1?kCGImageAlphaNone:kCGImageAlphaLast, @@ -89,9 +103,6 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, } CGColorSpaceRelease(lut); CGDataProviderRelease(src); - if (cb) { - delete[] tmpBuf; - } if (img) return; // else fall through to slow mode // following the very save (and very slow) way to write the image into the give port CGContextSetShouldAntialias(fl_gc, false); @@ -135,22 +146,19 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, } } CGContextSetShouldAntialias(fl_gc, true); -#else -# error : you must define __APPLE_QUARTZ__ -#endif } -void fl_draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){ +void Fl_Graphics_Driver::draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){ innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0); } -void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, +void Fl_Graphics_Driver::draw_image(Fl_Draw_Image_Cb cb, void* data, int x, int y, int w, int h,int d) { innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data); } -void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){ +void Fl_Graphics_Driver::draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){ innards(buf,x,y,w,h,d,l,1,0,0); } -void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, +void Fl_Graphics_Driver::draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int x, int y, int w, int h,int d) { innards(0,x,y,w,h,d,0,1,cb,data); } @@ -161,5 +169,5 @@ void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { } // -// End of "$Id: fl_draw_image_mac.cxx 6765 2009-04-15 08:35:28Z matt $". +// End of "$Id: fl_draw_image_mac.cxx 7617 2010-05-27 17:20:18Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_draw_image_win32.cxx b/plugins/zynaddsubfx/fltk/src/fl_draw_image_win32.cxx index d94e8b3b2..e5eb86012 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_draw_image_win32.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_draw_image_win32.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_draw_image_win32.cxx 6844 2009-08-24 19:55:29Z AlbrechtS $" +// "$Id: fl_draw_image_win32.cxx 7617 2010-05-27 17:20:18Z manolo $" // // WIN32 image drawing code for the Fast Light Tool Kit (FLTK). // @@ -46,6 +46,7 @@ #include #include +#include #include #include @@ -254,21 +255,36 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, } } } - SetDIBitsToDevice(fl_gc, x, y+j-k, w, k, 0, 0, 0, k, - (LPSTR)((uchar*)buffer+(blocking-k)*linesize), - &bmi, + if(Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) { + // if print context, device and logical units are not equal, so SetDIBitsToDevice + // does not do the expected job, whereas StretchDIBits does it. + StretchDIBits(fl_gc, x, y+j-k, w, k, 0, 0, w, k, + (LPSTR)((uchar*)buffer+(blocking-k)*linesize), + &bmi, #if USE_COLORMAP - indexed ? DIB_PAL_COLORS : DIB_RGB_COLORS + indexed ? DIB_PAL_COLORS : DIB_RGB_COLORS #else - DIB_RGB_COLORS + DIB_RGB_COLORS #endif - ); + , SRCCOPY ); + } + else { + SetDIBitsToDevice(fl_gc, x, y+j-k, w, k, 0, 0, 0, k, + (LPSTR)((uchar*)buffer+(blocking-k)*linesize), + &bmi, +#if USE_COLORMAP + indexed ? DIB_PAL_COLORS : DIB_RGB_COLORS +#else + DIB_RGB_COLORS +#endif + ); + } } } static int fl_abs(int v) { return v<0 ? -v : v; } -void fl_draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){ +void Fl_Graphics_Driver::draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){ if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) { d ^= FL_IMAGE_WITH_ALPHA; innards(buf,x,y,w,h,d,l,fl_abs(d),0,0); @@ -277,7 +293,7 @@ void fl_draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){ } } -void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, +void Fl_Graphics_Driver::draw_image(Fl_Draw_Image_Cb cb, void* data, int x, int y, int w, int h,int d) { if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) { d ^= FL_IMAGE_WITH_ALPHA; @@ -287,7 +303,7 @@ void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, } } -void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){ +void Fl_Graphics_Driver::draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){ if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) { d ^= FL_IMAGE_WITH_ALPHA; innards(buf,x,y,w,h,d,l,1,0,0); @@ -296,7 +312,7 @@ void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int } } -void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, +void Fl_Graphics_Driver::draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int x, int y, int w, int h,int d) { if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) { d ^= FL_IMAGE_WITH_ALPHA; @@ -321,5 +337,5 @@ void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { } // -// End of "$Id: fl_draw_image_win32.cxx 6844 2009-08-24 19:55:29Z AlbrechtS $". +// End of "$Id: fl_draw_image_win32.cxx 7617 2010-05-27 17:20:18Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_draw_pixmap.cxx b/plugins/zynaddsubfx/fltk/src/fl_draw_pixmap.cxx index 40f54dacb..c9debb5c6 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_draw_pixmap.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_draw_pixmap.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_draw_pixmap.cxx 6689 2009-03-15 19:38:13Z engelsman $" +// "$Id: fl_draw_pixmap.cxx 7659 2010-07-01 13:21:32Z manolo $" // // Pixmap drawing code for the Fast Light Tool Kit (FLTK). // @@ -139,8 +139,6 @@ struct pixmap_data { }; }; -# ifndef __APPLE_QUARTZ__ - // callback for 1 byte per pixel: static void cb1(void*v, int x, int y, int w, uchar* buf) { pixmap_data& d = *(pixmap_data*)v; @@ -160,8 +158,6 @@ static void cb2(void*v, int x, int y, int w, uchar* buf) { } } -# endif // !__APPLE_QUARTZ__ - #endif // U64 else U32 uchar **fl_mask_bitmap; // if non-zero, create bitmap and store pointer here @@ -179,6 +175,40 @@ int fl_draw_pixmap(/*const*/ char* const* data, int x,int y,Fl_Color bg) { return fl_draw_pixmap((const char*const*)data,x,y,bg); } +#ifdef WIN32 +// to compute an unused color to be used for the pixmap background +FL_EXPORT UINT win_pixmap_bg_color; // the RGB() of the pixmap background color +static int color_count; // # of non-transparent colors used in pixmap +static uchar *used_colors; // used_colors[3*i+j] j=0,1,2 are the RGB values of the ith used color + +static void make_unused_color(uchar &r, uchar &g, uchar &b) +// makes an RGB triplet different from all the colors used in the pixmap +// and compute win_pixmap_bg_color from this triplet +{ + int i; + r = 2; g = 3; b = 4; + while (1) { + for ( i = 0; i < color_count; i++) { + if(used_colors[3*i] == r && used_colors[3*i+1] == g && used_colors[3*i+2] == b) break; + } + if (i >= color_count) { + free(used_colors); + win_pixmap_bg_color = RGB(r, g, b); + return; + } + if (r < 255) r++; + else { + r = 0; + if (g < 255) g++; + else { + g = 0; + b++; + } + } + } +} +#endif + /** Draw XPM image data, with the top-left corner at the given position. \see fl_draw_pixmap(char* const* data, int x, int y, Fl_Color bg) @@ -188,6 +218,11 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) { if (!fl_measure_pixmap(cdata, d.w, d.h)) return 0; const uchar*const* data = (const uchar*const*)(cdata+1); int transparent_index = -1; + uchar *transparent_c = (uchar *)0; // such that transparent_c[0,1,2] are the RGB of the transparent color +#ifdef WIN32 + color_count = 0; + used_colors = (uchar *)malloc(abs(ncolors)*3*sizeof(uchar)); +#endif if (ncolors < 0) { // FLTK (non standard) compressed colormap ncolors = -ncolors; @@ -204,6 +239,7 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) { #endif transparent_index = ' '; Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0; + transparent_c = c; p += 4; ncolors--; } @@ -215,6 +251,12 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) { # if WORDS_BIGENDIAN c += 4; # endif +#endif +#ifdef WIN32 + used_colors[3*color_count] = *p; + used_colors[3*color_count+1] = *(p+1); + used_colors[3*color_count+2] = *(p+2); + color_count++; #endif *c++ = *p++; *c++ = *p++; @@ -266,7 +308,16 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) { #ifdef __APPLE_QUARTZ__ c[3] = 255; #endif - if (!fl_parse_color((const char*)p, c[0], c[1], c[2])) { + int parse = fl_parse_color((const char*)p, c[0], c[1], c[2]); + if (parse) { +#ifdef WIN32 + used_colors[3*color_count] = c[0]; + used_colors[3*color_count+1] = c[1]; + used_colors[3*color_count+2] = c[2]; + color_count++; +#endif + } + else { // assume "None" or "#transparent" for any errors // "bg" should be transparent... Fl::get_color(bg, c[0], c[1], c[2]); @@ -274,12 +325,55 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) { c[3] = 0; #endif transparent_index = ind; + transparent_c = c; } } } d.data = data; - -#ifndef __APPLE_QUARTZ__ +#ifdef WIN32 + if (transparent_c) { + make_unused_color(transparent_c[0], transparent_c[1], transparent_c[2]); + } + else { + uchar r, g, b; + make_unused_color(r, g, b); + } +#endif + +#ifdef __APPLE_QUARTZ__ + if (fl_graphics_driver->type() == Fl_Quartz_Graphics_Driver::device_type ) { + bool transparent = (transparent_index>=0); + transparent = true; + U32 *array = new U32[d.w * d.h], *q = array; + for (int Y = 0; Y < d.h; Y++) { + const uchar* p = data[Y]; + if (chars_per_pixel <= 1) { + for (int X = 0; X < d.w; X++) { + *q++ = d.colors[*p++]; + } + } else { + for (int X = 0; X < d.w; X++) { + U32* colors = (U32*)d.byte1[*p++]; + *q++ = colors[*p++]; + } + } + } + CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); + CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, d.w * d.h * 4, 0L); + CGImageRef img = CGImageCreate(d.w, d.h, 8, 4*8, 4*d.w, + lut, transparent?kCGImageAlphaLast:kCGImageAlphaNoneSkipLast, + src, 0L, false, kCGRenderingIntentDefault); + CGColorSpaceRelease(lut); + CGDataProviderRelease(src); + CGRect rect = { { x, y} , { d.w, d.h } }; + Fl_X::q_begin_image(rect, 0, 0, d.w, d.h); + CGContextDrawImage(fl_gc, rect, img); + Fl_X::q_end_image(); + CGImageRelease(img); + delete array; + } + else { +#endif // __APPLE_QUARTZ__ // build the mask bitmap used by Fl_Pixmap: if (fl_mask_bitmap && transparent_index >= 0) { @@ -322,45 +416,14 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) { } fl_draw_image(chars_per_pixel==1 ? cb1 : cb2, &d, x, y, d.w, d.h, 4); - -#else // __APPLE_QUARTZ__ - - bool transparent = (transparent_index>=0); - transparent = true; - U32 *array = new U32[d.w * d.h], *q = array; - for (int Y = 0; Y < d.h; Y++) { - const uchar* p = data[Y]; - if (chars_per_pixel <= 1) { - for (int X = 0; X < d.w; X++) { - *q++ = d.colors[*p++]; - } - } else { - for (int X = 0; X < d.w; X++) { - U32* colors = d.byte1[*p++]; - *q++ = colors[*p++]; - } +#ifdef __APPLE_QUARTZ__ } - } - CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); - CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, d.w * d.h * 4, 0L); - CGImageRef img = CGImageCreate(d.w, d.h, 8, 4*8, 4*d.w, - lut, transparent?kCGImageAlphaLast:kCGImageAlphaNoneSkipLast, - src, 0L, false, kCGRenderingIntentDefault); - CGColorSpaceRelease(lut); - CGDataProviderRelease(src); - CGRect rect = { { x, y} , { d.w, d.h } }; - Fl_X::q_begin_image(rect, 0, 0, d.w, d.h); - CGContextDrawImage(fl_gc, rect, img); - Fl_X::q_end_image(); - CGImageRelease(img); - delete array; - -#endif // !__APPLE_QUARTZ__ +#endif if (chars_per_pixel > 1) for (int i = 0; i < 256; i++) delete[] d.byte1[i]; return 1; } // -// End of "$Id: fl_draw_pixmap.cxx 6689 2009-03-15 19:38:13Z engelsman $". +// End of "$Id: fl_draw_pixmap.cxx 7659 2010-07-01 13:21:32Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_font_mac.cxx b/plugins/zynaddsubfx/fltk/src/fl_font_mac.cxx index 33af81566..3a07767ce 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_font_mac.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_font_mac.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_font_mac.cxx 6779 2009-04-24 09:28:30Z yuri $" +// "$Id: fl_font_mac.cxx 7659 2010-07-01 13:21:32Z manolo $" // // MacOS font selection routines for the Fast Light Tool Kit (FLTK). // @@ -33,6 +33,9 @@ extern unsigned fl_utf8toUtf16(const char* src, unsigned srclen, unsigned short* // if no font has been selected yet by the user, get one. #define check_default_font() {if (!fl_fontsize) fl_font(0, 12);} +static const CGAffineTransform font_mx = { 1, 0, 0, -1, 0, 0 }; +static SInt32 MACsystemVersion = 0; + Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) { next = 0; # if HAVE_GL @@ -43,13 +46,41 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) { // OpenGL needs those for its font handling q_name = strdup(name); size = Size; + minsize = maxsize = Size; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if(MACsystemVersion == 0) Gestalt(gestaltSystemVersion, &MACsystemVersion); + +if(MACsystemVersion >= 0x1050) {//unfortunately, CTFontCreateWithName != NULL on 10.4 also! + CFStringRef str = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8); + fontref = CTFontCreateWithName(str, size, NULL); + CGGlyph glyph[2]; + const UniChar A[2]={'W','.'}; + CTFontGetGlyphsForCharacters(fontref, A, glyph, 2); + CGSize advances[2]; + double w; + CTFontGetAdvancesForGlyphs(fontref, kCTFontHorizontalOrientation, glyph, advances, 2); + w = advances[0].width; + if( abs(advances[0].width - advances[1].width) < 1E-2 ) {//this is a fixed-width font + //slightly rescale fixed-width fonts so the character width has an integral value + CFRelease(fontref); + CGFloat fsize = size / ( w/floor(w + 0.5) ); + fontref = CTFontCreateWithName(str, fsize, NULL); + w = CTFontGetAdvancesForGlyphs(fontref, kCTFontHorizontalOrientation, glyph, NULL, 1); + } + CFRelease(str); + ascent = (short)(CTFontGetAscent(fontref) + 0.5); + descent = (short)(CTFontGetDescent(fontref) + 0.5); + q_width = w + 0.5; + } +else { +#endif +#if ! __LP64__ OSStatus err; // fill our structure with a few default values ascent = Size*3/4; descent = Size-ascent; q_width = Size*2/3; - minsize = maxsize = Size; - // now use ATS to get the actual Glyph size information + // now use ATS to get the actual Glyph size information // say that our passed-in name is encoded as UTF-8, since this works for plain ASCII names too... CFStringRef cfname = CFStringCreateWithCString(0L, name, kCFStringEncodingUTF8); ATSFontRef font = ATSFontFindFromName(cfname, kATSOptionFlagsDefault); @@ -112,6 +143,10 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) { // cause ATSU to find a suitable font to render any chars the current font can't do... ATSUSetTransientFontMatching (layout, true); # endif +#endif//__LP64__ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + } +#endif } Fl_Font_Descriptor* fl_fontsize = 0L; @@ -132,8 +167,12 @@ Fl_Font_Descriptor::~Fl_Font_Descriptor() { #endif */ if (this == fl_fontsize) fl_fontsize = 0; - ATSUDisposeTextLayout(layout); - ATSUDisposeStyle(style); +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if(MACsystemVersion >= 0x1050) CFRelease(fontref); +#else + /* ATSUDisposeTextLayout(layout); + ATSUDisposeStyle(style); */ +#endif } //////////////////////////////////////////////////////////////// @@ -178,11 +217,7 @@ Fl_Fontdesc* fl_fonts = built_in_table; void fl_font(Fl_Font_Descriptor* s) { fl_fontsize = s; -#if defined(__APPLE_QUARTZ__) // we will use fl_fontsize later to access the required style and layout -#else -# error : need to defined either Quartz or Quickdraw -#endif } static Fl_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size) { @@ -204,7 +239,7 @@ Fl_Font fl_font_ = 0; Fl_Fontsize fl_size_ = 0; -void fl_font(Fl_Font fnum, Fl_Fontsize size) { +void Fl_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) { if (fnum==-1) { fl_font_ = 0; fl_size_ = 0; @@ -235,7 +270,25 @@ double fl_width(const UniChar* txt, int n) { if (!fl_fontsize) return 8*n; // user must select a font first! } - OSStatus err; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +if(MACsystemVersion >= 0x1050) { + CTFontRef fontref = fl_fontsize->fontref; + CFStringRef str = CFStringCreateWithBytes(NULL, (const UInt8*)txt, n * sizeof(UniChar), kCFStringEncodingUTF16, false); + CFAttributedStringRef astr = CFAttributedStringCreate(NULL, str, NULL); + CFMutableAttributedStringRef mastr = CFAttributedStringCreateMutableCopy(NULL, 0, astr); + CFRelease(astr); + CFAttributedStringSetAttribute(mastr, CFRangeMake(0, CFStringGetLength(str)), kCTFontAttributeName, fontref); + CFRelease(str); + CTLineRef ctline = CTLineCreateWithAttributedString(mastr); + CFRelease(mastr); + double retval = CTLineGetTypographicBounds(ctline, NULL, NULL, NULL); + CFRelease(ctline); + return retval; + } +else { +#endif +#if ! __LP64__ + OSStatus err; Fixed bBefore, bAfter, bAscent, bDescent; ATSUTextLayout layout; ByteCount iSize; @@ -256,6 +309,11 @@ double fl_width(const UniChar* txt, int n) { // If err is OK then return length, else return 0. Or something... int len = FixedToInt(bAfter); return len; +#endif +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + } +#endif + return 0; // FIXME: I do not understand the shuffeling of the above ifdef's and why they are here! } double fl_width(const char* txt, int n) { @@ -281,6 +339,30 @@ void fl_text_extents(const UniChar* txt, int n, int &dx, int &dy, int &w, int &h h = 8.0; return; } +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +if(MACsystemVersion >= 0x1050) { + CTFontRef fontref = fl_fontsize->fontref; + CFStringRef str16 = CFStringCreateWithBytes(NULL, (const UInt8*)txt, n *sizeof(UniChar), kCFStringEncodingUTF16, false); + CFAttributedStringRef astr = CFAttributedStringCreate(NULL, str16, NULL); + CFMutableAttributedStringRef mastr = CFAttributedStringCreateMutableCopy(NULL, 0, astr); + CFRelease(astr); + CFAttributedStringSetAttribute(mastr, CFRangeMake(0, CFStringGetLength(str16)), kCTFontAttributeName, fontref); + CFRelease(str16); + CTLineRef ctline = CTLineCreateWithAttributedString(mastr); + CFRelease(mastr); + CGContextSetTextPosition(fl_gc, 0, 0); + CGContextSetShouldAntialias(fl_gc, true); + CGRect rect = CTLineGetImageBounds(ctline, fl_gc); + CGContextSetShouldAntialias(fl_gc, false); + CFRelease(ctline); + dx = floor(rect.origin.x + 0.5); + dy = floor(- rect.origin.y - rect.size.height + 0.5); + w = rect.size.width + 0.5; + h = rect.size.height + 0.5; + } +else { +#endif +#if ! __LP64__ OSStatus err; ATSUTextLayout layout; ByteCount iSize; @@ -304,6 +386,10 @@ void fl_text_extents(const UniChar* txt, int n, int &dx, int &dy, int &w, int &h dx = bbox.left; dy = -bbox.bottom; //printf("r: %d l: %d t: %d b: %d w: %d h: %d\n", bbox.right, bbox.left, bbox.top, bbox.bottom, w, h); +#endif +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + } +#endif return; } // fl_text_extents @@ -316,17 +402,70 @@ void fl_text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { void fl_draw(const char *str, int n, float x, float y); -void fl_draw(const char* str, int n, int x, int y) { - fl_draw(str, n, (float)x-0.0f, (float)y-0.5f); +void Fl_Graphics_Driver::draw(const char* str, int n, int x, int y) { + fl_draw(str, n, (float)x-0.0f, (float)y+0.5f); +} + + +static CGColorRef flcolortocgcolor(Fl_Color i) +{ + uchar r, g, b; + Fl::get_color(i, r, g, b); + CGFloat components[4] = {r/255.0f, g/255.0f, b/255.0f, 1.}; + static CGColorSpaceRef cspace = NULL; + if(cspace == NULL) { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + cspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); +#else + cspace = CGColorSpaceCreateWithName(kCGColorSpaceUserRGB); +#endif + } + return CGColorCreate(cspace, components); } void fl_draw(const char *str, int n, float x, float y) { - OSStatus err; - // convert to UTF-16 first - UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n); + if(fl_graphics_driver->type() != Fl_Quartz_Graphics_Driver::device_type) { + fl_graphics_driver->draw(str, n, (int)x, (int)y ); + return; + } // avoid a crash if no font has been selected by user yet ! check_default_font(); + // convert to UTF-16 first + UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n); +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if(MACsystemVersion >= 0x1050) { + CFStringRef keys[2]; + CFTypeRef values[2]; + CFStringRef str16 = CFStringCreateWithBytes(NULL, (const UInt8*)uniStr, n * sizeof(UniChar), kCFStringEncodingUTF16, false); + CGColorRef color = flcolortocgcolor(fl_color()); + keys[0] = kCTFontAttributeName; + keys[1] = kCTForegroundColorAttributeName; + values[0] = fl_fontsize->fontref; + values[1] = color; + CFDictionaryRef attributes = CFDictionaryCreate(kCFAllocatorDefault, + (const void**)&keys, + (const void**)&values, + 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, str16, attributes); + CFRelease(str16); + CFRelease(attributes); + CFRelease(color); + CTLineRef ctline = CTLineCreateWithAttributedString(mastr); + CFRelease(mastr); + CGContextSetTextMatrix(fl_gc, font_mx); + CGContextSetTextPosition(fl_gc, x, y); + CGContextSetShouldAntialias(fl_gc, true); + CTLineDraw(ctline, fl_gc); + CGContextSetShouldAntialias(fl_gc, false); + CFRelease(ctline); + } + else { +#endif +#if ! __LP64__ + OSStatus err; // now collect our ATSU resources ATSUTextLayout layout = fl_fontsize->layout; @@ -336,51 +475,27 @@ void fl_draw(const char *str, int n, float x, float y) { ATSUSetLayoutControls(layout, 1, &iTag, &iSize, &iValuePtr); err = ATSUSetTextPointerLocation(layout, uniStr, kATSUFromTextBeginning, n, n); + CGContextSetShouldAntialias(fl_gc, true); err = ATSUDrawText(layout, kATSUFromTextBeginning, n, FloatToFixed(x), FloatToFixed(y)); + CGContextSetShouldAntialias(fl_gc, false); +#endif +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + } +#endif } -void fl_draw(int angle, const char *str, int n, int x, int y) { - OSStatus err; - // convert to UTF-16 first - UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n); - - // avoid a crash if no font has been selected by user yet ! - check_default_font(); - // now collect our ATSU resources - ATSUTextLayout layout = fl_fontsize->layout; - - Fixed ang = IntToFixed(-angle); - ByteCount iSize[] = {sizeof(Fixed), sizeof(CGContextRef)}; - ATSUAttributeTag iTag[] = {kATSULineRotationTag, kATSUCGContextTag}; - ATSUAttributeValuePtr aAttr[] = { &ang, &fl_gc}; - ATSUSetLayoutControls(layout, 2, iTag, iSize, aAttr); - - err = ATSUSetTextPointerLocation(layout, uniStr, kATSUFromTextBeginning, n, n); - err = ATSUDrawText(layout, kATSUFromTextBeginning, n, FloatToFixed(x), FloatToFixed(y)); - //restore layout baseline - ang = IntToFixed(0); - ATSUSetLayoutControls(layout, 2, iTag, iSize, aAttr); +void Fl_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) { + CGContextSaveGState(fl_gc); + CGContextTranslateCTM(fl_gc, x, y); + CGContextRotateCTM(fl_gc, - angle*(M_PI/180) ); + fl_draw(str, n, (float)0., (float)0.); + CGContextRestoreGState(fl_gc); } -void fl_rtl_draw(const char* c, int n, int x, int y) { -// I guess with ATSU the thing to do is force the layout mode to RTL and let ATSU draw the text... - double offs = fl_width(c, n); - OSStatus err; - // convert to UTF-16 first - UniChar *uniStr = mac_Utf8_to_Utf16(c, n, &n); - // now collect our ATSU resources - ATSUTextLayout layout = fl_fontsize->layout; - // reverse the layout direction - ATSUAttributeTag llo = kATSURightToLeftBaseDirection; // layout option - ByteCount iSize[] = {sizeof(ATSUAttributeTag), sizeof(CGContextRef)}; - ATSUAttributeTag iTag[] = {kATSULineDirectionTag, kATSUCGContextTag}; - ATSUAttributeValuePtr aAttr[] = { &llo, &fl_gc}; - ATSUSetLayoutControls (layout, 2, iTag, iSize, aAttr ); - - err = ATSUSetTextPointerLocation(layout, uniStr, kATSUFromTextBeginning, n, n); - err = ATSUDrawText(layout, kATSUFromTextBeginning, n, FloatToFixed(x-offs), FloatToFixed(y)); +void Fl_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) { + draw(c, n, x - fl_width(c, n), y); } // -// End of "$Id: fl_font_mac.cxx 6779 2009-04-24 09:28:30Z yuri $". +// End of "$Id: fl_font_mac.cxx 7659 2010-07-01 13:21:32Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_font_win32.cxx b/plugins/zynaddsubfx/fltk/src/fl_font_win32.cxx index fc708a8ca..81a7c015b 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_font_win32.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_font_win32.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_font_win32.cxx 6779 2009-04-24 09:28:30Z yuri $" +// "$Id: fl_font_win32.cxx 7652 2010-06-21 15:49:45Z manolo $" // // WIN32 font selection routines for the Fast Light Tool Kit (FLTK). // @@ -24,6 +24,9 @@ // // http://www.fltk.org/str.php // + +#include + static int fl_angle_ = 0; #ifndef FL_DOXYGEN @@ -143,7 +146,7 @@ void fl_font(Fl_Font fnum, Fl_Fontsize size, int angle) { fl_fontsize = find(fnum, size, angle); } -void fl_font(Fl_Font fnum, Fl_Fontsize size) { +void Fl_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) { fl_font(fnum, size, 0); } @@ -234,6 +237,21 @@ static void GetGlyphIndices_init() { have_loaded_GetGlyphIndices = -1; // set this non-zero when we have attempted to load GetGlyphIndicesW } // GetGlyphIndices_init function +static void on_printer_extents_update(int &dx, int &dy, int &w, int &h) +// converts text extents from device coords to logical coords +{ + POINT pt[3] = { {0, 0}, {dx, dy}, {dx+w, dy+h} }; + DPtoLP(fl_gc, pt, 3); + w = pt[2].x - pt[1].x; + h = pt[2].y - pt[1].y; + dx = pt[1].x - pt[0].x; + dy = pt[1].y - pt[0].y; +} + +// if printer context, extents shd be converted to logical coords +#define EXTENTS_UPDATE(x,y,w,h) \ + if (Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) { on_printer_extents_update(x,y,w,h); } + static unsigned short *ext_buff = NULL; // UTF-16 converted version of input UTF-8 string static unsigned wc_len = 0; // current string buffer dimension static WORD *gi = NULL; // glyph indices array @@ -303,6 +321,7 @@ void fl_text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { h = maxh + miny; dx = minx; dy = -miny; + EXTENTS_UPDATE(dx, dy, w, h); return; // normal exit exit_error: @@ -311,10 +330,11 @@ exit_error: h = fl_height(); dx = 0; dy = fl_descent() - h; + EXTENTS_UPDATE(dx, dy, w, h); return; } // fl_text_extents -void fl_draw(const char* str, int n, int x, int y) { +void Fl_Graphics_Driver::draw(const char* str, int n, int x, int y) { int i = 0; int lx = 0; char *end = (char *)&str[n]; @@ -342,7 +362,7 @@ void fl_draw(const char* str, int n, int x, int y) { SetTextColor(fl_gc, oldColor); } -void fl_draw(int angle, const char* str, int n, int x, int y) { +void Fl_Graphics_Driver::draw(int angle, const char* str, int n, int x, int y) { fl_font(fl_font_, fl_size_, angle); // fl_draw(str, n, (int)x, (int)y); int i = 0, i2=0; @@ -366,7 +386,7 @@ void fl_draw(int angle, const char* str, int n, int x, int y) { fl_font(fl_font_, fl_size_); } -void fl_rtl_draw(const char* c, int n, int x, int y) { +void Fl_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) { int wn; int i = 0; int lx = 0; @@ -397,5 +417,5 @@ void fl_rtl_draw(const char* c, int n, int x, int y) { } #endif // -// End of "$Id: fl_font_win32.cxx 6779 2009-04-24 09:28:30Z yuri $". +// End of "$Id: fl_font_win32.cxx 7652 2010-06-21 15:49:45Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_font_x.cxx b/plugins/zynaddsubfx/fltk/src/fl_font_x.cxx index 4520ae981..52f30a3d3 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_font_x.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_font_x.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_font_x.cxx 6779 2009-04-24 09:28:30Z yuri $" +// "$Id: fl_font_x.cxx 7652 2010-06-21 15:49:45Z manolo $" // // Standard X11 font selection code for the Fast Light Tool Kit (FLTK). // @@ -39,6 +39,7 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name) { } Fl_Font_Descriptor* fl_fontsize; +Fl_XFont_On_Demand fl_xfont; Fl_Font_Descriptor::~Fl_Font_Descriptor() { # if HAVE_GL @@ -52,7 +53,10 @@ Fl_Font_Descriptor::~Fl_Font_Descriptor() { // glDeleteLists(listbase+base,size); // } # endif - if (this == fl_fontsize) fl_fontsize = 0; + if (this == fl_fontsize) { + fl_fontsize = 0; + fl_xfont = 0; + } XFreeUtf8FontStruct(fl_display, font); } @@ -83,6 +87,8 @@ Fl_Fontdesc* fl_fonts = built_in_table; #define MAXSIZE 32767 +#define current_font (fl_fontsize->font) + // return dash number N, or pointer to ending null if none: const char* fl_font_word(const char* p, int n) { while (*p) {if (*p=='-') {if (!--n) break;} p++;} @@ -256,12 +262,14 @@ static Fl_Font_Descriptor* find(int fnum, int size) { Fl_Font fl_font_ = 0; Fl_Fontsize fl_size_ = 0; -//XFontStruct* fl_xfont = 0; -XUtf8FontStruct* fl_xfont; void *fl_xftfont = 0; static GC font_gc; -void fl_font(Fl_Font fnum, Fl_Fontsize size) { +XFontStruct* Fl_XFont_On_Demand::value() { + return ptr; +} + +void Fl_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) { if (fnum==-1) { fl_font_ = 0; fl_size_ = 0; return; @@ -271,28 +279,28 @@ void fl_font(Fl_Font fnum, Fl_Fontsize size) { Fl_Font_Descriptor* f = find(fnum, size); if (f != fl_fontsize) { fl_fontsize = f; - fl_xfont = f->font; + fl_xfont = current_font->fonts[0]; font_gc = 0; } } int fl_height() { - if (fl_xfont) return (fl_xfont->ascent + fl_xfont->descent); + if (current_font) return (current_font->ascent + current_font->descent); else return -1; } int fl_descent() { - if (fl_xfont) return fl_xfont->descent; + if (current_font) return current_font->descent; else return -1; } double fl_width(const char* c, int n) { - if (fl_xfont) return (double) XUtf8TextWidth(fl_xfont, c, n); + if (current_font) return (double) XUtf8TextWidth(current_font, c, n); else return -1; } double fl_width(unsigned int c) { - if (fl_xfont) return (double) XUtf8UcsWidth(fl_xfont, c); + if (current_font) return (double) XUtf8UcsWidth(current_font, c); else return -1; } @@ -310,16 +318,16 @@ void fl_text_extents(const char *c, int n, int &dx, int &dy, int &W, int &H) { } // fl_text_extents -void fl_draw(const char* c, int n, int x, int y) { +void Fl_Graphics_Driver::draw(const char* c, int n, int x, int y) { if (font_gc != fl_gc) { - if (!fl_xfont) fl_font(FL_HELVETICA, 14); + if (!current_font) fl_font(FL_HELVETICA, 14); font_gc = fl_gc; - XSetFont(fl_display, fl_gc, fl_xfont->fid); + XSetFont(fl_display, fl_gc, current_font->fid); } // XDrawString(fl_display, fl_window, fl_gc, x, y, c, n); - XUtf8DrawString(fl_display, fl_window, fl_xfont, fl_gc, x, y, c, n); + XUtf8DrawString(fl_display, fl_window, current_font, fl_gc, x, y, c, n); } -void fl_draw(int angle, const char *str, int n, int x, int y) { +void Fl_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) { fprintf(stderr,"ROTATING TEXT NOT IMPLIMENTED\n"); fl_draw(str, n, (int)x, (int)y); } @@ -327,14 +335,14 @@ void fl_draw(int angle, const char *str, int n, int x, int y) { // fl_draw(str, n, (int)x, (int)y); //} -void fl_rtl_draw(const char* c, int n, int x, int y) { +void Fl_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) { if (font_gc != fl_gc) { - if (!fl_xfont) fl_font(FL_HELVETICA, 12); + if (!current_font) fl_font(FL_HELVETICA, 12); font_gc = fl_gc; } - XUtf8DrawRtlString(fl_display, fl_window, fl_xfont, fl_gc, x, y, c, n); + XUtf8DrawRtlString(fl_display, fl_window, current_font, fl_gc, x, y, c, n); } #endif // FL_DOXYGEN // -// End of "$Id: fl_font_x.cxx 6779 2009-04-24 09:28:30Z yuri $". +// End of "$Id: fl_font_x.cxx 7652 2010-06-21 15:49:45Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_font_xft.cxx b/plugins/zynaddsubfx/fltk/src/fl_font_xft.cxx index a7d43fcd4..cf8764751 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_font_xft.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_font_xft.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_font_xft.cxx 6862 2009-09-13 10:15:42Z matt $" +// "$Id: fl_font_xft.cxx 7652 2010-06-21 15:49:45Z manolo $" // // Xft font code for the Fast Light Tool Kit (FLTK). // @@ -94,8 +94,7 @@ Fl_Fontdesc* fl_fonts = built_in_table; Fl_Font fl_font_ = 0; Fl_Fontsize fl_size_ = 0; int fl_angle_ = 0; // internal for rotating text support -//XFontStruct* fl_xfont = 0; -XUtf8FontStruct* fl_xfont = 0; +Fl_XFont_On_Demand fl_xfont; void *fl_xftfont = 0; //const char* fl_encoding_ = "iso8859-1"; const char* fl_encoding_ = "iso10646-1"; @@ -134,7 +133,7 @@ void fl_font(Fl_Font fnum, Fl_Fontsize size, int angle) { fl_xftfont = (void*)f->font; } -void fl_font(Fl_Font fnum, Fl_Fontsize size) { +void Fl_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) { fl_font(fnum,size,0); } @@ -374,17 +373,16 @@ void fl_text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { } // fl_text_extents -#if HAVE_GL -/* This code is used by opengl to get a bitmapped font. The original XFT-1 code - * used XFT's "core" fonts methods to load an XFT font that was actually a - * X-bitmap font, that could then be readily used with GL. - * But XFT-2 does not provide that ability, and there is no easy method to use - * an XFT font directly with GL. So... +/* This code is used (mainly by opengl) to get a bitmapped font. The + * original XFT-1 code used XFT's "core" fonts methods to load an XFT + * font that was actually a X-bitmap font, that could then be readily + * used with GL. But XFT-2 does not provide that ability, and there + * is no easy method to use an XFT font directly with GL. So... */ # if XFT_MAJOR > 1 // This function attempts, on XFT2 systems, to find a suitable "core" Xfont -// for GL to use, since we dont have an XglUseXftFont(...) function. +// for GL or other bitmap font needs (we dont have an XglUseXftFont(...) function.) // There's probably a better way to do this. I can't believe it is this hard... // Anyway... This code attempts to make an XLFD out of the fltk-style font // name it is passed, then tries to load that font. Surprisingly, this quite @@ -394,8 +392,8 @@ void fl_text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { // If this code fails to load the requested font, it falls back through a // series of tried 'n tested alternatives, ultimately resorting to what the // original fltk code did. -// NOTE: On my test boxes (FC6, FC7, FC8, ubuntu8.04) this works well for the -// fltk "built-in" font names. +// NOTE: On my test boxes (FC6, FC7, FC8, ubuntu8.04, 9.04, 9.10) this works +// well for the fltk "built-in" font names. static XFontStruct* load_xfont_for_xft2(void) { XFontStruct* xgl_font = 0; int size = fl_size_; @@ -483,7 +481,11 @@ XFontStruct* fl_xxfont() { return xftfont->u.core.font; # endif // XFT_MAJOR > 1 } -#endif // HAVE_GL + +XFontStruct* Fl_XFont_On_Demand::value() { + if (!ptr) ptr = fl_xxfont(); + return ptr; +} #if USE_OVERLAY // Currently Xft does not work with colormapped visuals, so this probably @@ -497,7 +499,7 @@ extern XVisualInfo* fl_overlay_visual; // still exists in an XftDraw structure. It would be nice if this is not // true, a lot of junk is needed to try to stop this: -static XftDraw* draw; +static XftDraw* draw_; static Window draw_window; #if USE_OVERLAY static XftDraw* draw_overlay; @@ -506,36 +508,36 @@ static Window draw_overlay_window; void fl_destroy_xft_draw(Window id) { if (id == draw_window) - XftDrawChange(draw, draw_window = fl_message_window); + XftDrawChange(draw_, draw_window = fl_message_window); #if USE_OVERLAY if (id == draw_overlay_window) XftDrawChange(draw_overlay, draw_overlay_window = fl_message_window); #endif } -void fl_draw(const char *str, int n, int x, int y) { +void Fl_Graphics_Driver::draw(const char *str, int n, int x, int y) { if ( !current_font ) { fl_font(FL_HELVETICA, 14); } #if USE_OVERLAY - XftDraw*& draw = fl_overlay ? draw_overlay : ::draw; + XftDraw*& draw_ = fl_overlay ? draw_overlay : ::draw_; if (fl_overlay) { - if (!draw) - draw = XftDrawCreate(fl_display, draw_overlay_window = fl_window, + if (!draw_) + draw_ = XftDrawCreate(fl_display, draw_overlay_window = fl_window, fl_overlay_visual->visual, fl_overlay_colormap); else //if (draw_overlay_window != fl_window) - XftDrawChange(draw, draw_overlay_window = fl_window); + XftDrawChange(draw_, draw_overlay_window = fl_window); } else #endif - if (!draw) - draw = XftDrawCreate(fl_display, draw_window = fl_window, + if (!draw_) + draw_ = XftDrawCreate(fl_display, draw_window = fl_window, fl_visual->visual, fl_colormap); else //if (draw_window != fl_window) - XftDrawChange(draw, draw_window = fl_window); + XftDrawChange(draw_, draw_window = fl_window); Region region = fl_clip_region(); if (region && XEmptyRegion(region)) return; - XftDrawSetClip(draw, region); + XftDrawSetClip(draw_, region); // Use fltk's color allocator, copy the results to match what // XftCollorAllocValue returns: @@ -547,10 +549,10 @@ void fl_draw(const char *str, int n, int x, int y) { color.color.blue = ((int)b)*0x101; color.color.alpha = 0xffff; - XftDrawStringUtf8(draw, &color, current_font, x, y, (XftChar8 *)str, n); + XftDrawStringUtf8(draw_, &color, current_font, x, y, (XftChar8 *)str, n); } -void fl_draw(int angle, const char *str, int n, int x, int y) { +void Fl_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) { fl_font(fl_font_, fl_size_, angle); fl_draw(str, n, (int)x, (int)y); fl_font(fl_font_, fl_size_); @@ -562,24 +564,24 @@ void fl_draw(const char* str, int n, float x, float y) { static void fl_drawUCS4(const FcChar32 *str, int n, int x, int y) { #if USE_OVERLAY - XftDraw*& draw = fl_overlay ? draw_overlay : ::draw; + XftDraw*& draw_ = fl_overlay ? draw_overlay : ::draw_; if (fl_overlay) { - if (!draw) - draw = XftDrawCreate(fl_display, draw_overlay_window = fl_window, + if (!draw_) + draw_ = XftDrawCreate(fl_display, draw_overlay_window = fl_window, fl_overlay_visual->visual, fl_overlay_colormap); else //if (draw_overlay_window != fl_window) - XftDrawChange(draw, draw_overlay_window = fl_window); + XftDrawChange(draw_, draw_overlay_window = fl_window); } else #endif - if (!draw) - draw = XftDrawCreate(fl_display, draw_window = fl_window, + if (!draw_) + draw_ = XftDrawCreate(fl_display, draw_window = fl_window, fl_visual->visual, fl_colormap); else //if (draw_window != fl_window) - XftDrawChange(draw, draw_window = fl_window); + XftDrawChange(draw_, draw_window = fl_window); Region region = fl_clip_region(); if (region && XEmptyRegion(region)) return; - XftDrawSetClip(draw, region); + XftDrawSetClip(draw_, region); // Use fltk's color allocator, copy the results to match what // XftCollorAllocValue returns: @@ -591,11 +593,11 @@ static void fl_drawUCS4(const FcChar32 *str, int n, int x, int y) { color.color.blue = ((int)b)*0x101; color.color.alpha = 0xffff; - XftDrawString32(draw, &color, current_font, x, y, (FcChar32 *)str, n); + XftDrawString32(draw_, &color, current_font, x, y, (FcChar32 *)str, n); } -void fl_rtl_draw(const char* c, int n, int x, int y) { +void Fl_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) { #if defined(__GNUC__) #warning Need to improve this XFT right to left draw function @@ -635,5 +637,5 @@ void fl_rtl_draw(const char* c, int n, int x, int y) { #endif // -// End of "$Id: fl_font_xft.cxx 6862 2009-09-13 10:15:42Z matt $" +// End of "$Id: fl_font_xft.cxx 7652 2010-06-21 15:49:45Z manolo $" // diff --git a/plugins/zynaddsubfx/fltk/src/fl_line_style.cxx b/plugins/zynaddsubfx/fltk/src/fl_line_style.cxx index 41d22ce98..39c661e1f 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_line_style.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_line_style.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_line_style.cxx 6716 2009-03-24 01:40:44Z fabien $" +// "$Id: fl_line_style.cxx 7644 2010-06-15 21:16:27Z manolo $" // // Line style code for the Fast Light Tool Kit (FLTK). // @@ -33,6 +33,7 @@ #include #include #include +#include #include "flstring.h" #include @@ -40,7 +41,7 @@ float fl_quartz_line_width_ = 1.0f; static enum CGLineCap fl_quartz_line_cap_ = kCGLineCapButt; static enum CGLineJoin fl_quartz_line_join_ = kCGLineJoinMiter; -static float *fl_quartz_line_pattern = 0; +static CGFloat *fl_quartz_line_pattern = 0; static int fl_quartz_line_pattern_size = 0; void fl_quartz_restore_line_style_() { CGContextSetLineWidth(fl_gc, fl_quartz_line_width_); @@ -50,34 +51,7 @@ void fl_quartz_restore_line_style_() { } #endif -/** - Sets how to draw lines (the "pen"). - If you change this it is your responsibility to set it back to the default - using \c fl_line_style(0). - - \param[in] style A bitmask which is a bitwise-OR of a line style, a cap - style, and a join style. If you don't specify a dash type you - will get a solid line. If you don't specify a cap or join type - you will get a system-defined default of whatever value is - fastest. - \param[in] width The thickness of the lines in pixels. Zero results in the - system defined default, which on both X and Windows is somewhat - different and nicer than 1. - \param[in] dashes A pointer to an array of dash lengths, measured in pixels. - The first location is how long to draw a solid portion, the next - is how long to draw the gap, then the solid, etc. It is terminated - with a zero-length entry. A \c NULL pointer or a zero-length - array results in a solid line. Odd array sizes are not supported - and result in undefined behavior. - - \note Because of how line styles are implemented on Win32 systems, - you \e must set the line style \e after setting the drawing - color. If you set the color after the line style you will lose - the line style settings. - \note The \p dashes array does not work under Windows 95, 98 or Me, - since those operating systems do not support complex line styles. -*/ -void fl_line_style(int style, int width, char* dashes) { +void Fl_Graphics_Driver::line_style(int style, int width, char* dashes) { #if defined(USE_X11) int ndashes = dashes ? strlen(dashes) : 0; @@ -143,11 +117,15 @@ void fl_line_style(int style, int width, char* dashes) { if (width<1) width = 1; fl_quartz_line_width_ = (float)width; fl_quartz_line_cap_ = Cap[(style>>8)&3]; + // when printing kCGLineCapSquare seems better for solid lines + if ( Fl_Surface_Device::surface()->type() == Fl_Printer::device_type && style == FL_SOLID && dashes == NULL ) { + fl_quartz_line_cap_ = kCGLineCapSquare; + } fl_quartz_line_join_ = Join[(style>>12)&3]; char *d = dashes; - static float pattern[16]; + static CGFloat pattern[16]; if (d && *d) { - float *p = pattern; + CGFloat *p = pattern; while (*d) { *p++ = (float)*d++; } fl_quartz_line_pattern = pattern; fl_quartz_line_pattern_size = d-dashes; @@ -162,7 +140,7 @@ void fl_line_style(int style, int width, char* dashes) { dash = char(3*width); dot = gap = char(width); } - float *p = pattern; + CGFloat *p = pattern; switch (style & 0xff) { case FL_DASH: *p++ = dash; *p++ = gap; break; case FL_DOT: *p++ = dot; *p++ = gap; break; @@ -172,7 +150,8 @@ void fl_line_style(int style, int width, char* dashes) { fl_quartz_line_pattern_size = p-pattern; fl_quartz_line_pattern = pattern; } else { - fl_quartz_line_pattern = 0; fl_quartz_line_pattern_size = 0; + fl_quartz_line_pattern = 0; + fl_quartz_line_pattern_size = 0; } fl_quartz_restore_line_style_(); #else @@ -182,5 +161,5 @@ void fl_line_style(int style, int width, char* dashes) { // -// End of "$Id: fl_line_style.cxx 6716 2009-03-24 01:40:44Z fabien $". +// End of "$Id: fl_line_style.cxx 7644 2010-06-15 21:16:27Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_open_uri.cxx b/plugins/zynaddsubfx/fltk/src/fl_open_uri.cxx index cec2a2584..b04443d96 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_open_uri.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_open_uri.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_open_uri.cxx 6901 2009-09-26 13:56:04Z matt $" +// "$Id: fl_open_uri.cxx 6986 2010-01-01 18:30:49Z greg.ercolano $" // // fl_open_uri() code for FLTK. // @@ -72,6 +72,18 @@ static int run_program(const char *program, char **argv, char *msg, int msglen); * * On failure, the msg buffer is filled with an English error message. * + * \b Example + * \code + * #include + * [..] + * char errmsg[512]; + * if ( !fl_open_uri("http://google.com/", errmsg, sizeof(errmsg)) ) { + * char warnmsg[768]; + * sprintf(warnmsg, "Error: %s", errmsg); + * fl_alert(warnmsg); + * } + * \endcode + * * @param uri The URI to open * @param msg Optional buffer which contains the command or error message * @param msglen Length of optional buffer @@ -365,5 +377,5 @@ int main(int argc, char **argv) { // -// End of "$Id: fl_open_uri.cxx 6901 2009-09-26 13:56:04Z matt $". +// End of "$Id: fl_open_uri.cxx 6986 2010-01-01 18:30:49Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_read_image_mac.cxx b/plugins/zynaddsubfx/fltk/src/fl_read_image_mac.cxx index a0ba69ca8..00e9a4f9e 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_read_image_mac.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_read_image_mac.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_read_image_mac.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: fl_read_image_mac.cxx 7670 2010-07-09 17:29:35Z manolo $" // // WIN32 image reading routines for the Fast Light Tool Kit (FLTK). // @@ -26,12 +26,10 @@ // #include - -// warning: this function is only implemented in Quickdraw. The function -// below may not work If FLTK is compiled with Quartz enabled +extern unsigned char *MACbitmapFromRectOfWindow(Fl_Window *win, int x, int y, int w, int h, int *bytesPerPixel); // -// 'fl_read_image()' - Read an image from the current window. +// 'fl_read_image()' - Read an image from the current window or off-screen buffer. // uchar * // O - Pixel buffer or NULL if failed @@ -41,97 +39,45 @@ fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate int w, // I - Width of area to read int h, // I - Height of area to read int alpha) { // I - Alpha value for image (0 for none) - Rect src, // Source rectangle - dst; // Destination rectangle - GWorldPtr osbuffer; // Temporary off-screen buffer for copy - GrafPtr srcPort; // Source port - RGBColor rgb; // RGB colors for copy mask... - PixMapHandle pm; // Pixmap handle for off-screen buffer - uchar *base, // Base address of off-screen buffer - *psrc, // Pointer into off-screen buffer - *pdst; // Pointer into pixel buffer - int idx, idy; // Current X & Y in image - int d; // Depth of image - int rowBytes; // Number of bytes per row... - - // Set the source and destination rectangles... - src.top = y; - src.left = x; - src.bottom = y + h; - src.right = x + w; - - dst.top = 0; - dst.left = 0; - dst.bottom = h; - dst.right = w; - - // Get an off-screen buffer for copying the image... - QDErr err = NewGWorld(&osbuffer, 0, &dst, 0L, 0L, 0); - if (!osbuffer) return 0; - if (err!=noErr) { - DisposeGWorld(osbuffer); - return 0; - } - - // Get the source port... - GetPort(&srcPort); - - // Set the RGB copy mask via the foreground/background colors... - rgb.red = 0xffff; - rgb.green = 0xffff; - rgb.blue = 0xffff; - RGBBackColor(&rgb); - - rgb.red = 0x0000; - rgb.green = 0x0000; - rgb.blue = 0x0000; - RGBForeColor(&rgb); - - // Copy the screen image to the off-screen buffer... - CopyBits(GetPortBitMapForCopyBits(srcPort), - GetPortBitMapForCopyBits(osbuffer), &src, &dst, srcCopy, 0L); - + uchar *base; + int rowBytes, delta; + if(fl_window == NULL) { // reading from an offscreen buffer + CGContextRef src = (CGContextRef)fl_gc; // get bitmap context + base = (uchar *)CGBitmapContextGetData(src); // get data + if(!base) return NULL; + int sw = CGBitmapContextGetWidth(src); + int sh = CGBitmapContextGetHeight(src); + rowBytes = CGBitmapContextGetBytesPerRow(src); + delta = CGBitmapContextGetBitsPerPixel(src)/8; + if( (sw - x < w) || (sh - y < h) ) return NULL; + } + else { // reading from current window + Fl_Window *window = Fl_Window::current(); + while(window->window()) window = window->window(); + base = MACbitmapFromRectOfWindow(window,x,y,w,h,&delta); + rowBytes = delta*w; + x = y = 0; + } // Allocate the image data array as needed... - d = alpha ? 4 : 3; - + int d = alpha ? 4 : 3; if (!p) p = new uchar[w * h * d]; - // Initialize the default colors/alpha in the whole image... memset(p, alpha, w * h * d); - - // Set the correct port for the off-screen buffer and lock the buffer - SetGWorld(osbuffer, 0); - - pm = GetGWorldPixMap(osbuffer); - LockPixels(pm); - - base = (uchar *)GetPixBaseAddr(pm); - rowBytes = (*pm)->rowBytes & 0x3fff; - // Copy the image from the off-screen buffer to the memory buffer. - for (idy = 0, pdst = p; idy < h; idy ++) -#ifdef __i386__ - for (idx = 0, psrc = base + idy * rowBytes; idx < w; idx ++, psrc += 4, pdst += d) { - pdst[0] = psrc[2]; - pdst[1] = psrc[1]; - pdst[2] = psrc[0]; + int idx, idy; // Current X & Y in image + uchar *pdst, *psrc; + for (idy = y, pdst = p; idy < h + y; idy ++) { + for (idx = 0, psrc = base + idy * rowBytes + x * delta; idx < w; idx ++, psrc += delta, pdst += d) { + pdst[0] = psrc[0]; // R + pdst[1] = psrc[1]; // G + pdst[2] = psrc[2]; // B } -#else - for (idx = 0, psrc = base + idy * rowBytes + 1; idx < w; idx ++, psrc += 4, pdst += d) { - pdst[0] = psrc[0]; - pdst[1] = psrc[1]; - pdst[2] = psrc[2]; - } -#endif // __i386__ - // Unlock and delete the off-screen buffer, then return... - UnlockPixels(pm); - DisposeGWorld(osbuffer); - - SetPort(srcPort); + } + if(fl_window != NULL) delete base; return p; } // -// End of "$Id: fl_read_image_mac.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: fl_read_image_mac.cxx 7670 2010-07-09 17:29:35Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_rect.cxx b/plugins/zynaddsubfx/fltk/src/fl_rect.cxx index 3b00deb05..3a9b470a4 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_rect.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_rect.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_rect.cxx 6755 2009-04-12 13:48:03Z matt $" +// "$Id: fl_rect.cxx 7617 2010-05-27 17:20:18Z manolo $" // // Rectangle drawing routines for the Fast Light Tool Kit (FLTK). // @@ -38,17 +38,17 @@ #include #include #include +#include #include #include #ifdef __APPLE_QUARTZ__ extern float fl_quartz_line_width_; +#define USINGQUARTZPRINTER (Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) #endif -/** - Draws a 1-pixel border \e inside the given bounding box -*/ -void fl_rect(int x, int y, int w, int h) { +void Fl_Graphics_Driver::rect(int x, int y, int w, int h) { + if (w<=0 || h<=0) return; #if defined(USE_X11) XDrawRectangle(fl_display, fl_window, fl_gc, x, y, w-1, h-1); @@ -59,19 +59,16 @@ void fl_rect(int x, int y, int w, int h) { LineTo(fl_gc, x, y+h-1); LineTo(fl_gc, x, y); #elif defined(__APPLE_QUARTZ__) - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); CGRect rect = CGRectMake(x, y, w-1, h-1); CGContextStrokeRect(fl_gc, rect); - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); #else # error unsupported platform #endif } -/** - Colors a rectangle that exactly fills the given bounding box -*/ -void fl_rectf(int x, int y, int w, int h) { +void Fl_Graphics_Driver::rectf(int x, int y, int w, int h) { if (w<=0 || h<=0) return; #if defined(USE_X11) if (w && h) XFillRectangle(fl_display, fl_window, fl_gc, x, y, w, h); @@ -81,38 +78,32 @@ void fl_rectf(int x, int y, int w, int h) { rect.right = x + w; rect.bottom = y + h; FillRect(fl_gc, &rect, fl_brush()); #elif defined(__APPLE_QUARTZ__) - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); CGRect rect = CGRectMake(x, y, w-1, h-1); CGContextFillRect(fl_gc, rect); - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); #else # error unsupported platform #endif } -/** - Draws a horizontal line from (x,y) to (x1,y) -*/ -void fl_xyline(int x, int y, int x1) { +void Fl_Graphics_Driver::xyline(int x, int y, int x1) { #if defined(USE_X11) XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y); #elif defined(WIN32) MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x1+1, y); #elif defined(__APPLE_QUARTZ__) - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); CGContextMoveToPoint(fl_gc, x, y); CGContextAddLineToPoint(fl_gc, x1, y); CGContextStrokePath(fl_gc); - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); #else # error unsupported platform #endif } -/** - Draws a horizontal line from (x,y) to (x1,y), then vertical from (x1,y) to (x1,y2) -*/ -void fl_xyline(int x, int y, int x1, int y2) { +void Fl_Graphics_Driver::xyline(int x, int y, int x1, int y2) { #if defined (USE_X11) XPoint p[3]; p[0].x = x; p[0].y = p[1].y = y; @@ -125,22 +116,18 @@ void fl_xyline(int x, int y, int x1, int y2) { LineTo(fl_gc, x1, y); LineTo(fl_gc, x1, y2); #elif defined(__APPLE_QUARTZ__) - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); CGContextMoveToPoint(fl_gc, x, y); CGContextAddLineToPoint(fl_gc, x1, y); CGContextAddLineToPoint(fl_gc, x1, y2); CGContextStrokePath(fl_gc); - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); #else #error unsupported platform #endif } -/** - Draws a horizontal line from (x,y) to (x1,y), then a vertical from (x1,y) to (x1,y2) - and then another horizontal from (x1,y2) to (x3,y2) -*/ -void fl_xyline(int x, int y, int x1, int y2, int x3) { +void Fl_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) { #if defined(USE_X11) XPoint p[4]; p[0].x = x; p[0].y = p[1].y = y; @@ -155,22 +142,19 @@ void fl_xyline(int x, int y, int x1, int y2, int x3) { LineTo(fl_gc, x1, y2); LineTo(fl_gc, x3, y2); #elif defined(__APPLE_QUARTZ__) - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); CGContextMoveToPoint(fl_gc, x, y); CGContextAddLineToPoint(fl_gc, x1, y); CGContextAddLineToPoint(fl_gc, x1, y2); CGContextAddLineToPoint(fl_gc, x3, y2); CGContextStrokePath(fl_gc); - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); #else # error unsupported platform #endif } -/** - Draws a vertical line from (x,y) to (x,y1) -*/ -void fl_yxline(int x, int y, int y1) { +void Fl_Graphics_Driver::yxline(int x, int y, int y1) { #if defined(USE_X11) XDrawLine(fl_display, fl_window, fl_gc, x, y, x, y1); #elif defined(WIN32) @@ -178,20 +162,17 @@ void fl_yxline(int x, int y, int y1) { else y1++; MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x, y1); #elif defined(__APPLE_QUARTZ__) - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); CGContextMoveToPoint(fl_gc, x, y); CGContextAddLineToPoint(fl_gc, x, y1); CGContextStrokePath(fl_gc); - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); #else # error unsupported platform #endif } -/** - Draws a vertical line from (x,y) to (x,y1), then a horizontal from (x,y1) to (x2,y1) -*/ -void fl_yxline(int x, int y, int y1, int x2) { +void Fl_Graphics_Driver::yxline(int x, int y, int y1, int x2) { #if defined(USE_X11) XPoint p[3]; p[0].x = p[1].x = x; p[0].y = y; @@ -204,22 +185,18 @@ void fl_yxline(int x, int y, int y1, int x2) { LineTo(fl_gc, x, y1); LineTo(fl_gc, x2, y1); #elif defined(__APPLE_QUARTZ__) - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); CGContextMoveToPoint(fl_gc, x, y); CGContextAddLineToPoint(fl_gc, x, y1); CGContextAddLineToPoint(fl_gc, x2, y1); CGContextStrokePath(fl_gc); - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); #else # error unsupported platform #endif } -/** - Draws a vertical line from (x,y) to (x,y1) then a horizontal from (x,y1) - to (x2,y1), then another vertical from (x2,y1) to (x2,y3) -*/ -void fl_yxline(int x, int y, int y1, int x2, int y3) { +void Fl_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) { #if defined(USE_X11) XPoint p[4]; p[0].x = p[1].x = x; p[0].y = y; @@ -234,22 +211,19 @@ void fl_yxline(int x, int y, int y1, int x2, int y3) { LineTo(fl_gc, x2, y1); LineTo(fl_gc, x2, y3); #elif defined(__APPLE_QUARTZ__) - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); CGContextMoveToPoint(fl_gc, x, y); CGContextAddLineToPoint(fl_gc, x, y1); CGContextAddLineToPoint(fl_gc, x2, y1); CGContextAddLineToPoint(fl_gc, x2, y3); CGContextStrokePath(fl_gc); - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); + if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); #else # error unsupported platform #endif } -/** - Draws a line from (x,y) to (x1,y1) -*/ -void fl_line(int x, int y, int x1, int y1) { +void Fl_Graphics_Driver::line(int x, int y, int x1, int y1) { #if defined(USE_X11) XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y1); #elif defined(WIN32) @@ -259,20 +233,17 @@ void fl_line(int x, int y, int x1, int y1) { // functions will not draw the last point ("it's a feature!"...) SetPixel(fl_gc, x1, y1, fl_RGB()); #elif defined(__APPLE_QUARTZ__) - if (fl_quartz_line_width_==1.0f ) CGContextSetShouldAntialias(fl_gc, false); + if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); CGContextMoveToPoint(fl_gc, x, y); CGContextAddLineToPoint(fl_gc, x1, y1); CGContextStrokePath(fl_gc); - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); + if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); #else # error unsupported platform #endif } -/** - Draws a line from (x,y) to (x1,y1) and another from (x1,y1) to (x2,y2) -*/ -void fl_line(int x, int y, int x1, int y1, int x2, int y2) { +void Fl_Graphics_Driver::line(int x, int y, int x1, int y1, int x2, int y2) { #if defined(USE_X11) XPoint p[3]; p[0].x = x; p[0].y = y; @@ -287,21 +258,18 @@ void fl_line(int x, int y, int x1, int y1, int x2, int y2) { // functions will not draw the last point ("it's a feature!"...) SetPixel(fl_gc, x2, y2, fl_RGB()); #elif defined(__APPLE_QUARTZ__) - if (fl_quartz_line_width_==1.0f ) CGContextSetShouldAntialias(fl_gc, false); + if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); CGContextMoveToPoint(fl_gc, x, y); CGContextAddLineToPoint(fl_gc, x1, y1); CGContextAddLineToPoint(fl_gc, x2, y2); CGContextStrokePath(fl_gc); - if (fl_quartz_line_width_==1.0f ) CGContextSetShouldAntialias(fl_gc, true); + if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); #else # error unsupported platform #endif } -/** - Outlines a 3-sided polygon with lines -*/ -void fl_loop(int x, int y, int x1, int y1, int x2, int y2) { +void Fl_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2) { #if defined(USE_X11) XPoint p[4]; p[0].x = x; p[0].y = y; @@ -315,20 +283,19 @@ void fl_loop(int x, int y, int x1, int y1, int x2, int y2) { LineTo(fl_gc, x2, y2); LineTo(fl_gc, x, y); #elif defined(__APPLE_QUARTZ__) + CGContextSetShouldAntialias(fl_gc, true); CGContextMoveToPoint(fl_gc, x, y); CGContextAddLineToPoint(fl_gc, x1, y1); CGContextAddLineToPoint(fl_gc, x2, y2); CGContextClosePath(fl_gc); CGContextStrokePath(fl_gc); + CGContextSetShouldAntialias(fl_gc, false); #else # error unsupported platform #endif } -/** - Outlines a 4-sided polygon with lines -*/ -void fl_loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { +void Fl_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { #if defined(USE_X11) XPoint p[5]; p[0].x = x; p[0].y = y; @@ -344,21 +311,20 @@ void fl_loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { LineTo(fl_gc, x3, y3); LineTo(fl_gc, x, y); #elif defined(__APPLE_QUARTZ__) + CGContextSetShouldAntialias(fl_gc, true); CGContextMoveToPoint(fl_gc, x, y); CGContextAddLineToPoint(fl_gc, x1, y1); CGContextAddLineToPoint(fl_gc, x2, y2); CGContextAddLineToPoint(fl_gc, x3, y3); CGContextClosePath(fl_gc); CGContextStrokePath(fl_gc); + CGContextSetShouldAntialias(fl_gc, false); #else # error unsupported platform #endif } -/** - Fills a 3-sided polygon. The polygon must be convex. -*/ -void fl_polygon(int x, int y, int x1, int y1, int x2, int y2) { +void Fl_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y2) { XPoint p[4]; p[0].x = x; p[0].y = y; p[1].x = x1; p[1].y = y1; @@ -371,20 +337,19 @@ void fl_polygon(int x, int y, int x1, int y1, int x2, int y2) { SelectObject(fl_gc, fl_brush()); Polygon(fl_gc, p, 3); #elif defined(__APPLE_QUARTZ__) + CGContextSetShouldAntialias(fl_gc, true); CGContextMoveToPoint(fl_gc, x, y); CGContextAddLineToPoint(fl_gc, x1, y1); CGContextAddLineToPoint(fl_gc, x2, y2); CGContextClosePath(fl_gc); CGContextFillPath(fl_gc); + CGContextSetShouldAntialias(fl_gc, false); #else # error unsupported platform #endif } -/** - Fills a 4-sided polygon. The polygon must be convex. -*/ -void fl_polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { +void Fl_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { XPoint p[5]; p[0].x = x; p[0].y = y; p[1].x = x1; p[1].y = y1; @@ -398,31 +363,30 @@ void fl_polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { SelectObject(fl_gc, fl_brush()); Polygon(fl_gc, p, 4); #elif defined(__APPLE_QUARTZ__) + CGContextSetShouldAntialias(fl_gc, true); CGContextMoveToPoint(fl_gc, x, y); CGContextAddLineToPoint(fl_gc, x1, y1); CGContextAddLineToPoint(fl_gc, x2, y2); CGContextAddLineToPoint(fl_gc, x3, y3); CGContextClosePath(fl_gc); CGContextFillPath(fl_gc); + CGContextSetShouldAntialias(fl_gc, false); #else # error unsupported platform #endif } -/** - Draws a single pixel at the given coordinates -*/ -void fl_point(int x, int y) { +void Fl_Graphics_Driver::point(int x, int y) { #if defined(USE_X11) XDrawPoint(fl_display, fl_window, fl_gc, x, y); #elif defined(WIN32) SetPixel(fl_gc, x, y, fl_RGB()); #elif defined(__APPLE_QUARTZ__) - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); + if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); CGContextMoveToPoint(fl_gc, x-.5, y); // Quartz needs a line that is one pixel long, or it will not draw anything CGContextAddLineToPoint(fl_gc, x+.5, y); CGContextStrokePath(fl_gc); - if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); + if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); #else # error unsupported platform #endif @@ -448,14 +412,6 @@ Fl_Region XRectangleRegion(int x, int y, int w, int h) { } #endif -#if defined(__APPLE_QUARTZ__) -// warning: the Quartz implementation currently uses Quickdraw calls to achieve -// clipping. A future version should instead use 'CGContectClipToRect' -// and friends. -extern Fl_Region fl_window_region; -#endif - -/** Undoes any clobbering of clip done by your program */ void fl_restore_clip() { fl_clip_state_number++; Fl_Region r = rstack[rstackptr]; @@ -465,42 +421,25 @@ void fl_restore_clip() { #elif defined(WIN32) SelectClipRgn(fl_gc, r); //if r is NULL, clip is automatically cleared #elif defined(__APPLE_QUARTZ__) - if ( fl_window ) // clipping for a true window - { - GrafPtr port = GetWindowPort( fl_window ); - if ( port ) { - RgnHandle portClip = NewRgn(); - CopyRgn( fl_window_region, portClip ); // changed - if ( r ) - SectRgn( portClip, r, portClip ); - Rect portRect; GetPortBounds(port, &portRect); - Fl_X::q_clear_clipping(); - ClipCGContextToRegion(fl_gc, &portRect, portClip ); - Fl_X::q_fill_context(); - DisposeRgn( portClip ); + if ( fl_window ) { // clipping for a true window + Fl_X::q_clear_clipping(); + Fl_X::q_fill_context();//flip coords if bitmap context + //apply program clip + if (r) { + CGContextClipToRects(fl_gc, r->rects, r->count); } } else if (fl_gc) { // clipping for an offscreen drawing world (CGBitmap) - Rect portRect; - portRect.top = 0; - portRect.left = 0; - portRect.bottom = CGBitmapContextGetHeight(fl_gc); - portRect.right = CGBitmapContextGetWidth(fl_gc); Fl_X::q_clear_clipping(); - if (r) - ClipCGContextToRegion(fl_gc, &portRect, r); Fl_X::q_fill_context(); + if (r) { + CGContextClipToRects(fl_gc, r->rects, r->count); + } } #else # error unsupported platform #endif } -/** - Replaces the top of the clipping stack with a clipping region of any shape. - - Fl_Region is an operating system specific type. - \param[in] r clipping region -*/ void fl_clip_region(Fl_Region r) { Fl_Region oldr = rstack[rstackptr]; if (oldr) XDestroyRegion(oldr); @@ -508,19 +447,11 @@ void fl_clip_region(Fl_Region r) { fl_restore_clip(); } -/** - \returns the current clipping region. -*/ Fl_Region fl_clip_region() { return rstack[rstackptr]; } -/** - Intersects the current clip region with a rectangle and pushes this - new region onto the stack. - \param[in] x,y,w,h position and size -*/ -void fl_push_clip(int x, int y, int w, int h) { +void Fl_Graphics_Driver::push_clip(int x, int y, int w, int h) { Fl_Region r; if (w > 0 && h > 0) { r = XRectangleRegion(x,y,w,h); @@ -534,7 +465,8 @@ void fl_push_clip(int x, int y, int w, int h) { #elif defined(WIN32) CombineRgn(r,r,current,RGN_AND); #elif defined(__APPLE_QUARTZ__) - SectRgn(r, current, r); + XDestroyRegion(r); + r = MacRectRegionIntersect(current, x,y,w,h); #else # error unsupported platform #endif @@ -545,8 +477,7 @@ void fl_push_clip(int x, int y, int w, int h) { #elif defined(WIN32) r = CreateRectRgn(0,0,0,0); #elif defined(__APPLE_QUARTZ__) - r = NewRgn(); - SetEmptyRgn(r); + r = XRectangleRegion(0,0,0,0); #else # error unsupported platform #endif @@ -557,24 +488,14 @@ void fl_push_clip(int x, int y, int w, int h) { } // make there be no clip (used by fl_begin_offscreen() only!) -/** - Pushes an empty clip region onto the stack so nothing will be clipped. -*/ -void fl_push_no_clip() { +void Fl_Graphics_Driver::push_no_clip() { if (rstackptr < STACK_MAX) rstack[++rstackptr] = 0; else Fl::warning("fl_push_no_clip: clip stack overflow!\n"); fl_restore_clip(); } // pop back to previous clip: -/** - Restores the previous clip region. - - You must call fl_pop_clip() once for every time you call fl_push_clip(). - Unpredictable results may occur if the clip stack is not empty when - you return to FLTK. -*/ -void fl_pop_clip() { +void Fl_Graphics_Driver::pop_clip() { if (rstackptr > 0) { Fl_Region oldr = rstack[rstackptr--]; if (oldr) XDestroyRegion(oldr); @@ -582,17 +503,7 @@ void fl_pop_clip() { fl_restore_clip(); } -/** - Does the rectangle intersect the current clip region? - \param[in] x,y,w,h position and size of rectangle - \returns non-zero if any of the rectangle intersects the current clip - region. If this returns 0 you don't have to draw the object. - - \note - Under X this returns 2 if the rectangle is partially clipped, - and 1 if it is entirely inside the clip region. -*/ -int fl_not_clipped(int x, int y, int w, int h) { +int Fl_Graphics_Driver::not_clipped(int x, int y, int w, int h) { if (x+w <= 0 || y+h <= 0) return 0; Fl_Region r = rstack[rstackptr]; #if defined (USE_X11) @@ -600,34 +511,30 @@ int fl_not_clipped(int x, int y, int w, int h) { #elif defined(WIN32) if (!r) return 1; RECT rect; - rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h; + if (Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) { // in case of print context, convert coords from logical to device + POINT pt[2] = { {x, y}, {x + w, y + h} }; + LPtoDP(fl_gc, pt, 2); + rect.left = pt[0].x; rect.top = pt[0].y; rect.right = pt[1].x; rect.bottom = pt[1].y; + } + else { + rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h; + } return RectInRegion(r,&rect); #elif defined(__APPLE_QUARTZ__) if (!r) return 1; - Rect rect; - rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h; - return RectInRgn(&rect, r); + CGRect arg = fl_cgrectmake_cocoa(x, y, w, h); + for(int i = 0; i < r->count; i++) { + CGRect test = CGRectIntersection(r->rects[i], arg); + if( ! CGRectIsEmpty(test)) return 1; + } + return 0; #else # error unsupported platform #endif } // return rectangle surrounding intersection of this rectangle and clip: -/** - Intersects the rectangle with the current clip region and returns the - bounding box of the result. - - Returns non-zero if the resulting rectangle is different to the original. - This can be used to limit the necessary drawing to a rectangle. - \p W and \p H are set to zero if the rectangle is completely outside - the region. - \param[in] x,y,w,h position and size of rectangle - \param[out] X,Y,W,H position and size of resulting bounding box. - \p W and \p H are set to zero if the rectangle is - completely outside the region. - \returns Non-zero if the resulting rectangle is different to the original. -*/ -int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){ +int Fl_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){ X = x; Y = y; W = w; H = h; Fl_Region r = rstack[rstackptr]; if (!r) return 0; @@ -663,33 +570,44 @@ int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){ ret = 2; } else if (EqualRgn(temp, rr)) { // complete ret = 0; - } else { // parital intersection + } else { // partial intersection RECT rect; GetRgnBox(temp, &rect); - X = rect.left; Y = rect.top; W = rect.right - X; H = rect.bottom - Y; + if(Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) { // if print context, convert coords from device to logical + POINT pt[2] = { {rect.left, rect.top}, {rect.right, rect.bottom} }; + DPtoLP(fl_gc, pt, 2); + X = pt[0].x; Y = pt[0].y; W = pt[1].x - X; H = pt[1].y - Y; + } + else { + X = rect.left; Y = rect.top; W = rect.right - X; H = rect.bottom - Y; + } ret = 1; } DeleteObject(temp); DeleteObject(rr); return ret; #elif defined(__APPLE_QUARTZ__) - RgnHandle rr = NewRgn(); - SetRectRgn( rr, x, y, x+w, y+h ); - SectRgn( r, rr, rr ); - Rect rp; GetRegionBounds(rr, &rp); - X = rp.left; - Y = rp.top; - W = rp.right - X; - H = rp.bottom - Y; - DisposeRgn( rr ); - if ( H==0 ) return 2; - if ( h==H && w==W ) return 0; - return 0; + CGRect arg = fl_cgrectmake_cocoa(x, y, w, h); + CGRect u = CGRectMake(0,0,0,0); + CGRect test; + for(int i = 0; i < r->count; i++) { + test = CGRectIntersection(r->rects[i], arg); + if( ! CGRectIsEmpty(test) ) { + if(CGRectIsEmpty(u)) u = test; + else u = CGRectUnion(u, test); + } + } + X = u.origin.x; + Y = u.origin.y; + W = u.size.width + 1; + H = u.size.height + 1; + if(CGRectIsEmpty(u)) W = H = 0; + return ! CGRectEqualToRect(arg, u); #else # error unsupported platform #endif } // -// End of "$Id: fl_rect.cxx 6755 2009-04-12 13:48:03Z matt $". +// End of "$Id: fl_rect.cxx 7617 2010-05-27 17:20:18Z manolo $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_scroll_area.cxx b/plugins/zynaddsubfx/fltk/src/fl_scroll_area.cxx index 450083a5c..25f32c208 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_scroll_area.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_scroll_area.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_scroll_area.cxx 6716 2009-03-24 01:40:44Z fabien $" +// "$Id: fl_scroll_area.cxx 7351 2010-03-29 10:35:00Z matt $" // // Scrolling routines for the Fast Light Tool Kit (FLTK). // @@ -151,16 +151,13 @@ void fl_scroll(int X, int Y, int W, int H, int dx, int dy, BitBlt(fl_gc, dest_x, dest_y, src_w, src_h, fl_gc, src_x, src_y,SRCCOPY); #elif defined(__APPLE_QUARTZ__) - // warning: there does not seem to be an equivalent to this function in Quartz - // ScrollWindowRect is a QuickDraw function and won't work here. - // Since on OS X all windows are fully double buffered, we need not - // worry about offscreen or obscured areas - Rect src = { src_y, src_x, src_y+src_h, src_x+src_w }; - Rect dst = { dest_y, dest_x, dest_y+src_h, dest_x+src_w }; - static RGBColor bg = { 0xffff, 0xffff, 0xffff }; RGBBackColor( &bg ); - static RGBColor fg = { 0x0000, 0x0000, 0x0000 }; RGBForeColor( &fg ); - CopyBits( GetPortBitMapForCopyBits( GetWindowPort(fl_window) ), - GetPortBitMapForCopyBits( GetWindowPort(fl_window) ), &src, &dst, srcCopy, 0L); + extern CGImageRef MAC_CGImageFromRectOfWindow(Fl_Window*, int x, int y, int w, int h); + CGImageRef img = MAC_CGImageFromRectOfWindow(Fl_Window::current(), src_x, src_y, src_w, src_h); + CGRect rect = { { dest_x, dest_y }, { src_w, src_h } }; + Fl_X::q_begin_image(rect, 0, 0, src_w, src_h); + CGContextDrawImage(fl_gc, rect, img); + Fl_X::q_end_image(); + CFRelease(img); #else # error unsupported platform #endif @@ -169,5 +166,5 @@ void fl_scroll(int X, int Y, int W, int H, int dx, int dy, } // -// End of "$Id: fl_scroll_area.cxx 6716 2009-03-24 01:40:44Z fabien $". +// End of "$Id: fl_scroll_area.cxx 7351 2010-03-29 10:35:00Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_set_fonts_mac.cxx b/plugins/zynaddsubfx/fltk/src/fl_set_fonts_mac.cxx index 07680dcbf..d12a38ff8 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_set_fonts_mac.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_set_fonts_mac.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_set_fonts_mac.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: fl_set_fonts_mac.cxx 7351 2010-03-29 10:35:00Z matt $" // // MacOS font utilities for the Fast Light Tool Kit (FLTK). // @@ -60,26 +60,37 @@ static int fl_free_font = FL_FREE_FONT; Fl_Font Fl::set_fonts(const char* xstarname) { #pragma unused ( xstarname ) -#if defined(OLD__APPLE_QUARTZ__) - ATSFontIterator it; - ATSFontIteratorCreate(kATSFontContextGlobal, 0L, 0L, kATSOptionFlagsUnRestrictedScope, &it); - for (;;) { - ATSFontRef font; - CFStringRef fname = 0; - OSStatus err = ATSFontIteratorNext(it, &font); - if (err!=noErr) break; - ATSFontGetName(font, kATSOptionFlagsDefault, &fname); - char buf[1024]; - CFStringGetCString(fname, buf, 1024, kCFStringEncodingUTF8); - int i; - for (i=0; i= MAC_OS_X_VERSION_10_5 +static SInt32 MACsystemVersion = 0; +if(MACsystemVersion == 0) Gestalt(gestaltSystemVersion, &MACsystemVersion); +if(MACsystemVersion >= 0x1050) { +//if(CTFontCreateWithFontDescriptor != NULL) {// CTFontCreateWithFontDescriptor != NULL on 10.4 also! + int value[1] = {1}; + CFDictionaryRef dict = CFDictionaryCreate(NULL, + (const void **)kCTFontCollectionRemoveDuplicatesOption, + (const void **)&value, 1, NULL, NULL); + CTFontCollectionRef fcref = CTFontCollectionCreateFromAvailableFonts(dict); + CFRelease(dict); + CFArrayRef arrayref = CTFontCollectionCreateMatchingFontDescriptors(fcref); + CFRelease(fcref); + CFIndex count = CFArrayGetCount(arrayref); + CFIndex i; + for (i = 0; i < count; i++) { + CTFontDescriptorRef fdesc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(arrayref, i); + CTFontRef font = CTFontCreateWithFontDescriptor(fdesc, 0., NULL); + CFStringRef cfname = CTFontCopyPostScriptName(font); + CFRelease(font); + static char fname[100]; + CFStringGetCString(cfname, fname, sizeof(fname), kCFStringEncodingUTF8); + CFRelease(cfname); + Fl::set_font((Fl_Font)(fl_free_font++), strdup(fname)); + } + CFRelease(arrayref); return (Fl_Font)fl_free_font; -#else +} +else { +#endif +#if ! __LP64__ ItemCount oFontCount, oCountAgain; ATSUFontID *oFontIDs; // How many fonts? @@ -114,7 +125,11 @@ Fl_Font Fl::set_fonts(const char* xstarname) { } free(oFontIDs); return (Fl_Font)fl_free_font; +#endif //__LP64__ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + } #endif + return 0; // FIXME: I do not understand the shuffeling of the above ifdef's and why they are here! } static int array[128]; @@ -132,5 +147,5 @@ int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) { } // -// End of "$Id: fl_set_fonts_mac.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: fl_set_fonts_mac.cxx 7351 2010-03-29 10:35:00Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_shortcut.cxx b/plugins/zynaddsubfx/fltk/src/fl_shortcut.cxx index 56b03241d..22b316655 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_shortcut.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_shortcut.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_shortcut.cxx 6878 2009-09-17 22:12:24Z matt $" +// "$Id: fl_shortcut.cxx 7496 2010-04-13 21:08:06Z greg.ercolano $" // // Shortcut support routines for the Fast Light Tool Kit (FLTK). // @@ -58,11 +58,11 @@ be confused with Fl_Widget::test_shortcut(). */ -int Fl::test_shortcut(Fl_Shortcut shortcut) { +int Fl::test_shortcut(unsigned int shortcut) { if (!shortcut) return 0; - Fl_Char v = shortcut & FL_KEY_MASK; - if (fl_tolower(v)!=v) { + unsigned int v = shortcut & FL_KEY_MASK; + if (((unsigned)fl_tolower(v))!=v) { shortcut |= FL_SHIFT; } @@ -74,13 +74,13 @@ int Fl::test_shortcut(Fl_Shortcut shortcut) { // these three must always be correct: if (mismatch&(FL_META|FL_ALT|FL_CTRL)) return 0; - Fl_Char key = shortcut & FL_KEY_MASK; + unsigned int key = shortcut & FL_KEY_MASK; // if shift is also correct, check for exactly equal keysyms: - if (!(mismatch&(FL_SHIFT)) && key == Fl::event_key()) return 1; + if (!(mismatch&(FL_SHIFT)) && key == (unsigned)Fl::event_key()) return 1; // try matching utf8, ignore shift: - Fl_Char firstChar = fl_utf8decode(Fl::event_text(), Fl::event_text()+Fl::event_length(), 0); + unsigned int firstChar = fl_utf8decode(Fl::event_text(), Fl::event_text()+Fl::event_length(), 0); if (key==firstChar) return 1; // kludge so that Ctrl+'_' works (as opposed to Ctrl+'^_'): @@ -90,7 +90,7 @@ int Fl::test_shortcut(Fl_Shortcut shortcut) { } // This table must be in numeric order by fltk (X) keysym number: -struct Keyname {int key; const char* name;}; +struct Keyname {unsigned int key; const char* name;}; #if defined(WIN32) static Keyname table[] = { {' ', "Space"}, @@ -129,36 +129,36 @@ static Keyname table[] = { static Keyname table[] = { // v - this column contains utf8 characters {' ', "Space"}, - {FL_BackSpace,"\xe2\x8c\xab"}, // ⌫ erase to the left - {FL_Tab, "\xe2\x87\xa5"}, // ⇥ rightwards arrow to bar - {0xff0b, "\xe2\x8c\xa6"}, // ⌦ erase to the right - {FL_Enter, "\xe2\x86\xa9"}, // ↩ leftwards arrow with hook + {FL_BackSpace,"\xe2\x8c\xab"}, // erase to the left + {FL_Tab, "\xe2\x87\xa5"}, // rightwards arrow to bar + {0xff0b, "\xe2\x8c\xa6"}, // erase to the right + {FL_Enter, "\xe2\x86\xa9"}, // leftwards arrow with hook {FL_Pause, "Pause"}, {FL_Scroll_Lock, "Scroll_Lock"}, {FL_Escape, "\xe2\x90\x9b"}, - {FL_Home, "\xe2\x86\x96"}, // ↖ north west arrow - {FL_Left, "\xe2\x86\x90"}, // ↠leftwards arrow - {FL_Up, "\xe2\x86\x91"}, // ↑ upwards arrow - {FL_Right, "\xe2\x86\x92"}, // → rightwards arrow - {FL_Down, "\xe2\x86\x93"}, // ↓ downwards arrow - {FL_Page_Up, "\xe2\x87\x9e"}, // ⇞ upwards arrow with double stroke - {FL_Page_Down,"\xe2\x87\x9f"}, // ⇟ downward arrow with double stroke - {FL_End, "\xe2\x86\x98"}, // ↘ south east arrow + {FL_Home, "\xe2\x86\x96"}, // north west arrow + {FL_Left, "\xe2\x86\x90"}, // leftwards arrow + {FL_Up, "\xe2\x86\x91"}, // upwards arrow + {FL_Right, "\xe2\x86\x92"}, // rightwards arrow + {FL_Down, "\xe2\x86\x93"}, // downwards arrow + {FL_Page_Up, "\xe2\x87\x9e"}, // upwards arrow with double stroke + {FL_Page_Down,"\xe2\x87\x9f"}, // downward arrow with double stroke + {FL_End, "\xe2\x86\x98"}, // south east arrow {FL_Print, "Print"}, {FL_Insert, "Insert"}, {FL_Menu, "Menu"}, {FL_Num_Lock, "Num_Lock"}, - {FL_KP_Enter, "\xe2\x8c\xa4"}, // ⌤ up arrow head between two horizontal bars + {FL_KP_Enter, "\xe2\x8c\xa4"}, // up arrow head between two horizontal bars {FL_Shift_L, "Shift_L"}, {FL_Shift_R, "Shift_R"}, {FL_Control_L,"Control_L"}, {FL_Control_R,"Control_R"}, - {FL_Caps_Lock,"\xe2\x87\xaa"}, // ⇪ upwards white arrow from bar + {FL_Caps_Lock,"\xe2\x87\xaa"}, // upwards white arrow from bar {FL_Meta_L, "Meta_L"}, {FL_Meta_R, "Meta_R"}, {FL_Alt_L, "Alt_L"}, {FL_Alt_R, "Alt_R"}, - {FL_Delete, "\xe2\x8c\xa7"} // ⌧ x in a rectangle box + {FL_Delete, "\xe2\x8c\xa7"} // x in a rectangle box }; #endif @@ -174,7 +174,7 @@ static Keyname table[] = { \param [in] shortcut the integer value containing the ascii charcter or extended keystroke plus modifiers \return a pointer to a static buffer containing human readable text for the shortcut */ -const char* fl_shortcut_label(Fl_Shortcut shortcut) { +const char* fl_shortcut_label(unsigned int shortcut) { return fl_shortcut_label(shortcut, 0L); } @@ -184,24 +184,24 @@ const char* fl_shortcut_label(Fl_Shortcut shortcut) { \param [in] shortcut the integer value containing the ascii charcter or extended keystroke plus modifiers \param [in] eom if this pointer is set, it will receive a pointer to the end of the modifier text \return a pointer to a static buffer containing human readable text for the shortcut - \see fl_shortcut_label(Fl_Shortcut shortcut) + \see fl_shortcut_label(unsigned int shortcut) */ -const char* fl_shortcut_label(Fl_Shortcut shortcut, const char **eom) { +const char* fl_shortcut_label(unsigned int shortcut, const char **eom) { static char buf[20]; char *p = buf; if (eom) *eom = p; if (!shortcut) {*p = 0; return buf;} // fix upper case shortcuts - Fl_Char v = shortcut & FL_KEY_MASK; - if (fl_tolower(v)!=v) { + unsigned int v = shortcut & FL_KEY_MASK; + if (((unsigned)fl_tolower(v))!=v) { shortcut |= FL_SHIFT; } #ifdef __APPLE__ // this column contains utf8 characters - v - if (shortcut & FL_SHIFT) {strcpy(p,"\xe2\x87\xa7"); p += 3;} // ⇧ upwards white arrow - if (shortcut & FL_CTRL) {strcpy(p,"\xe2\x8c\x83"); p += 3;} // ⌃ up arrowhead - if (shortcut & FL_ALT) {strcpy(p,"\xe2\x8e\x87"); p += 3;} // ⎇ alternative key symbol - if (shortcut & FL_META) {strcpy(p,"\xe2\x8c\x98"); p += 3;} // ⌘ place of interest sign + if (shortcut & FL_SHIFT) {strcpy(p,"\xe2\x87\xa7"); p += 3;} // upwards white arrow + if (shortcut & FL_CTRL) {strcpy(p,"\xe2\x8c\x83"); p += 3;} // up arrowhead + if (shortcut & FL_ALT) {strcpy(p,"\xe2\x8c\xa5"); p += 3;} // alternative key symbol + if (shortcut & FL_META) {strcpy(p,"\xe2\x8c\x98"); p += 3;} // place of interest sign #else if (shortcut & FL_META) {strcpy(p,"Meta+"); p += 5;} if (shortcut & FL_ALT) {strcpy(p,"Alt+"); p += 4;} @@ -209,7 +209,7 @@ const char* fl_shortcut_label(Fl_Shortcut shortcut, const char **eom) { if (shortcut & FL_CTRL) {strcpy(p,"Ctrl+"); p += 5;} #endif // __APPLE__ if (eom) *eom = p; - Fl_Char key = shortcut & FL_KEY_MASK; + unsigned int key = shortcut & FL_KEY_MASK; #if defined(WIN32) || defined(__APPLE__) // if not X if (key >= FL_F && key <= FL_F_Last) { *p++ = 'F'; @@ -269,10 +269,20 @@ const char* fl_shortcut_label(Fl_Shortcut shortcut, const char **eom) { #include /** Emulation of XForms named shortcuts. + + Converts ascii shortcut specifications (eg. "^c") + into the FLTK integer equivalent (eg. FL_CTRL+'c') + + These ascii characters are used to specify the various keyboard modifier keys: + \verbatim + # - Alt + + - Shift + ^ - Control + \endverbatim */ -Fl_Shortcut fl_old_shortcut(const char* s) { +unsigned int fl_old_shortcut(const char* s) { if (!s || !*s) return 0; - Fl_Shortcut n = 0; + unsigned int n = 0; if (*s == '#') {n |= FL_ALT; s++;} if (*s == '+') {n |= FL_SHIFT; s++;} if (*s == '^') {n |= FL_CTRL; s++;} @@ -282,14 +292,14 @@ Fl_Shortcut fl_old_shortcut(const char* s) { // Tests for &x shortcuts in button labels: -Fl_Shortcut Fl_Widget::label_shortcut(const char *t) { +unsigned int Fl_Widget::label_shortcut(const char *t) { if (!t) return 0; for (;;) { if (*t==0) return 0; if (*t=='&') { - Fl_Shortcut s = fl_utf8decode(t+1, 0, 0); + unsigned int s = fl_utf8decode(t+1, 0, 0); if (s==0) return 0; - else if (s==(Fl_Char)'&') t++; + else if (s==(unsigned int)'&') t++; else return s; } t++; @@ -302,7 +312,7 @@ int Fl_Widget::test_shortcut(const char *t) { if (Fl::event_state(FL_ALT)==0) return 0; #endif if (!t) return 0; - Fl_Shortcut c = fl_utf8decode(Fl::event_text(), Fl::event_text()+Fl::event_length(), 0); + unsigned int c = fl_utf8decode(Fl::event_text(), Fl::event_text()+Fl::event_length(), 0); if (!c) return 0; if (c == label_shortcut(t)) return 1; @@ -315,5 +325,5 @@ int Fl_Widget::test_shortcut() { } // -// End of "$Id: fl_shortcut.cxx 6878 2009-09-17 22:12:24Z matt $". +// End of "$Id: fl_shortcut.cxx 7496 2010-04-13 21:08:06Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_show_colormap.cxx b/plugins/zynaddsubfx/fltk/src/fl_show_colormap.cxx index eb7cded47..3992c8e7d 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_show_colormap.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_show_colormap.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_show_colormap.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: fl_show_colormap.cxx 7147 2010-02-25 23:29:42Z matt $" // // Colormap color selection dialog for the Fast Light Tool Kit (FLTK). // @@ -82,7 +82,7 @@ void ColorMenu::draw() { } int ColorMenu::handle(int e) { - int c = which; + Fl_Color c = which; switch (e) { case FL_PUSH: case FL_DRAG: { @@ -158,5 +158,5 @@ Fl_Color fl_show_colormap(Fl_Color oldcol) { } // -// End of "$Id: fl_show_colormap.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: fl_show_colormap.cxx 7147 2010-02-25 23:29:42Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_utf.c b/plugins/zynaddsubfx/fltk/src/fl_utf.c index cc2059ce5..e57c32e2c 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_utf.c +++ b/plugins/zynaddsubfx/fltk/src/fl_utf.c @@ -1,5 +1,8 @@ -/* This is the utf.c file from fltk2 adapted for use in my fltk1.1 port */ - +/* + * "$Id: fl_utf.c 7609 2010-05-17 20:03:47Z engelsman $" + * + * This is the utf.c file from fltk2 adapted for use in my fltk1.1 port + */ /* Copyright 2006-2009 by Bill Spitzak and others. * * This library is free software; you can redistribute it and/or @@ -46,7 +49,7 @@ \c NULL, only the length of the utf-8 sequence is calculated \return length of the sequence in bytes */ - /* FL_EXPORT int fl_unichar_to_utf8(Fl_Char uc, char *text); */ + /* FL_EXPORT int fl_unichar_to_utf8(unsigned int uc, char *text); */ /** @} */ @@ -60,22 +63,22 @@ \param[in] uc Unicode character \return length of the sequence in bytes */ - /* FL_EXPORT int fl_utf8_size(Fl_Char uc); */ + /* FL_EXPORT int fl_utf8_size(unsigned int uc); */ /** @} */ #endif /* 0 */ -/* Set to 1 to turn bad UTF8 bytes into ISO-8859-1. If this is to zero +/*!Set to 1 to turn bad UTF8 bytes into ISO-8859-1. If this is to zero they are instead turned into the Unicode REPLACEMENT CHARACTER, of value 0xfffd. - If this is on fl_utf8decode will correctly map most (perhaps all) + If this is on fl_utf8decode() will correctly map most (perhaps all) human-readable text that is in ISO-8859-1. This may allow you to completely ignore character sets in your code because virtually everything is either ISO-8859-1 or UTF-8. */ #define ERRORS_TO_ISO8859_1 1 -/* Set to 1 to turn bad UTF8 bytes in the 0x80-0x9f range into the +/*!Set to 1 to turn bad UTF8 bytes in the 0x80-0x9f range into the Unicode index for Microsoft's CP1252 character set. You should also set ERRORS_TO_ISO8859_1. With this a huge amount of more available text (such as all web pages) are correctly converted @@ -83,7 +86,7 @@ */ #define ERRORS_TO_CP1252 1 -/* A number of Unicode code points are in fact illegal and should not +/*!A number of Unicode code points are in fact illegal and should not be produced by a UTF-8 converter. Turn this on will replace the bytes in those encodings with errors. If you do this then converting arbitrary 16-bit data to UTF-8 and then back is not an identity, @@ -283,7 +286,7 @@ int fl_utf8bytes(unsigned ucs) { return 2; } else if (ucs < 0x010000U) { return 3; - } else if (ucs < 0x10ffffU) { + } else if (ucs <= 0x10ffffU) { return 4; } else { return 3; /* length of the illegal character encoding */ @@ -319,7 +322,7 @@ int fl_utf8encode(unsigned ucs, char* buf) { buf[1] = 0x80 | ((ucs >> 6) & 0x3F); buf[2] = 0x80 | (ucs & 0x3F); return 3; - } else if (ucs < 0x0010ffffU) { + } else if (ucs <= 0x0010ffffU) { buf[0] = 0xf0 | (ucs >> 18); buf[1] = 0x80 | ((ucs >> 12) & 0x3F); buf[2] = 0x80 | ((ucs >> 6) & 0x3F); @@ -412,7 +415,7 @@ unsigned fl_utf8toUtf16(const char* src, unsigned srclen, unsigned fl_utf8towc(const char* src, unsigned srclen, wchar_t* dst, unsigned dstlen) { -#ifdef _WIN32 +#ifdef WIN32 return fl_utf8toUtf16(src, srclen, (unsigned short*)dst, dstlen); #else const char* p = src; @@ -538,7 +541,7 @@ unsigned fl_utf8fromwc(char* dst, unsigned dstlen, if (count+2 >= dstlen) {dst[count] = 0; count += 2; break;} dst[count++] = 0xc0 | (ucs >> 6); dst[count++] = 0x80 | (ucs & 0x3F); -#ifdef _WIN32 +#ifdef WIN32 } else if (ucs >= 0xd800 && ucs <= 0xdbff && i < srclen && src[i] >= 0xdc00 && src[i] <= 0xdfff) { /* surrogate pair */ @@ -558,7 +561,7 @@ unsigned fl_utf8fromwc(char* dst, unsigned dstlen, dst[count++] = 0x80 | ((ucs >> 6) & 0x3F); dst[count++] = 0x80 | (ucs & 0x3F); } else { -#ifndef _WIN32 +#ifndef WIN32 J1: #endif /* all others are 3 bytes: */ @@ -575,7 +578,7 @@ unsigned fl_utf8fromwc(char* dst, unsigned dstlen, count++; } else if (ucs < 0x800U) { /* 2 bytes */ count += 2; -#ifdef _WIN32 +#ifdef WIN32 } else if (ucs >= 0xd800 && ucs <= 0xdbff && i < srclen-1 && src[i+1] >= 0xdc00 && src[i+1] <= 0xdfff) { /* surrogate pair */ @@ -641,7 +644,7 @@ unsigned fl_utf8froma(char* dst, unsigned dstlen, return count; } -#ifdef _WIN32 +#ifdef WIN32 # include #endif @@ -660,7 +663,7 @@ unsigned fl_utf8froma(char* dst, unsigned dstlen, int fl_utf8locale(void) { static int ret = 2; if (ret == 2) { -#ifdef _WIN32 +#ifdef WIN32 ret = GetACP() == CP_UTF8; #else char* s; @@ -696,7 +699,7 @@ unsigned fl_utf8to_mb(const char* src, unsigned srclen, char* dst, unsigned dstlen) { if (!fl_utf8locale()) { -#ifdef _WIN32 +#ifdef WIN32 wchar_t lbuf[1024]; wchar_t* buf = lbuf; unsigned length = fl_utf8towc(src, srclen, buf, 1024); @@ -772,14 +775,13 @@ unsigned fl_utf8from_mb(char* dst, unsigned dstlen, const char* src, unsigned srclen) { if (!fl_utf8locale()) { -#ifdef _WIN32 +#ifdef WIN32 wchar_t lbuf[1024]; wchar_t* buf = lbuf; unsigned length; unsigned ret; - length = - MultiByteToWideChar(GetACP(), 0, src, srclen, buf, 1024); - if (length >= 1024) { + length = MultiByteToWideChar(GetACP(), 0, src, srclen, buf, 1024); + if ((length == 0)&&(GetLastError()==ERROR_INSUFFICIENT_BUFFER)) { length = MultiByteToWideChar(GetACP(), 0, src, srclen, 0, 0); buf = (wchar_t*)(malloc(length*sizeof(wchar_t))); MultiByteToWideChar(GetACP(), 0, src, srclen, buf, length); @@ -795,7 +797,7 @@ unsigned fl_utf8from_mb(char* dst, unsigned dstlen, length = mbstowcs(buf, src, 1024); if (length >= 1024) { length = mbstowcs(0, src, 0)+1; - buf = (wchar_t*)(malloc(length*sizeof(unsigned short))); + buf = (wchar_t*)(malloc(length*sizeof(wchar_t))); mbstowcs(buf, src, length); } if (length >= 0) { @@ -854,4 +856,54 @@ int fl_utf8test(const char* src, unsigned srclen) { return ret; } +/* forward declare mk_wcwidth() as static so the name is not visible. + */ + static int mk_wcwidth(unsigned int ucs); + + /* include the c source directly so it's contents are only visible here + */ +#include "xutf8/mk_wcwidth.c" + +/** wrapper to adapt Markus Kuhn's implementation of wcwidth() for FLTK + \param [in] ucs Unicode character value + \returns width of character in columns + + See http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c for Markus Kuhn's + original implementation of wcwidth() and wcswidth() + (defined in IEEE Std 1002.1-2001) for Unicode. + + \b WARNING: this function returns widths for "raw" Unicode characters. + It does not even try to map C1 control characters (0x80 to 0x9F) to + CP1252, and C0/C1 control characters and DEL will return -1. + You are advised to use fl_width(const char* src) instead. + */ +int fl_wcwidth_(unsigned int ucs) { + return mk_wcwidth(ucs); +} + +/** extended wrapper around fl_wcwidth_(unsigned int ucs) function. + \param[in] src pointer to start of UTF-8 byte sequence + \returns width of character in columns + + Depending on build options, this function may map C1 control + characters (0x80 to 0x9f) to CP1252, and return the width of + that character instead. This is not the same behaviour as + fl_wcwidth_(unsigned int ucs) . + + Note that other control characters and DEL will still return -1, + so if you want different behaviour, you need to test for those + characters before calling fl_wcwidth(), and handle them separately. + */ +int fl_wcwidth(const char* src) { + int len = fl_utf8len(*src); + int ret = 0; + unsigned int ucs = fl_utf8decode(src, src+len, &ret); + int width = fl_wcwidth_(ucs); + return width; +} + /** @} */ + +/* + * End of "$Id: fl_utf.c 7609 2010-05-17 20:03:47Z engelsman $". + */ diff --git a/plugins/zynaddsubfx/fltk/src/fl_utf8.cxx b/plugins/zynaddsubfx/fltk/src/fl_utf8.cxx index 7634ca93b..8621c1f7e 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_utf8.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_utf8.cxx @@ -1,4 +1,5 @@ -// "$Id: $" +// +// "$Id: fl_utf8.cxx 6943 2009-11-18 12:43:21Z AlbrechtS $" // // Unicode to UTF-8 conversion functions. // @@ -822,6 +823,5 @@ void fl_make_path_for_file( const char *path ) /** @} */ // -// End of "$Id: $". +// End of "$Id: fl_utf8.cxx 6943 2009-11-18 12:43:21Z AlbrechtS $". // - diff --git a/plugins/zynaddsubfx/fltk/src/fl_vertex.cxx b/plugins/zynaddsubfx/fltk/src/fl_vertex.cxx index b21e24d5e..5b695a44e 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_vertex.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_vertex.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_vertex.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: fl_vertex.cxx 7617 2010-05-27 17:20:18Z manolo $" // // Portable drawing routines for the Fast Light Tool Kit (FLTK). // @@ -49,6 +49,7 @@ struct matrix {double a, b, c, d, x, y;}; static matrix m = {1, 0, 0, 1, 0, 0}; static matrix stack[32]; +matrix * fl_matrix = &m; static int sptr = 0; /** @@ -144,25 +145,13 @@ static int n; static int what; enum {LINE, LOOP, POLYGON, POINT_}; -/** - Starts drawing a list of points. Points are added to the list with fl_vertex() -*/ -void fl_begin_points() {n = 0; what = POINT_;} +void Fl_Graphics_Driver::begin_points() {n = 0; what = POINT_;} -/** - Starts drawing a list of lines. -*/ -void fl_begin_line() {n = 0; what = LINE;} +void Fl_Graphics_Driver::begin_line() {n = 0; what = LINE;} -/** - Starts drawing a closed sequence of lines. -*/ -void fl_begin_loop() {n = 0; what = LOOP;} +void Fl_Graphics_Driver::begin_loop() {n = 0; what = LOOP;} -/** - Starts drawing a convex filled polygon. -*/ -void fl_begin_polygon() {n = 0; what = POLYGON;} +void Fl_Graphics_Driver::begin_polygon() {n = 0; what = POLYGON;} /** Transforms coordinate using the current transformation matrix. @@ -200,11 +189,7 @@ static void fl_transformed_vertex(COORD_T x, COORD_T y) { } } -/** - Adds coordinate pair to the vertex list without further transformations. - \param[in] xf,yf transformed coordinate -*/ -void fl_transformed_vertex(double xf, double yf) { +void Fl_Graphics_Driver::transformed_vertex(double xf, double yf) { #ifdef __APPLE_QUARTZ__ fl_transformed_vertex(COORD_T(xf), COORD_T(yf)); #else @@ -212,39 +197,29 @@ void fl_transformed_vertex(double xf, double yf) { #endif } -/** - Adds a single vertex to the current path. - \param[in] x,y coordinate -*/ -void fl_vertex(double x,double y) { +void Fl_Graphics_Driver::vertex(double x,double y) { fl_transformed_vertex(x*m.a + y*m.c + m.x, x*m.b + y*m.d + m.y); } -/** - Ends list of points, and draws. -*/ -void fl_end_points() { +void Fl_Graphics_Driver::end_points() { #if defined(USE_X11) if (n>1) XDrawPoints(fl_display, fl_window, fl_gc, p, n, 0); #elif defined(WIN32) for (int i=0; i 1.5f) CGContextSetShouldAntialias(fl_gc, true); for (int i=0; i 1.5f) CGContextSetShouldAntialias(fl_gc, false); #else # error unsupported platform #endif } -/** - Ends list of lines, and draws. -*/ -void fl_end_line() { +void Fl_Graphics_Driver::end_line() { if (n < 2) { fl_end_points(); return; @@ -255,10 +230,12 @@ void fl_end_line() { if (n>1) Polyline(fl_gc, p, n); #elif defined(__APPLE_QUARTZ__) if (n<=1) return; + CGContextSetShouldAntialias(fl_gc, true); CGContextMoveToPoint(fl_gc, p[0].x, p[0].y); for (int i=1; i2 && p[n-1].x == p[0].x && p[n-1].y == p[0].y) n--; } -/** - Ends closed sequence of lines, and draws. -*/ -void fl_end_loop() { +void Fl_Graphics_Driver::end_loop() { fixloop(); if (n>2) fl_transformed_vertex((COORD_T)p[0].x, (COORD_T)p[0].y); fl_end_line(); } -/** - Ends convex filled polygon, and draws. -*/ -void fl_end_polygon() { +void Fl_Graphics_Driver::end_polygon() { fixloop(); if (n < 3) { fl_end_line(); @@ -295,67 +266,46 @@ void fl_end_polygon() { } #elif defined(__APPLE_QUARTZ__) if (n<=1) return; + CGContextSetShouldAntialias(fl_gc, true); CGContextMoveToPoint(fl_gc, p[0].x, p[0].y); for (int i=1; igap+2 && p[n-1].x == p[gap].x && p[n-1].y == p[gap].y) n--; - if (n > gap+2) { - fl_transformed_vertex((COORD_T)p[gap].x, (COORD_T)p[gap].y); +void Fl_Graphics_Driver::gap() { + while (n>gap_+2 && p[n-1].x == p[gap_].x && p[n-1].y == p[gap_].y) n--; + if (n > gap_+2) { + fl_transformed_vertex((COORD_T)p[gap_].x, (COORD_T)p[gap_].y); #if defined(WIN32) - counts[numcount++] = n-gap; + counts[numcount++] = n-gap_; #endif - gap = n; + gap_ = n; } else { - n = gap; + n = gap_; } } -/** - Ends complex filled polygon, and draws. -*/ -void fl_end_complex_polygon() { +void Fl_Graphics_Driver::end_complex_polygon() { fl_gap(); if (n < 3) { fl_end_line(); @@ -370,11 +320,13 @@ void fl_end_complex_polygon() { } #elif defined(__APPLE_QUARTZ__) if (n<=1) return; + CGContextSetShouldAntialias(fl_gc, true); CGContextMoveToPoint(fl_gc, p[0].x, p[0].y); for (int i=1; i which unfortunatly does not play well otherwise - * when included - to be resolved... - */ - -# if defined(__APPLE__) && defined(__MWERKS__) && defined(_MSL_USING_MW_C_HEADERS) -int strcasecmp(const char*,const char*); -int strncasecmp(const char*,const char*,int); -char *strdup(const char*); -# endif - FL_EXPORT extern int fl_snprintf(char *, size_t, const char *, ...); # if !HAVE_SNPRINTF # define snprintf fl_snprintf @@ -112,5 +100,5 @@ FL_EXPORT extern size_t fl_strlcpy(char *, const char *, size_t); /* - * End of "$Id: flstring.h 6680 2009-03-14 02:11:31Z greg.ercolano $". + * End of "$Id: flstring.h 7352 2010-03-29 10:47:11Z matt $". */ diff --git a/plugins/zynaddsubfx/fltk/src/print_panel.cxx b/plugins/zynaddsubfx/fltk/src/print_panel.cxx new file mode 100644 index 000000000..d9d87817e --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/print_panel.cxx @@ -0,0 +1,598 @@ +// +// "$Id: print_panel.cxx 7480 2010-04-11 18:42:35Z AlbrechtS $" +// +// Print panel for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// +// This file is "work in progress". The main parts have been copied +// from fluid's print_panel{.fl|.h|.cxx} and hand-edited to produce +// a working version w/o global variables. The intention is to move +// all static variables into an own class, and to name this class +// Fl_Printer_Chooser or similar... +// +// Todo: +// +// - Currently preferences can't be saved, and there are options that +// are not yet used for printing. +// - This file can only be used as an include file in Fl_PS_Printer.cxx +// - The use of static variables should be avoided. +// - Probably much more ... +// + +#include "print_panel.h" +#include +#include +#include "../src/flstring.h" +#include +#include + +static Fl_Preferences print_prefs(Fl_Preferences::USER, "fltk.org", "printers"); +static Fl_Double_Window *print_panel=(Fl_Double_Window *)0; +static Fl_Group *print_panel_controls=(Fl_Group *)0; +static Fl_Choice *print_choice=(Fl_Choice *)0; +static Fl_Button *print_properties=(Fl_Button *)0; +static Fl_Box *print_status=(Fl_Box *)0; +static Fl_Round_Button *print_all=(Fl_Round_Button *)0; +static Fl_Round_Button *print_pages=(Fl_Round_Button *)0; +static Fl_Round_Button *print_selection=(Fl_Round_Button *)0; +static Fl_Check_Button *print_collate_button=(Fl_Check_Button *)0; +static Fl_Group *print_collate_group[2]={(Fl_Group *)0}; +static Fl_Progress *print_progress=(Fl_Progress *)0; +static Fl_Double_Window *print_properties_panel=(Fl_Double_Window *)0; +static Fl_Choice *print_page_size=(Fl_Choice *)0; +static Fl_Int_Input *print_from=(Fl_Int_Input *)0; +static Fl_Int_Input *print_to=(Fl_Int_Input *)0; +static Fl_Spinner *print_copies=(Fl_Spinner *)0; + +static int print_start = 0; // 1 if print_okay has been clicked +static int print_pipe = 0; // 0 = file, 1 = pipe (lp) + +static void cb_print_choice(Fl_Choice*, void*) { + print_update_status(); +} + +static void cb_print_properties(Fl_Button*, void*) { + print_properties_panel->show(); +} + +static void cb_print_all(Fl_Round_Button*, void*) { + print_from->deactivate(); + print_to->deactivate(); +} + +static void cb_print_pages(Fl_Round_Button*, void*) { + print_from->activate(); + print_to->activate(); +} + +static void cb_print_selection(Fl_Round_Button*, void*) { + print_from->deactivate(); + print_to->deactivate(); +} + +static void cb_print_copies(Fl_Spinner*, void*) { + if (print_copies->value() == 1) { + print_collate_button->deactivate(); + print_collate_group[0]->deactivate(); + print_collate_group[1]->deactivate(); + } else { +/* print_collate_button->activate(); // TODO: manage collate options + print_collate_group[0]->activate(); + print_collate_group[1]->activate(); */ + }; +} + +static void cb_print_collate_button(Fl_Check_Button*, void*) { + int i = print_collate_button->value() != 0; + print_collate_group[i]->show(); + print_collate_group[1 - i]->hide(); +} + +static void cb_Cancel(Fl_Button*, void*) { + print_start = 0; + print_panel->hide(); +} + +static void cb_print_properties_panel(Fl_Double_Window*, void*) { + print_properties_panel->hide(); + print_update_status(); +} + +static Fl_Menu_Item menu_print_page_size[] = { + {"Letter", 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {"A4", 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +#include +static const char *idata_print_color[] = { +"24 24 17 1", +" \tc None", +".\tc #FFFF00", +"+\tc #C8FF00", +"@\tc #00FF00", +"#\tc #FFC800", +"$\tc #FF0000", +"%\tc #00FFFF", +"&\tc #000000", +"*\tc #FF00FF", +"=\tc #00FFC8", +"-\tc #FF00C8", +";\tc #00C800", +">\tc #C80000", +",\tc #0000C8", +"\'\tc #0000FF", +")\tc #00C8FF", +"!\tc #C800FF", +" ...... ", +" .......... ", +" ............ ", +" .............. ", +" .............. ", +" ................ ", +" ................ ", +" ................ ", +" +@@@@@@+#$$$$$$# ", +" %@@@@@@@&&$$$$$$$* ", +" %%@@@@@@&&&&$$$$$$** ", +" %%%=@@@@&&&&&&$$$$-*** ", +" %%%%@@@;&&&&&&>$$$**** ", +"%%%%%%@@&&&&&&&&$$******", +"%%%%%%%@&&&&&&&&$*******", +"%%%%%%%%,&&&&&&,********", +"%%%%%%%%\'\'\'\'\'\'\'\'********", +"%%%%%%%%\'\'\'\'\'\'\'\'********", +"%%%%%%%%\'\'\'\'\'\'\'\'********", +" %%%%%%%)\'\'\'\'\'\'!******* ", +" %%%%%%%%\'\'\'\'\'\'******** ", +" %%%%%%%%\'\'\'\'******** ", +" %%%%%%%%\'\'******** ", +" %%%%%% ****** " +}; +static Fl_Pixmap image_print_color(idata_print_color); + +static const char *idata_print_gray[] = { +"24 24 17 1", +" \tc None", +".\tc #E3E3E3", +"+\tc #D2D2D2", +"@\tc #969696", +"#\tc #C2C2C2", +"$\tc #4C4C4C", +"%\tc #B2B2B2", +"&\tc #000000", +"*\tc #696969", +"=\tc #ACACAC", +"-\tc #626262", +";\tc #767676", +">\tc #3C3C3C", +",\tc #161616", +"\'\tc #1C1C1C", +")\tc #929292", +"!\tc #585858", +" ...... ", +" .......... ", +" ............ ", +" .............. ", +" .............. ", +" ................ ", +" ................ ", +" ................ ", +" +@@@@@@+#$$$$$$# ", +" %@@@@@@@&&$$$$$$$* ", +" %%@@@@@@&&&&$$$$$$** ", +" %%%=@@@@&&&&&&$$$$-*** ", +" %%%%@@@;&&&&&&>$$$**** ", +"%%%%%%@@&&&&&&&&$$******", +"%%%%%%%@&&&&&&&&$*******", +"%%%%%%%%,&&&&&&,********", +"%%%%%%%%\'\'\'\'\'\'\'\'********", +"%%%%%%%%\'\'\'\'\'\'\'\'********", +"%%%%%%%%\'\'\'\'\'\'\'\'********", +" %%%%%%%)\'\'\'\'\'\'!******* ", +" %%%%%%%%\'\'\'\'\'\'******** ", +" %%%%%%%%\'\'\'\'******** ", +" %%%%%%%%\'\'******** ", +" %%%%%% ****** " +}; +static Fl_Pixmap image_print_gray(idata_print_gray); + +static Fl_Button *print_output_mode[4]={(Fl_Button *)0}; + +static void cb_Save(Fl_Return_Button*, void*) { + print_properties_panel->hide(); + + char name[1024]; + int val; + const char *printer = (const char *)print_choice->menu()[print_choice->value()].user_data(); + + snprintf(name, sizeof(name), "%s/page_size", printer); + print_prefs.set(name, print_page_size->value()); + + snprintf(name, sizeof(name), "%s/output_mode", printer); + for (val = 0; val < 4; val ++) { + if (print_output_mode[val]->value()) break; + } + print_prefs.set(name, val); +} + +static void cb_Cancel1(Fl_Button*, void*) { + print_properties_panel->hide(); + print_update_status(); +} + +static void cb_Use(Fl_Button*, void*) { + print_properties_panel->hide(); +} + +Fl_Double_Window* make_print_panel() { + { print_panel = new Fl_Double_Window(465, 235, Fl_Printer::dialog_title); + { print_panel_controls = new Fl_Group(10, 10, 447, 216); + { print_choice = new Fl_Choice(133, 10, 181, 25, Fl_Printer::dialog_printer); + print_choice->down_box(FL_BORDER_BOX); + print_choice->labelfont(1); + print_choice->callback((Fl_Callback*)cb_print_choice); + print_choice->when(FL_WHEN_CHANGED); + } // Fl_Choice* print_choice + { print_properties = new Fl_Button(314, 10, 115, 25, Fl_Printer::dialog_properties); + print_properties->callback((Fl_Callback*)cb_print_properties); + } // Fl_Button* print_properties + { print_status = new Fl_Box(0, 41, print_panel_controls->w(), 17, "printer/job status"); + print_status->align(Fl_Align(FL_ALIGN_CLIP|FL_ALIGN_INSIDE|FL_ALIGN_LEFT)); + } // Fl_Box* print_status + { Fl_Group* o = new Fl_Group(10, 86, 227, 105, Fl_Printer::dialog_range); + o->box(FL_THIN_DOWN_BOX); + o->labelfont(1); + o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); + { print_all = new Fl_Round_Button(20, 96, 38, 25, Fl_Printer::dialog_all); + print_all->type(102); + print_all->down_box(FL_ROUND_DOWN_BOX); + print_all->value(1); + print_all->callback((Fl_Callback*)cb_print_all); + } // Fl_Round_Button* print_all + { print_pages = new Fl_Round_Button(20, 126, 64, 25, Fl_Printer::dialog_pages); + print_pages->type(102); + print_pages->down_box(FL_ROUND_DOWN_BOX); + print_pages->callback((Fl_Callback*)cb_print_pages); + } // Fl_Round_Button* print_pages + { print_selection = new Fl_Round_Button(20, 156, 82, 25, "Selection"); + print_selection->type(102); + print_selection->down_box(FL_ROUND_DOWN_BOX); + print_selection->callback((Fl_Callback*)cb_print_selection); + } // Fl_Round_Button* print_selection + { print_from = new Fl_Int_Input(136, 126, 28, 25, Fl_Printer::dialog_from); + print_from->type(2); + print_from->textfont(4); + print_from->deactivate(); + } // Fl_Int_Input* print_from + { print_to = new Fl_Int_Input(199, 126, 28, 25, Fl_Printer::dialog_to); + print_to->type(2); + print_to->textfont(4); + print_to->deactivate(); + } // Fl_Int_Input* print_to + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(247, 86, 210, 105, Fl_Printer::dialog_copies); + o->box(FL_THIN_DOWN_BOX); + o->labelfont(1); + o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); + { print_copies = new Fl_Spinner(321, 96, 45, 25, Fl_Printer::dialog_copyNo); + print_copies->callback((Fl_Callback*)cb_print_copies); + print_copies->when(FL_WHEN_CHANGED); + } // Fl_Spinner* print_copies + { print_collate_button = new Fl_Check_Button(376, 96, 64, 25, "Collate"); + print_collate_button->down_box(FL_DOWN_BOX); + print_collate_button->callback((Fl_Callback*)cb_print_collate_button); + print_collate_button->when(FL_WHEN_CHANGED); + print_collate_button->deactivate(); + } // Fl_Check_Button* print_collate_button + { print_collate_group[0] = new Fl_Group(257, 131, 191, 50); + print_collate_group[0]->deactivate(); + { Fl_Box* o = new Fl_Box(287, 141, 30, 40, "1"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + o->deactivate(); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(272, 136, 30, 40, "1"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + o->deactivate(); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(257, 131, 30, 40, "1"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + o->deactivate(); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(352, 141, 30, 40, "2"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + o->deactivate(); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(337, 136, 30, 40, "2"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + o->deactivate(); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(322, 131, 30, 40, "2"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + o->deactivate(); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(417, 141, 30, 40, "3"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + o->deactivate(); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(402, 136, 30, 40, "3"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + o->deactivate(); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(387, 131, 30, 40, "3"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + o->deactivate(); + } // Fl_Box* o + print_collate_group[0]->end(); + } // Fl_Group* print_collate_group[0] + { print_collate_group[1] = new Fl_Group(257, 131, 191, 50); + print_collate_group[1]->hide(); + print_collate_group[1]->deactivate(); + { Fl_Box* o = new Fl_Box(287, 141, 30, 40, "3"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(272, 136, 30, 40, "2"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(257, 131, 30, 40, "1"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(352, 141, 30, 40, "3"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(337, 136, 30, 40, "2"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(322, 131, 30, 40, "1"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(417, 141, 30, 40, "3"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(402, 136, 30, 40, "2"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(387, 131, 30, 40, "1"); + o->box(FL_BORDER_BOX); + o->color(FL_BACKGROUND2_COLOR); + o->labelsize(11); + o->align(Fl_Align(FL_ALIGN_BOTTOM_RIGHT|FL_ALIGN_INSIDE)); + } // Fl_Box* o + print_collate_group[1]->end(); + } // Fl_Group* print_collate_group[1] + o->end(); + } // Fl_Group* o + { Fl_Return_Button* o = new Fl_Return_Button(279, 201, 100, 25, Fl_Printer::dialog_print_button); + o->callback((Fl_Callback*)print_cb); + } // Fl_Return_Button* o + { Fl_Button* o = new Fl_Button(389, 201, 68, 25, Fl_Printer::dialog_cancel_button); + o->callback((Fl_Callback*)cb_Cancel); + } // Fl_Button* o + print_panel_controls->end(); + } // Fl_Group* print_panel_controls + { print_progress = new Fl_Progress(10, 203, 289, 21); + print_progress->selection_color((Fl_Color)4); + print_progress->hide(); + } // Fl_Progress* print_progress + print_panel->set_modal(); + print_panel->end(); + } // Fl_Double_Window* print_panel + { print_properties_panel = new Fl_Double_Window(290, 130, Fl_Printer::property_title); + print_properties_panel->callback((Fl_Callback*)cb_print_properties_panel); + { print_page_size = new Fl_Choice(150, 10, 80, 25, Fl_Printer::property_pagesize); + print_page_size->down_box(FL_BORDER_BOX); + print_page_size->labelfont(FL_HELVETICA); + print_page_size->menu(menu_print_page_size); + } // Fl_Choice* print_page_size + { Fl_Group* o = new Fl_Group(110, 45, 170, 40, Fl_Printer::property_mode); + o->labelfont(FL_HELVETICA); + o->align(Fl_Align(FL_ALIGN_LEFT)); + { print_output_mode[0] = new Fl_Button(110, 45, 30, 40); + print_output_mode[0]->type(102); + print_output_mode[0]->box(FL_BORDER_BOX); + print_output_mode[0]->down_box(FL_BORDER_BOX); + print_output_mode[0]->value(1); + print_output_mode[0]->color(FL_BACKGROUND2_COLOR); + print_output_mode[0]->selection_color(FL_FOREGROUND_COLOR); + print_output_mode[0]->image(image_print_color); + } // Fl_Button* print_output_mode[0] + { print_output_mode[1] = new Fl_Button(150, 50, 40, 30); + print_output_mode[1]->type(102); + print_output_mode[1]->box(FL_BORDER_BOX); + print_output_mode[1]->down_box(FL_BORDER_BOX); + print_output_mode[1]->color(FL_BACKGROUND2_COLOR); + print_output_mode[1]->selection_color(FL_FOREGROUND_COLOR); + print_output_mode[1]->image(image_print_color); + } // Fl_Button* print_output_mode[1] + { print_output_mode[2] = new Fl_Button(200, 45, 30, 40); + print_output_mode[2]->type(102); + print_output_mode[2]->box(FL_BORDER_BOX); + print_output_mode[2]->down_box(FL_BORDER_BOX); + print_output_mode[2]->color(FL_BACKGROUND2_COLOR); + print_output_mode[2]->selection_color(FL_FOREGROUND_COLOR); + print_output_mode[2]->image(image_print_gray); + } // Fl_Button* print_output_mode[2] + { print_output_mode[3] = new Fl_Button(240, 50, 40, 30); + print_output_mode[3]->type(102); + print_output_mode[3]->box(FL_BORDER_BOX); + print_output_mode[3]->down_box(FL_BORDER_BOX); + print_output_mode[3]->color(FL_BACKGROUND2_COLOR); + print_output_mode[3]->selection_color(FL_FOREGROUND_COLOR); + print_output_mode[3]->image(image_print_gray); + } // Fl_Button* print_output_mode[3] + o->end(); + } // Fl_Group* o + { Fl_Return_Button* o = new Fl_Return_Button(93, 95, 99, 25, Fl_Printer::property_save); + o->callback((Fl_Callback*)cb_Save); + } // Fl_Return_Button* o + { Fl_Button* o = new Fl_Button(202, 95, 78, 25, Fl_Printer::property_cancel); + o->callback((Fl_Callback*)cb_Cancel1); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(10, 95, 73, 25, Fl_Printer::property_use); + o->callback((Fl_Callback*)cb_Use); + } // Fl_Button* o + print_properties_panel->set_modal(); + print_properties_panel->end(); + } // Fl_Double_Window* print_properties_panel + return print_properties_panel; +} + +void print_cb(Fl_Return_Button *, void *) { + print_start = 1; + print_panel->hide(); +} + +void print_load() { + FILE *lpstat; + char line[1024], name[1024], *nptr, qname[2048], *qptr, defname[1024]; + int i; + + if (print_choice->size() > 1) { + for (i = 1; print_choice->text(i); i ++) { + free(print_choice->menu()[i].user_data()); + } + } + + print_choice->clear(); + print_choice->add(Fl_Printer::dialog_print_to_file, 0, 0, 0, FL_MENU_DIVIDER); + print_choice->value(0); + + print_start = 0; + + defname[0] = '\0'; + + if ((lpstat = popen("LC_MESSAGES=C LANG=C lpstat -p -d", "r")) != NULL) { + while (fgets(line, sizeof(line), lpstat)) { + if (!strncmp(line, "printer ", 8) && + sscanf(line + 8, "%s", name) == 1) { + for (nptr = name, qptr = qname; *nptr; *qptr++ = *nptr++) { + if (*nptr == '/') *qptr++ = '\\'; + } + *qptr = '\0'; + + print_choice->add(qname, 0, 0, (void *)strdup(name), 0); + } else if (!strncmp(line, "system default destination: ", 28)) { + if (sscanf(line + 28, "%s", defname) != 1) defname[0] = '\0'; + } + } + pclose(lpstat); + } + + if (defname[0]) { + for (i = 1; print_choice->text(i); i ++) { + if (!strcmp((char *)print_choice->menu()[i].user_data(), defname)) { + print_choice->value(i); + break; + } + } + } else if (print_choice->size() > 2) print_choice->value(1); + + print_update_status(); + +} // print_load() + +void print_update_status() { + FILE *lpstat; + char command[1024]; + static char status[1024]; + const char *printer = (const char *)print_choice->menu()[print_choice->value()].user_data(); + + if (print_choice->value()) { + snprintf(command, sizeof(command), "lpstat -p '%s'", printer); + if ((lpstat = popen(command, "r")) != NULL) { + fgets(status, sizeof(status), lpstat); + pclose(lpstat); + } else strcpy(status, "printer status unavailable"); + } else status[0] = '\0'; + + print_status->label(status); + + char name[1024]; + int val; + + snprintf(name, sizeof(name), "%s/page_size", printer); + print_prefs.get(name, val, 1); + print_page_size->value(val); + + snprintf(name, sizeof(name), "%s/output_mode", printer); + print_prefs.get(name, val, 0); + print_output_mode[val]->setonly(); +} + +// +// End of "$Id: print_panel.cxx 7480 2010-04-11 18:42:35Z AlbrechtS $". +// diff --git a/plugins/zynaddsubfx/fltk/src/print_panel.h b/plugins/zynaddsubfx/fltk/src/print_panel.h new file mode 100644 index 000000000..7c7ae6237 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/print_panel.h @@ -0,0 +1,55 @@ +// +// "$Id: print_panel.h 7263 2010-03-14 18:07:24Z AlbrechtS $" +// +// Print panel for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2009 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// +// This is a temporary file. It is only for development and will +// probably be removed later. +// + +#ifndef print_panel_h +#define print_panel_h +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +static Fl_Double_Window* make_print_panel(); +static void print_cb(Fl_Return_Button *, void *); +static void print_load(); +static void print_update_status(); +#endif + +// +// End of "$Id: print_panel.h 7263 2010-03-14 18:07:24Z AlbrechtS $". +// diff --git a/plugins/zynaddsubfx/fltk/src/ps_image.cxx b/plugins/zynaddsubfx/fltk/src/ps_image.cxx new file mode 100644 index 000000000..51646efa6 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/ps_image.cxx @@ -0,0 +1,553 @@ +// +// "$Id: image.cxx 4324 2005-05-09 21:47:22Z rokan $" +// +// Postscript image drawing implementation for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef FL_DOXYGEN + +#include +#include +#include + +#include +#include +#include +#include + +int Fl_PostScript_Graphics_Driver::alpha_mask(const uchar * data, int w, int h, int D, int LD){ + + mask = 0; + if((D/2)*2 != D){ //no mask info + return 0; + } + int xx; + int i,j, k, l; + LD += w*D; + int V255=0; + int V0 =0; + int V_=0; +// uchar d; + for(j=0;j127){ + mask[jj*xx+ii/8] |= 1 << (ii % 8); //set mask bit + error = val-255; + }else + error = val; + + ////// error spreading ///// + if(error >0){ + next[ii] += o1 = (error * 3 + 8)/16; + current[ii+2] += o2 = (error * 7 + 8)/16; + next[ii+2] = o3 =(error + 8)/16; // *1 - ok replacing (cleaning) + }else{ + next[ii] += o1 = (error * 3 - 8)/16; + current[ii+2] += o2 = (error * 7 - 8)/16; + next[ii+2] = o3 = (error - 8)/16; + } + next[1+ii] += error - o1 - o2 - o3; + } + } + l++; + + ////// backward + + jj = j*4+l; + swap = next; + next = current; + current = swap; + *(next+1) = 0; // must clean the first cell, next are overriden by *1 + + for(i=w-1;i>=0;i--){ + + for(k=3;k>=0;k--){ // generating 4 x-pixels for 1 RGB + short error, o1, o2, o3; + + int ii = i*4+k; // mask cell index + short val = data[j*LD+D*i+D-1] + current[1+ii]; + if (val>127){ + + mask[jj*xx+ii/8] |= 1 << (ii % 8); //set mask bit + error = val-255; + }else + error = val; + + ////// error spreading ///// + if(error >0){ + next[ii+2] += o1 = (error * 3 + 8)/16; + current[ii] += o2 = (error * 7 + 8)/16; + next[ii] = o3 =(error + 8)/16; // *1 - ok replacing (cleaning) + }else{ + next[ii+2] += o1 = (error * 3 - 8)/16; + + current[ii] += o2 = (error * 7 - 8)/16; + next[ii] = o3 = (error - 8)/16; + } + next[1+ii] += error - o1 - o2 - o3; + } + } + l++; + } + } + delete[] errors1; + delete[] errors2; + return 0; +} + +// bitwise inversion of all 4-bit quantities +static const unsigned char swapped[16] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15}; + +// bitwise inversion of a byte +static inline uchar swap_byte(const uchar b) { + return (swapped[b & 0xF] << 4) | swapped[b >> 4]; +} + + +extern uchar **fl_mask_bitmap; + + +void Fl_PostScript_Graphics_Driver::draw_scaled_image(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D, int LD) { + + + if(D<3){ //mono + draw_scaled_image_mono(data, x, y, w, h, iw, ih, D, LD); + return; + } + + + int i,j, k; + + fprintf(output,"save\n"); + + const char * interpol; + if(lang_level_>1){ + if(interpolate_) + interpol="true"; + else + interpol="false"; + if(mask && lang_level_>2) + fprintf(output, "%g %g %g %g %i %i %i %i %s CIM\n", x , y+h , w , -h , iw , ih, mx, my, interpol); + else + fprintf(output, "%g %g %g %g %i %i %s CII\n", x , y+h , w , -h , iw , ih, interpol); + }else + fprintf(output , "%g %g %g %g %i %i CI", x , y+h , w , -h , iw , ih); + + + if(!LD) LD = iw*D; + uchar *curmask=mask; + + for (j=0; j3) { //can do mixing using bg_* colors) + unsigned int a2 = curdata[3]; //must be int + unsigned int a = 255-a2; + r = (a2 * r + bg_r * a)/255; + g = (a2 * g + bg_g * a)/255; + b = (a2 * b + bg_b * a)/255; + } + if (!(i%40)) fprintf(output, "\n"); + fprintf(output, "%.2x%.2x%.2x", r, g, b); + curdata +=D; + } + fprintf(output,"\n"); + + } + + fprintf(output," >\nrestore\n" ); + + +}; + +void Fl_PostScript_Graphics_Driver::draw_scaled_image(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D) { + + int level2_mask = 0; + fprintf(output,"save\n"); + int i,j,k; + const char * interpol; + if (lang_level_ > 1) { + if (interpolate_) interpol="true"; + else interpol="false"; + if (mask && lang_level_ > 2) { + fprintf(output, "%g %g %g %g %i %i %i %i %s CIM\n", x , y+h , w , -h , iw , ih, mx, my, interpol); + } + else if (mask && lang_level_ == 2) { + level2_mask = 1; // use method for drawing masked color image with PostScript level 2 + fprintf(output, "%d %d pixmap_size\n pixmap_loadmask\n", iw, ih); + } + else { + fprintf(output, "%g %g %g %g %i %i %s CII\n", x , y+h , w , -h , iw , ih, interpol); + } + } else { + fprintf(output , "%g %g %g %g %i %i CI", x , y+h , w , -h , iw , ih); + } + + int LD=iw*D; + uchar *rgbdata=new uchar[LD]; + uchar *curmask=mask; + + if(level2_mask) { + for (j = ih - 1; j >= 0; j--) { + curmask = mask + j * my/ih * ((mx+7)/8); + for(k=0; k < my/ih; k++) { // output mask data + for (i=0; i < ((mx+7)/8); i++) { + fprintf(output, "%.2x",swap_byte(*curmask)); + curmask++; + } + fprintf(output,"\n"); + } + } + fprintf(output,"pop def\n\npixmap_loaddata\n"); + for (j = ih - 1; j >= 0; j--) { // output full image data + call(data,0,j,iw,rgbdata); + uchar *curdata=rgbdata; + for(i=0 ; i 2) { // InterleaveType 2 mask data + for(k=0; k\n"); + } + + fprintf(output,"restore\n"); + delete[] rgbdata; +} + +void Fl_PostScript_Graphics_Driver::draw_scaled_image_mono(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D, int LD) { + + fprintf(output,"save\n"); + + int i,j, k; + + const char * interpol; + if(lang_level_>1){ + if(interpolate_) + interpol="true"; + else + interpol="false"; + if(mask && lang_level_>2) + fprintf(output, "%g %g %g %g %i %i %i %i %s GIM\n", x , y+h , w , -h , iw , ih, mx, my, interpol); + else + fprintf(output, "%g %g %g %g %i %i %s GII\n", x , y+h , w , -h , iw , ih, interpol); + }else + fprintf(output , "%g %g %g %g %i %i GI", x , y+h , w , -h , iw , ih); + + + if(!LD) LD = iw*D; + + + int bg = (bg_r + bg_g + bg_b)/3; + + uchar *curmask=mask; + for (j=0; j1) { //can do mixing + + unsigned int a2 = curdata[1]; //must be int + unsigned int a = 255-a2; + r = (a2 * r + bg * a)/255; + } + if (!(i%120)) fprintf(output, "\n"); + fprintf(output, "%.2x", r); + curdata +=D; + } + fprintf(output,"\n"); + + } + + fprintf(output," >\nrestore\n" ); + +}; + + + +void Fl_PostScript_Graphics_Driver::draw_scaled_image_mono(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D) { + + fprintf(output,"save\n"); + int i,j,k; + const char * interpol; + if(lang_level_>1){ + if(interpolate_) interpol="true"; + else interpol="false"; + if(mask && lang_level_>2) + fprintf(output, "%g %g %g %g %i %i %i %i %s GIM\n", x , y+h , w , -h , iw , ih, mx, my, interpol); + else + fprintf(output, "%g %g %g %g %i %i %s GII\n", x , y+h , w , -h , iw , ih, interpol); + }else + fprintf(output , "%g %g %g %g %i %i GI", x , y+h , w , -h , iw , ih); + + int LD=iw*D; + uchar *rgbdata=new uchar[LD]; + uchar *curmask=mask; + for (j=0; j2){ // InterleaveType 2 mask data + for(k=0; k\n"); + fprintf(output,"restore\n"); + delete[] rgbdata; +} + + +////////////////////////////// Image classes ////////////////////// + + +void Fl_PostScript_Graphics_Driver::draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy){ + const char * const * di =pxm->data(); + int w,h; + if (!fl_measure_pixmap(di, w, h)) return; + mask=0; + fl_mask_bitmap=&mask; + mx = WP; + my = HP; + push_clip(XP, YP, WP, HP); + fl_draw_pixmap(di,XP -cx, YP -cy, FL_BLACK ); + pop_clip(); + delete[] mask; + mask=0; + fl_mask_bitmap=0; +}; + +void Fl_PostScript_Graphics_Driver::draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy){ + const uchar * di = rgb->array; + int w = rgb->w(); + int h = rgb->h(); + mask=0; + if(lang_level_>2) //when not true, not making alphamask, mixing colors instead... + if (alpha_mask(di, w, h, rgb->d(),rgb->ld())) return; //everthing masked, no need for painting! + push_clip(XP, YP, WP, HP); + draw_scaled_image(di, XP + cx, YP + cy, w, h, w, h, rgb->d(), rgb->ld()); + pop_clip(); + delete[]mask; + mask=0; +}; + +void Fl_PostScript_Graphics_Driver::draw(Fl_Bitmap * bitmap,int XP, int YP, int WP, int HP, int cx, int cy){ + const uchar * di = bitmap->array; + int w,h; + int LD=(bitmap->w()+7)/8; + int xx; + + if (WP> bitmap->w() - cx){// to assure that it does not go out of bounds; + w = bitmap->w() - cx; + xx = (bitmap->w()+7)/8 - cx/8; //length of mask in bytes + }else{ + w =WP; + xx = (w+7)/8 - cx/8; + } + if( HP > bitmap->h()-cy) + h = bitmap->h() - cy; + else + h = HP; + + di += cy*LD + cx/8; + int si = cx % 8; // small shift to be clipped, it is simpler than shifting whole mask + + int i,j; + push_clip(XP, YP, WP, HP); + fprintf(output , "%i %i %i %i %i %i MI", XP - si, YP + HP , WP , -HP , w , h); + + for (j=0; j\n"); + pop_clip(); +}; + +#endif // FL_DOXYGEN + +// +// End of "$Id: image.cxx 4324 2005-05-09 21:47:22Z rokan $" +// + + + + + + + + + + + + + + + + + + diff --git a/plugins/zynaddsubfx/fltk/src/screen_xywh.cxx b/plugins/zynaddsubfx/fltk/src/screen_xywh.cxx index fa7e1e139..a6446e978 100644 --- a/plugins/zynaddsubfx/fltk/src/screen_xywh.cxx +++ b/plugins/zynaddsubfx/fltk/src/screen_xywh.cxx @@ -1,5 +1,5 @@ // -// "$Id: screen_xywh.cxx 6716 2009-03-24 01:40:44Z fabien $" +// "$Id: screen_xywh.cxx 7351 2010-03-29 10:35:00Z matt $" // // Screen/monitor bounding box API for the Fast Light Tool Kit (FLTK). // @@ -107,19 +107,9 @@ static void screen_init() { #elif defined(__APPLE__) XRectangle screens[16]; +extern int MACscreen_init(XRectangle screens[]); static void screen_init() { - GDHandle gd; - - for (gd = GetDeviceList(), num_screens = 0; gd; gd = GetNextDevice(gd)) { - GDPtr gp = *gd; - screens[num_screens].x = gp->gdRect.left; - screens[num_screens].y = gp->gdRect.top; - screens[num_screens].width = gp->gdRect.right - gp->gdRect.left; - screens[num_screens].height = gp->gdRect.bottom - gp->gdRect.top; - - num_screens ++; - if (num_screens >= 16) break; - } + num_screens = MACscreen_init(screens); } #elif HAVE_XINERAMA # include @@ -264,5 +254,5 @@ void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int n) { // -// End of "$Id: screen_xywh.cxx 6716 2009-03-24 01:40:44Z fabien $". +// End of "$Id: screen_xywh.cxx 7351 2010-03-29 10:35:00Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/xutf8/mk_wcwidth.c b/plugins/zynaddsubfx/fltk/src/xutf8/mk_wcwidth.c new file mode 100644 index 000000000..0c4eb2cc9 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/xutf8/mk_wcwidth.c @@ -0,0 +1,353 @@ +/* + * FLTK: Important! + * This file should remain as close to Markus Kuhn's original source + * as possible for easy checking for changes later, however unlikely. + * All customisations to work with FLTK shall be annotated! + */ + +/* + * This is an implementation of wcwidth() and wcswidth() (defined in + * IEEE Std 1002.1-2001) for Unicode. + * + * http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html + * http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html + * + * In fixed-width output devices, Latin characters all occupy a single + * "cell" position of equal width, whereas ideographic CJK characters + * occupy two such cells. Interoperability between terminal-line + * applications and (teletype-style) character terminals using the + * UTF-8 encoding requires agreement on which character should advance + * the cursor by how many cell positions. No established formal + * standards exist at present on which Unicode character shall occupy + * how many cell positions on character terminals. These routines are + * a first attempt of defining such behavior based on simple rules + * applied to data provided by the Unicode Consortium. + * + * For some graphical characters, the Unicode standard explicitly + * defines a character-cell width via the definition of the East Asian + * FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes. + * In all these cases, there is no ambiguity about which width a + * terminal shall use. For characters in the East Asian Ambiguous (A) + * class, the width choice depends purely on a preference of backward + * compatibility with either historic CJK or Western practice. + * Choosing single-width for these characters is easy to justify as + * the appropriate long-term solution, as the CJK practice of + * displaying these characters as double-width comes from historic + * implementation simplicity (8-bit encoded characters were displayed + * single-width and 16-bit ones double-width, even for Greek, + * Cyrillic, etc.) and not any typographic considerations. + * + * Much less clear is the choice of width for the Not East Asian + * (Neutral) class. Existing practice does not dictate a width for any + * of these characters. It would nevertheless make sense + * typographically to allocate two character cells to characters such + * as for instance EM SPACE or VOLUME INTEGRAL, which cannot be + * represented adequately with a single-width glyph. The following + * routines at present merely assign a single-cell width to all + * neutral characters, in the interest of simplicity. This is not + * entirely satisfactory and should be reconsidered before + * establishing a formal standard in this area. At the moment, the + * decision which Not East Asian (Neutral) characters should be + * represented by double-width glyphs cannot yet be answered by + * applying a simple rule from the Unicode database content. Setting + * up a proper standard for the behavior of UTF-8 character terminals + * will require a careful analysis not only of each Unicode character, + * but also of each presentation form, something the author of these + * routines has avoided to do so far. + * + * http://www.unicode.org/unicode/reports/tr11/ + * + * Markus Kuhn -- 2007-05-26 (Unicode 5.0) + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted. The author + * disclaims all warranties with regard to this software. + * + * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c + */ + +/* + * FLTK - avoid possible problems on systems with 32-bit wchar_t. + * Don't include wchar.h, and change wchar_t to unsigned int. + * Can we guarantee sizeof(unsigned int) >= 4 ? + */ +#if 0 +#include +#endif + +struct interval { + int first; + int last; +}; + +/* auxiliary function for binary search in interval table */ +/* + * FLTK: was +static int bisearch(wchar_t ucs, const struct interval *table, int max) { + */ +static int bisearch(unsigned int ucs, const struct interval *table, int max) { + int min = 0; + int mid; + + if (ucs < table[0].first || ucs > table[max].last) + return 0; + while (max >= min) { + mid = (min + max) / 2; + if (ucs > table[mid].last) + min = mid + 1; + else if (ucs < table[mid].first) + max = mid - 1; + else + return 1; + } + + return 0; +} + + +/* The following two functions define the column width of an ISO 10646 + * character as follows: + * + * - The null character (U+0000) has a column width of 0. + * + * - Other C0/C1 control characters and DEL will lead to a return + * value of -1. + * + * - Non-spacing and enclosing combining characters (general + * category code Mn or Me in the Unicode database) have a + * column width of 0. + * + * - SOFT HYPHEN (U+00AD) has a column width of 1. + * + * - Other format characters (general category code Cf in the Unicode + * database) and ZERO WIDTH SPACE (U+200B) have a column width of 0. + * + * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF) + * have a column width of 0. + * + * - Spacing characters in the East Asian Wide (W) or East Asian + * Full-width (F) category as defined in Unicode Technical + * Report #11 have a column width of 2. + * + * - All remaining characters (including all printable + * ISO 8859-1 and WGL4 characters, Unicode control characters, + * etc.) have a column width of 1. + * + * This implementation assumes that wchar_t characters are encoded + * in ISO 10646. + */ + +/* + * FLTK: was +int mk_wcwidth(wchar_t ucs) + */ +int mk_wcwidth(unsigned int ucs) +{ + /* sorted list of non-overlapping intervals of non-spacing characters */ + /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */ + static const struct interval combining[] = { + { 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 }, + { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, + { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 }, + { 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 }, + { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, + { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, + { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 }, + { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D }, + { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, + { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, + { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C }, + { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, + { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, + { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, + { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C }, + { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D }, + { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 }, + { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 }, + { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC }, + { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, + { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, + { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, + { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, + { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, + { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, + { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, + { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, + { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, + { 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, + { 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F }, + { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 }, + { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD }, + { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD }, + { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 }, + { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B }, + { 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 }, + { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 }, + { 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF }, + { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 }, + { 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F }, + { 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B }, + { 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F }, + { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB }, + { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F }, + { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 }, + { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD }, + { 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F }, + { 0xE0100, 0xE01EF } + }; + + /* test for 8-bit control characters */ + if (ucs == 0) + return 0; + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) + return -1; + + /* binary search in table of non-spacing characters */ + if (bisearch(ucs, combining, + sizeof(combining) / sizeof(struct interval) - 1)) + return 0; + + /* if we arrive here, ucs is not a combining or C0/C1 control character */ + + return 1 + + (ucs >= 0x1100 && + (ucs <= 0x115f || /* Hangul Jamo init. consonants */ + ucs == 0x2329 || ucs == 0x232a || + (ucs >= 0x2e80 && ucs <= 0xa4cf && + ucs != 0x303f) || /* CJK ... Yi */ + (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ + (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ + (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ + (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ + (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ + (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x20000 && ucs <= 0x2fffd) || + (ucs >= 0x30000 && ucs <= 0x3fffd))); +} + + +/* + * FLTK: comment out the remaining functions, as we don't need themm. + */ +#if 0 + +/* + * FLTK: was +int mk_wcswidth(const wchar_t *pwcs, size_t n) + */ +int mk_wcswidth(const unsigned int *pwcs, size_t n) +{ + int w, width = 0; + + for (;*pwcs && n-- > 0; pwcs++) + if ((w = mk_wcwidth(*pwcs)) < 0) + return -1; + else + width += w; + + return width; +} + + +/* + * The following functions are the same as mk_wcwidth() and + * mk_wcswidth(), except that spacing characters in the East Asian + * Ambiguous (A) category as defined in Unicode Technical Report #11 + * have a column width of 2. This variant might be useful for users of + * CJK legacy encodings who want to migrate to UCS without changing + * the traditional terminal character-width behaviour. It is not + * otherwise recommended for general use. + */ +/* + * FLTK: was +int mk_wcwidth_cjk(wchar_t ucs) + */ +int mk_wcwidth_cjk(unsigned int ucs) +{ + /* sorted list of non-overlapping intervals of East Asian Ambiguous + * characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */ + static const struct interval ambiguous[] = { + { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 }, + { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 }, + { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 }, + { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 }, + { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED }, + { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA }, + { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 }, + { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B }, + { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 }, + { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 }, + { 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 }, + { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE }, + { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 }, + { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA }, + { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 }, + { 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB }, + { 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB }, + { 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 }, + { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 }, + { 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 }, + { 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 }, + { 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 }, + { 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 }, + { 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 }, + { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC }, + { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 }, + { 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 }, + { 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 }, + { 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 }, + { 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 }, + { 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 }, + { 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B }, + { 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 }, + { 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 }, + { 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E }, + { 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 }, + { 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 }, + { 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F }, + { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 }, + { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF }, + { 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B }, + { 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 }, + { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, + { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, + { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 }, + { 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 }, + { 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 }, + { 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 }, + { 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 }, + { 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F }, + { 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF }, + { 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD } + }; + + /* binary search in table of non-spacing characters */ + if (bisearch(ucs, ambiguous, + sizeof(ambiguous) / sizeof(struct interval) - 1)) + return 2; + + return mk_wcwidth(ucs); +} + + +/* + * FLTK: was +int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n) + */ +int mk_wcswidth_cjk(const unsigned int *pwcs, size_t n) +{ + int w, width = 0; + + for (;*pwcs && n-- > 0; pwcs++) + if ((w = mk_wcwidth_cjk(*pwcs)) < 0) + return -1; + else + width += w; + + return width; +} + +/* + * FLTK: end of commented out functions + */ +#endif diff --git a/plugins/zynaddsubfx/mxml/CHANGES b/plugins/zynaddsubfx/mxml/CHANGES deleted file mode 100644 index 956d5c5e0..000000000 --- a/plugins/zynaddsubfx/mxml/CHANGES +++ /dev/null @@ -1,305 +0,0 @@ -CHANGES - 2008-01-28 --------------------- - -CHANGES IN Mini-XML 2.5 - - - The mxmldoc program now makes greater use of CSS and - supports a --css option to embed an alternate stylesheet. - - The mxmldoc program now supports --header and --footer - options to insert documentation content before and - after the generated content. - - The mxmldoc program now supports a --framed option to - generate framed HTML output. - - The mxmldoc program now creates a table of contents - including any headings in the --intro file when - generating HTML output. - - The man pages and man page output from mxmldoc did - not use "\-" for dashes (STR #68) - - The debug version of the Mini-XML DLL could not be - built (STR #65) - - Processing instructions and directives did not work - when not at the top level of a document (STR #67) - - Spaces around the "=" in attributes were not supported - (STR #67) - - -CHANGES IN Mini-XML 2.4 - - - Fixed shared library build problems on HP-UX and Mac OS X. - - The mxmldoc program did not output argument descriptions - for functions properly. - - All global settings (custom, error, and entity callbacks - and the wrap margin) are now managed separately for each - thread. - - Added mxmlElementDeleteAttr() function (STR #59) - - mxmlElementSetAttrf() did not work (STR #57) - - mxmlLoad*() incorrectly treated declarations as parent - elements (STR #56) - - mxmlLoad*() incorrectly allowed attributes without values - (STR #47) - - Fixed Visual C++ build problems (STR #49) - - mxmlLoad*() did not return NULL when an element contained - an error (STR #46) - - Added support for the apos character entity (STR #54) - - Fixed whitespace detection with Unicode characters (STR - #48) - - mxmlWalkNext() and mxmlWalkPrev() did not work correctly - when called with a node with no children as the top node - (STR #53) - - -CHANGES IN Mini-XML 2.3 - - - Added two exceptions to the LGPL to support static - linking of applications against Mini-XML - - The mxmldoc utility can now generate man pages, too. - - Added a mxmlNewXML() function - - Added a mxmlElementSetAttrf() function (STR #43) - - Added snprintf() emulation function for test program (STR - #32) - - Added the _CRT_SECURE_NO_DEPRECATE definition when - building on VC++ 2005 (STR #36) - - mxmlLoad*() did not detect missing > characters in - elements (STR #41) - - mxmlLoad*() did not detect missing close tags at the end - of an XML document (STR #45) - - Added user_data and ref_count members to mxml_node_t - structure - - Added mxmlReleaseNode() and mxmlRetainNode() APIs for - reference-counted nodes - - Added mxmlSetWrapMargin() to control the wrapping of XML - output - - Added conditional check for EINTR error code for - certain Windows compilers that do not define it (STR - #33) - - The mxmldoc program now generates correct HTML 4.0 - output - previously it generated invalid XHTML - - The mxmldoc program now supports "@deprecated@, - "@private@", and "@since version@" comments - - Fixed function and enumeration type bugs in mxmldoc. - - Fixed the XML schema for mxmldoc - - The mxmldoc program now supports --intro, --section, - and --title options - - The mxmlLoad*() functions could leak a node on an error - (STR #27) - - The mxml_vsnprintf() function could get in an infinite - loop on a buffer overflow (STR #25) - - Added new mxmlNewCDATA() and mxmlSetCDATA() functions - to create and set CDATA nodes, which are really just - special element nodes - - Added new MXML_IGNORE type and MXML_IGNORE_CB callback - to ignore non-element nodes, e.g. whitespace - - mxmlLoad*() crashed when reporting an error in some - invalid XML (STR #23) - - -CHANGES IN Mini-XML 2.2.2 - - - mxmlLoad*() did not treat custom data as opaque, so - whitespace characters would be lost. - - -CHANGES IN Mini-XML 2.2.1 - - - mxmlLoadFd(), mxmlLoadFile(), and mxmlLoadString() now - correctly return NULL on error (STR #21) - - mxmlNewInteger(), mxmlNewOpaque(), mxmlNewReal(), - mxmlNewText(), and mxmlNewTextf() incorrectly required - a parent node (STR #22) - - Fixed an XML output bug in mxmldoc. - - The "make install" target now uses the install command - to set the proper permissions on UNIX/Linux/OSX. - - Fixed a MingW/Cygwin compilation problem (STR #18) - - -CHANGES IN Mini-XML 2.2 - - - Added shared library support (STR #17) - - mxmlLoad*() now returns an error when an XML stream - contains illegal control characters (STR #10) - - mxmlLoad*() now returns an error when an element - contains two attributes with the same name in - conformance with the XML spec (STR #16) - - Added support for CDATA (STR #14, STR #15) - - Updated comment and processing instruction handling - - no entity support per XML specification. - - Added checking for invalid comment termination ("--->" - is not allowed) - - -CHANGES IN Mini-XML 2.1 - - - Added support for custom data nodes (STR #6) - - Now treat UTF-8 sequences which are longer than - necessary as an error (STR #4) - - Fixed entity number support (STR #8) - - Fixed mxmlLoadString() bug with UTF-8 (STR #7) - - Fixed entity lookup bug (STR #5) - - Added mxmlLoadFd() and mxmlSaveFd() functions. - - Fixed multi-word UTF-16 handling. - - -CHANGES IN Mini-XML 2.0 - - - New programmers manual. - - Added Visual C++ project files for Microsoft Windows - users. - - Added optimizations to mxmldoc, mxmlSaveFile(), and - mxmlIndexNew() (STR #2) - - mxmlEntityAddCallback() now returns an integer status - (STR #2) - - Added UTF-16 support (input only; all output is UTF-8) - - Added index functions to build a searchable index of - XML nodes. - - Added character entity callback interface to support - additional character entities beyond those defined in - the XHTML specification. - - Added support for XHTML character entities. - - The mxmldoc utility now produces XML output which - conforms to an updated XML schema, described in the file - "doc/mxmldoc.xsd". - - Changed the whitespace callback interface to return - strings instead of a single character, allowing for - greater control over the formatting of XML files - written using Mini-XML. THIS CHANGE WILL REQUIRE - CHANGES TO YOUR 1.x CODE IF YOU USE WHITESPACE - CALLBACKS. - - The mxmldoc utility is now capable of documenting C++ - classes, functions, and structures, and correctly - handles C++ comments. - - Added new modular tests for mxmldoc. - - Updated the mxmldoc output to be more compatible with - embedding in manuals produced with HTMLDOC. - - The makefile incorrectly included a "/" separator - between the destination path and install path. This - caused problems when building and installing with - MingW. - - -CHANGES IN Mini-XML 1.3 - - - Fixes for mxmldoc. - - Added support for reading standard HTML entity names. - - mxmlLoadString/File() did not decode character - entities in element names, attribute names, or - attribute values. - - mxmlLoadString/File() would crash when loading non- - conformant XML data under an existing parent (top) - node. - - Fixed several bugs in the mxmldoc utility. - - Added new error callback function to catch a variety - of errors and log them to someplace other than stderr. - - The mxmlElementSetAttr() function now allows for NULL - attribute values. - - The load and save functions now properly handle quoted - element and attribute name strings properly, e.g. for - !DOCTYPE declarations. - - -CHANGES IN Mini-XML 1.2 - - - Added new "set" methods to set the value of a node. - - Added new formatted text methods mxmlNewTextf() and - mxmlSetTextf() to create/set a text node value using - printf-style formats. - - Added new standard callbacks for use with the mxmlLoad - functions. - - Updated the HTML documentation to include examples of - the walk and load function output. - - Added --with/without-ansi configure option to control - the strdup() function check. - - Added --with/without-snprintf configure option to - control the snprintf() and vsnprintf() function - checks. - - -CHANGES IN Mini-XML 1.1.2 - - - The mxml(3) man page wasn't updated for the string - functions. - - mxmlSaveString() returned the wrong number of - characters. - - mxml_add_char() updated the buffer pointer in the - wrong place. - - -CHANGES IN Mini-XML 1.1.1 - - - The private mxml_add_ch() function did not update the - start-of-buffer pointer which could cause a crash when - using mxmlSaveString(). - - The private mxml_write_ws() function called putc() - instead of using the proper callback which could cause - a crash when using mxmlSaveString(). - - Added a mxmlSaveAllocString() convenience function for - saving an XML node tree to an allocated string. - - -CHANGES IN Mini-XML 1.1 - - - The mxmlLoadFile() function now uses dynamically - allocated string buffers for element names, attribute - names, and attribute values. Previously they were - capped at 16383, 255, and 255 bytes, respectively. - - Added a new mxmlLoadString() function for loading an - XML node tree from a string. - - Added a new mxmlSaveString() function for saving an - XML node tree to a string. - - Add emulation of strdup() if the local platform does - not provide the function. - - -CHANGES IN Mini-XML 1.0 - - - The mxmldoc program now handles function arguments, - structures, unions, enumerations, classes, and - typedefs properly. - - Documentation provided via mxmldoc and more in-line - comments in the code. - - Added man pages and packaging files. - - -CHANGES IN Mini-XML 0.93 - - - New mxmldoc example program that is also used to - create and update code documentation using XML and - produce HTML reference pages. - - Added mxmlAdd() and mxmlRemove() functions to add and - remove nodes from a tree. This provides more - flexibility over where the nodes are inserted and - allows nodes to be moved within the tree as needed. - - mxmlLoadFile() now correctly handles comments. - - mxmlLoadFile() now supports the required "gt", "quot", - and "nbsp" character entities. - - mxmlSaveFile() now uses newlines as whitespace - when valid to do so. - - mxmlFindElement() now also takes attribute name and - attribute value string arguments to limit the search - to specific elements with attributes and/or values. - NULL pointers can be used as "wildcards". - - Added uninstall target to makefile, and auto-reconfig - if Makefile.in or configure.in are changed. - - mxmlFindElement(), mxmlWalkNext(), and mxmlWalkPrev() - now all provide "descend" arguments to control whether - they descend into child nodes in the tree. - - Fixed some whitespace issues in mxmlLoadFile(). - - Fixed Unicode output and whitespace issues in - mxmlSaveFile(). - - mxmlSaveFile() now supports a whitespace callback to - provide more human-readable XML output under program - control. - - -CHANGES IN Mini-XML 0.92 - - - mxmlSaveFile() didn't return a value on success. - - -CHANGES IN Mini-XML 0.91 - - - mxmlWalkNext() would go into an infinite loop. - - -CHANGES IN Mini-XML 0.9 - - - Initial public release. diff --git a/plugins/zynaddsubfx/mxml/COPYING b/plugins/zynaddsubfx/mxml/COPYING deleted file mode 100644 index fd9d3532a..000000000 --- a/plugins/zynaddsubfx/mxml/COPYING +++ /dev/null @@ -1,507 +0,0 @@ - Mini-XML License - October 18, 2005 - - -The Mini-XML library and included programs are provided under the -terms of the GNU Library General Public License (LGPL) with the -following exceptions: - - 1. Static linking of applications to the Mini-XML library - does not constitute a derivative work and does not require - the author to provide source code for the application, use - the shared Mini-XML libraries, or link their applications - against a user-supplied version of Mini-XML. - - If you link the application to a modified version of - Mini-XML, then the changes to Mini-XML must be provided - under the terms of the LGPL in sections 1, 2, and 4. - - 2. You do not have to provide a copy of the Mini-XML license - with programs that are linked to the Mini-XML library, nor - do you have to identify the Mini-XML license in your - program or documentation as required by section 6 of the - LGPL. - - - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - [This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, 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 -this service 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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. 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 not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library 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 -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "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 -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY 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 -LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/plugins/zynaddsubfx/mxml/README b/plugins/zynaddsubfx/mxml/README deleted file mode 100644 index 3b880417d..000000000 --- a/plugins/zynaddsubfx/mxml/README +++ /dev/null @@ -1,204 +0,0 @@ -README - 2008-01-28 -------------------- - - -INTRODUCTION - - This README file describes the Mini-XML library version 2.5. - - Mini-XML is a small XML parsing library that you can use to - read XML and XML-like data files in your application without - requiring large non-standard libraries. Mini-XML only - requires an ANSI C compatible compiler (GCC works, as do - most vendors' ANSI C compilers) and a "make" program. - - Mini-XML provides the following functionality: - - - Reading of UTF-8 and UTF-16 and writing of UTF-8 - encoded XML files and strings. - - Data is stored in a linked-list tree structure, - preserving the XML data hierarchy. - - Supports arbitrary element names, attributes, and - attribute values with no preset limits, just available - memory. - - Supports integer, real, opaque ("cdata"), and text - data types in "leaf" nodes. - - Functions for creating and managing trees of data. - - "Find" and "walk" functions for easily locating and - navigating trees of data. - - Mini-XML doesn't do validation or other types of processing - on the data based upon schema files or other sources of - definition information. - - -BUILDING Mini-XML - - Mini-XML comes with an autoconf-based configure script; just - type the following command to get things going: - - ./configure - - The default install prefix is /usr/local, which can be - overridden using the --prefix option: - - ./configure --prefix=/foo - - Other configure options can be found using the --help - option: - - ./configure --help - - Once you have configured the software, type "make" to do the - build and run the test program to verify that things are - working, as follows: - - make - - If you are using Mini-XML under Microsoft Windows with - Visual C++, use the included project files in the "vcnet" - subdirectory to build the library instead. - - -INSTALLING Mini-XML - - The "install" target will install Mini-XML in the lib and - include directories: - - make install - - Once you have installed it, use the "-lmxml" option to link - your application against it. - - -DOCUMENTATION - - The documentation is available in the "doc" subdirectory in - the files "mxml.html" (HTML) and "mxml.pdf" (PDF). You can - also look at the "testmxml.c" and "mxmldoc.c" source files - for examples of using Mini-XML. - - Mini-XML provides a single header file which you include: - - #include - - Nodes are defined by the "mxml_node_t" structure; the "type" - member defines the node type (element, integer, opaque, - real, or text) which determines which value you want to look - at in the "value" union. New nodes can be created using the - "mxmlNewElement()", "mxmlNewInteger()", "mxmlNewOpaque()", - "mxmlNewReal()", and "mxmlNewText()" functions. Only - elements can have child nodes, and the top node must be an - element, usually "?xml". - - You load an XML file using the "mxmlLoadFile()" function: - - FILE *fp; - mxml_node_t *tree; - - fp = fopen("filename.xml", "r"); - tree = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK); - fclose(fp); - - Similarly, you save an XML file using the "mxmlSaveFile()" - function: - - FILE *fp; - mxml_node_t *tree; - - fp = fopen("filename.xml", "w"); - mxmlSaveFile(tree, fp, MXML_NO_CALLBACK); - fclose(fp); - - The "mxmlLoadString()", "mxmlSaveAllocString()", and - "mxmlSaveString()" functions load XML node trees from and - save XML node trees to strings: - - char buffer[8192]; - char *ptr; - mxml_node_t *tree; - - ... - tree = mxmlLoadString(NULL, buffer, MXML_NO_CALLBACK); - - ... - mxmlSaveString(tree, buffer, sizeof(buffer), MXML_NO_CALLBACK); - - ... - ptr = mxmlSaveAllocString(tree, MXML_NO_CALLBACK); - - You can find a named element/node using the - "mxmlFindElement()" function: - - mxml_node_t *node = mxmlFindElement(tree, tree, "name", "attr", - "value", MXML_DESCEND); - - The "name", "attr", and "value" arguments can be passed as - NULL to act as wildcards, e.g.: - - /* Find the first "a" element */ - node = mxmlFindElement(tree, tree, "a", NULL, NULL, MXML_DESCEND); - - /* Find the first "a" element with "href" attribute */ - node = mxmlFindElement(tree, tree, "a", "href", NULL, MXML_DESCEND); - - /* Find the first "a" element with "href" to a URL */ - node = mxmlFindElement(tree, tree, "a", "href", - "http://www.easysw.com/~mike/mxml/", - MXML_DESCEND); - - /* Find the first element with a "src" attribute*/ - node = mxmlFindElement(tree, tree, NULL, "src", NULL, MXML_DESCEND); - - /* Find the first element with a "src" = "foo.jpg" */ - node = mxmlFindElement(tree, tree, NULL, "src", "foo.jpg", - MXML_DESCEND); - - You can also iterate with the same function: - - mxml_node_t *node; - - for (node = mxmlFindElement(tree, tree, "name", NULL, NULL, - MXML_DESCEND); - node != NULL; - node = mxmlFindElement(node, tree, "name", NULL, NULL, - MXML_DESCEND)) - { - ... do something ... - } - - Finally, once you are done with the XML data, use the - "mxmlDelete()" function to recursively free the memory that - is used for a particular node or the entire tree: - - mxmlDelete(tree); - - -GETTING HELP AND REPORTING PROBLEMS - - The Mini-XML web site provides access to a discussion forum - and bug reporting page: - - http://www.minixml.org/ - - -LEGAL STUFF - - The Mini-XML library is Copyright 2003-2008 by Michael Sweet. - - This library is free software; you can redistribute it - and/or modify it under the terms of the GNU Library General - Public License as published by the Free Software Foundation; - either version 2 of the License, or (at your option) any - later version. - - This library 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 Library General Public License for - more details. - - You should have received a copy of the GNU Library General - Public License along with this library; if not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA - 02139, USA. diff --git a/plugins/zynaddsubfx/mxml/mxml-attr.c b/plugins/zynaddsubfx/mxml/mxml-attr.c deleted file mode 100644 index 3b9ba69d3..000000000 --- a/plugins/zynaddsubfx/mxml/mxml-attr.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * "$Id: mxml-attr.c 308 2007-09-15 20:04:56Z mike $" - * - * Attribute support code for Mini-XML, a small XML-like file parsing library. - * - * Copyright 2003-2007 by Michael Sweet. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2, 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. - * - * Contents: - * - * mxmlElementDeleteAttr() - Delete an attribute. - * mxmlElementGetAttr() - Get an attribute. - * mxmlElementSetAttr() - Set an attribute. - * mxmlElementSetAttrf() - Set an attribute with a formatted value. - * mxml_set_attr() - Set or add an attribute name/value pair. - */ - -/* - * Include necessary headers... - */ - -#include "mxml-config.h" -#include "mxml.h" - - -/* - * Local functions... - */ - -static int mxml_set_attr(mxml_node_t *node, const char *name, - char *value); - - -/* - * 'mxmlElementDeleteAttr()' - Delete an attribute. - * - * @since Mini-XML 2.4@ - */ - -void -mxmlElementDeleteAttr(mxml_node_t *node,/* I - Element */ - const char *name)/* I - Attribute name */ -{ - int i; /* Looping var */ - mxml_attr_t *attr; /* Cirrent attribute */ - - -#ifdef DEBUG - fprintf(stderr, "mxmlElementDeleteAttr(node=%p, name=\"%s\")\n", - node, name ? name : "(null)"); -#endif /* DEBUG */ - - /* - * Range check input... - */ - - if (!node || node->type != MXML_ELEMENT || !name) - return; - - /* - * Look for the attribute... - */ - - for (i = node->value.element.num_attrs, attr = node->value.element.attrs; - i > 0; - i --, attr ++) - { -#ifdef DEBUG - printf(" %s=\"%s\"\n", attr->name, attr->value); -#endif /* DEBUG */ - - if (!strcmp(attr->name, name)) - { - /* - * Delete this attribute... - */ - - free(attr->name); - free(attr->value); - - i --; - if (i > 0) - memmove(attr, attr + 1, i * sizeof(mxml_attr_t)); - - node->value.element.num_attrs --; - return; - } - } -} - - -/* - * 'mxmlElementGetAttr()' - Get an attribute. - * - * This function returns NULL if the node is not an element or the - * named attribute does not exist. - */ - -const char * /* O - Attribute value or NULL */ -mxmlElementGetAttr(mxml_node_t *node, /* I - Element node */ - const char *name) /* I - Name of attribute */ -{ - int i; /* Looping var */ - mxml_attr_t *attr; /* Cirrent attribute */ - - -#ifdef DEBUG - fprintf(stderr, "mxmlElementGetAttr(node=%p, name=\"%s\")\n", - node, name ? name : "(null)"); -#endif /* DEBUG */ - - /* - * Range check input... - */ - - if (!node || node->type != MXML_ELEMENT || !name) - return (NULL); - - /* - * Look for the attribute... - */ - - for (i = node->value.element.num_attrs, attr = node->value.element.attrs; - i > 0; - i --, attr ++) - { -#ifdef DEBUG - printf(" %s=\"%s\"\n", attr->name, attr->value); -#endif /* DEBUG */ - - if (!strcmp(attr->name, name)) - { -#ifdef DEBUG - printf(" Returning \"%s\"!\n", attr->value); -#endif /* DEBUG */ - return (attr->value); - } - } - - /* - * Didn't find attribute, so return NULL... - */ - -#ifdef DEBUG - puts(" Returning NULL!\n"); -#endif /* DEBUG */ - - return (NULL); -} - - -/* - * 'mxmlElementSetAttr()' - Set an attribute. - * - * If the named attribute already exists, the value of the attribute - * is replaced by the new string value. The string value is copied - * into the element node. This function does nothing if the node is - * not an element. - */ - -void -mxmlElementSetAttr(mxml_node_t *node, /* I - Element node */ - const char *name, /* I - Name of attribute */ - const char *value) /* I - Attribute value */ -{ - char *valuec; /* Copy of value */ - - -#ifdef DEBUG - fprintf(stderr, "mxmlElementSetAttr(node=%p, name=\"%s\", value=\"%s\")\n", - node, name ? name : "(null)", value ? value : "(null)"); -#endif /* DEBUG */ - - /* - * Range check input... - */ - - if (!node || node->type != MXML_ELEMENT || !name) - return; - - if (value) - valuec = strdup(value); - else - valuec = NULL; - - if (mxml_set_attr(node, name, valuec)) - free(valuec); -} - - -/* - * 'mxmlElementSetAttrf()' - Set an attribute with a formatted value. - * - * If the named attribute already exists, the value of the attribute - * is replaced by the new formatted string. The formatted string value is - * copied into the element node. This function does nothing if the node - * is not an element. - * - * @since Mini-XML 2.3@ - */ - -void -mxmlElementSetAttrf(mxml_node_t *node, /* I - Element node */ - const char *name, /* I - Name of attribute */ - const char *format,/* I - Printf-style attribute value */ - ...) /* I - Additional arguments as needed */ -{ - va_list ap; /* Argument pointer */ - char *value; /* Value */ - - -#ifdef DEBUG - fprintf(stderr, - "mxmlElementSetAttrf(node=%p, name=\"%s\", format=\"%s\", ...)\n", - node, name ? name : "(null)", format ? format : "(null)"); -#endif /* DEBUG */ - - /* - * Range check input... - */ - - if (!node || node->type != MXML_ELEMENT || !name || !format) - return; - - /* - * Format the value... - */ - - va_start(ap, format); - value = _mxml_vstrdupf(format, ap); - va_end(ap); - - if (!value) - mxml_error("Unable to allocate memory for attribute '%s' in element %s!", - name, node->value.element.name); - else if (mxml_set_attr(node, name, value)) - free(value); -} - - -/* - * 'mxml_set_attr()' - Set or add an attribute name/value pair. - */ - -static int /* O - 0 on success, -1 on failure */ -mxml_set_attr(mxml_node_t *node, /* I - Element node */ - const char *name, /* I - Attribute name */ - char *value) /* I - Attribute value */ -{ - int i; /* Looping var */ - mxml_attr_t *attr; /* New attribute */ - - - /* - * Look for the attribute... - */ - - for (i = node->value.element.num_attrs, attr = node->value.element.attrs; - i > 0; - i --, attr ++) - if (!strcmp(attr->name, name)) - { - /* - * Free the old value as needed... - */ - - if (attr->value) - free(attr->value); - - attr->value = value; - - return (0); - } - - /* - * Add a new attribute... - */ - - if (node->value.element.num_attrs == 0) - attr = malloc(sizeof(mxml_attr_t)); - else - attr = realloc(node->value.element.attrs, - (node->value.element.num_attrs + 1) * sizeof(mxml_attr_t)); - - if (!attr) - { - mxml_error("Unable to allocate memory for attribute '%s' in element %s!", - name, node->value.element.name); - return (-1); - } - - node->value.element.attrs = attr; - attr += node->value.element.num_attrs; - - if ((attr->name = strdup(name)) == NULL) - { - mxml_error("Unable to allocate memory for attribute '%s' in element %s!", - name, node->value.element.name); - return (-1); - } - - attr->value = value; - - node->value.element.num_attrs ++; - - return (0); -} - - -/* - * End of "$Id: mxml-attr.c 308 2007-09-15 20:04:56Z mike $". - */ diff --git a/plugins/zynaddsubfx/mxml/mxml-config.h b/plugins/zynaddsubfx/mxml/mxml-config.h deleted file mode 100644 index a0577b083..000000000 --- a/plugins/zynaddsubfx/mxml/mxml-config.h +++ /dev/null @@ -1,91 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* - * "$Id: config.h.in 310 2007-09-22 21:00:56Z mike $" - * - * Configuration file for Mini-XML, a small XML-like file parsing library. - * - * Copyright 2003-2007 by Michael Sweet. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2, 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. - */ - -/* - * Include necessary headers... - */ - -#include -#include -#include -#include -#include - - -/* - * Version number... - */ - -#define MXML_VERSION "Mini-XML v2.5" - - -/* - * Inline function support... - */ - -#define inline - - -/* - * Do we have the snprintf() and vsnprintf() functions? - */ - -#define HAVE_SNPRINTF 1 -#define HAVE_VSNPRINTF 1 - - -/* - * Do we have the strXXX() functions? - */ - -#define HAVE_STRDUP 1 - - -/* - * Do we have threading support? - */ - -#undef HAVE_PTHREAD_H - - -/* - * Define prototypes for string functions as needed... - */ - -# ifndef HAVE_STRDUP -extern char *_mxml_strdup(const char *); -# define strdup _mxml_strdup -# endif /* !HAVE_STRDUP */ - -extern char *_mxml_strdupf(const char *, ...); -extern char *_mxml_vstrdupf(const char *, va_list); - -# ifndef HAVE_SNPRINTF -extern int _mxml_snprintf(char *, size_t, const char *, ...); -# define snprintf _mxml_snprintf -# endif /* !HAVE_SNPRINTF */ - -# ifndef HAVE_VSNPRINTF -extern int _mxml_vsnprintf(char *, size_t, const char *, va_list); -# define vsnprintf _mxml_vsnprintf -# endif /* !HAVE_VSNPRINTF */ - -/* - * End of "$Id: config.h.in 310 2007-09-22 21:00:56Z mike $". - */ diff --git a/plugins/zynaddsubfx/mxml/mxml-entity.c b/plugins/zynaddsubfx/mxml/mxml-entity.c deleted file mode 100644 index 89f154234..000000000 --- a/plugins/zynaddsubfx/mxml/mxml-entity.c +++ /dev/null @@ -1,462 +0,0 @@ -/* - * "$Id: mxml-entity.c 309 2007-09-21 04:46:02Z mike $" - * - * Character entity support code for Mini-XML, a small XML-like - * file parsing library. - * - * Copyright 2003-2007 by Michael Sweet. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2, 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. - * - * Contents: - * - * mxmlEntityAddCallback() - Add a callback to convert entities to - * Unicode. - * mxmlEntityGetName() - Get the name that corresponds to the - * character value. - * mxmlEntityGetValue() - Get the character corresponding to a named - * entity. - * mxmlEntityRemoveCallback() - Remove a callback. - * _mxml_entity_cb() - Lookup standard (X)HTML entities. - */ - -/* - * Include necessary headers... - */ - -#include "mxml-private.h" - - -/* - * 'mxmlEntityAddCallback()' - Add a callback to convert entities to Unicode. - */ - -int /* O - 0 on success, -1 on failure */ -mxmlEntityAddCallback( - int (*cb)(const char *name)) /* I - Callback function to add */ -{ - _mxml_global_t *global = _mxml_global(); - /* Global data */ - - - if (global->num_entity_cbs < (int)(sizeof(global->entity_cbs) / sizeof(global->entity_cbs[0]))) - { - global->entity_cbs[global->num_entity_cbs] = cb; - global->num_entity_cbs ++; - - return (0); - } - else - { - mxml_error("Unable to add entity callback!"); - - return (-1); - } -} - - -/* - * 'mxmlEntityGetName()' - Get the name that corresponds to the character value. - * - * If val does not need to be represented by a named entity, NULL is returned. - */ - -const char * /* O - Entity name or NULL */ -mxmlEntityGetName(int val) /* I - Character value */ -{ - switch (val) - { - case '&' : - return ("amp"); - - case '<' : - return ("lt"); - - case '>' : - return ("gt"); - - case '\"' : - return ("quot"); - - default : - return (NULL); - } -} - - -/* - * 'mxmlEntityGetValue()' - Get the character corresponding to a named entity. - * - * The entity name can also be a numeric constant. -1 is returned if the - * name is not known. - */ - -int /* O - Character value or -1 on error */ -mxmlEntityGetValue(const char *name) /* I - Entity name */ -{ - int i; /* Looping var */ - int ch; /* Character value */ - _mxml_global_t *global = _mxml_global(); - /* Global data */ - - - for (i = 0; i < global->num_entity_cbs; i ++) - if ((ch = (global->entity_cbs[i])(name)) >= 0) - return (ch); - - return (-1); -} - - -/* - * 'mxmlEntityRemoveCallback()' - Remove a callback. - */ - -void -mxmlEntityRemoveCallback(int (*cb)(const char *name)) - /* I - Callback function to remove */ -{ - int i; /* Looping var */ - _mxml_global_t *global = _mxml_global(); - /* Global data */ - - - for (i = 0; i < global->num_entity_cbs; i ++) - if (cb == global->entity_cbs[i]) - { - /* - * Remove the callback... - */ - - global->num_entity_cbs --; - - if (i < global->num_entity_cbs) - memmove(global->entity_cbs + i, global->entity_cbs + i + 1, - (global->num_entity_cbs - i) * sizeof(global->entity_cbs[0])); - - return; - } -} - - -/* - * '_mxml_entity_cb()' - Lookup standard (X)HTML entities. - */ - -int /* O - Unicode value or -1 */ -_mxml_entity_cb(const char *name) /* I - Entity name */ -{ - int diff, /* Difference between names */ - current, /* Current entity in search */ - first, /* First entity in search */ - last; /* Last entity in search */ - static const struct - { - const char *name; /* Entity name */ - int val; /* Character value */ - } entities[] = - { - { "AElig", 198 }, - { "Aacute", 193 }, - { "Acirc", 194 }, - { "Agrave", 192 }, - { "Alpha", 913 }, - { "Aring", 197 }, - { "Atilde", 195 }, - { "Auml", 196 }, - { "Beta", 914 }, - { "Ccedil", 199 }, - { "Chi", 935 }, - { "Dagger", 8225 }, - { "Delta", 916 }, - { "Dstrok", 208 }, - { "ETH", 208 }, - { "Eacute", 201 }, - { "Ecirc", 202 }, - { "Egrave", 200 }, - { "Epsilon", 917 }, - { "Eta", 919 }, - { "Euml", 203 }, - { "Gamma", 915 }, - { "Iacute", 205 }, - { "Icirc", 206 }, - { "Igrave", 204 }, - { "Iota", 921 }, - { "Iuml", 207 }, - { "Kappa", 922 }, - { "Lambda", 923 }, - { "Mu", 924 }, - { "Ntilde", 209 }, - { "Nu", 925 }, - { "OElig", 338 }, - { "Oacute", 211 }, - { "Ocirc", 212 }, - { "Ograve", 210 }, - { "Omega", 937 }, - { "Omicron", 927 }, - { "Oslash", 216 }, - { "Otilde", 213 }, - { "Ouml", 214 }, - { "Phi", 934 }, - { "Pi", 928 }, - { "Prime", 8243 }, - { "Psi", 936 }, - { "Rho", 929 }, - { "Scaron", 352 }, - { "Sigma", 931 }, - { "THORN", 222 }, - { "Tau", 932 }, - { "Theta", 920 }, - { "Uacute", 218 }, - { "Ucirc", 219 }, - { "Ugrave", 217 }, - { "Upsilon", 933 }, - { "Uuml", 220 }, - { "Xi", 926 }, - { "Yacute", 221 }, - { "Yuml", 376 }, - { "Zeta", 918 }, - { "aacute", 225 }, - { "acirc", 226 }, - { "acute", 180 }, - { "aelig", 230 }, - { "agrave", 224 }, - { "alefsym", 8501 }, - { "alpha", 945 }, - { "amp", '&' }, - { "and", 8743 }, - { "ang", 8736 }, - { "apos", '\'' }, - { "aring", 229 }, - { "asymp", 8776 }, - { "atilde", 227 }, - { "auml", 228 }, - { "bdquo", 8222 }, - { "beta", 946 }, - { "brkbar", 166 }, - { "brvbar", 166 }, - { "bull", 8226 }, - { "cap", 8745 }, - { "ccedil", 231 }, - { "cedil", 184 }, - { "cent", 162 }, - { "chi", 967 }, - { "circ", 710 }, - { "clubs", 9827 }, - { "cong", 8773 }, - { "copy", 169 }, - { "crarr", 8629 }, - { "cup", 8746 }, - { "curren", 164 }, - { "dArr", 8659 }, - { "dagger", 8224 }, - { "darr", 8595 }, - { "deg", 176 }, - { "delta", 948 }, - { "diams", 9830 }, - { "die", 168 }, - { "divide", 247 }, - { "eacute", 233 }, - { "ecirc", 234 }, - { "egrave", 232 }, - { "empty", 8709 }, - { "emsp", 8195 }, - { "ensp", 8194 }, - { "epsilon", 949 }, - { "equiv", 8801 }, - { "eta", 951 }, - { "eth", 240 }, - { "euml", 235 }, - { "euro", 8364 }, - { "exist", 8707 }, - { "fnof", 402 }, - { "forall", 8704 }, - { "frac12", 189 }, - { "frac14", 188 }, - { "frac34", 190 }, - { "frasl", 8260 }, - { "gamma", 947 }, - { "ge", 8805 }, - { "gt", '>' }, - { "hArr", 8660 }, - { "harr", 8596 }, - { "hearts", 9829 }, - { "hellip", 8230 }, - { "hibar", 175 }, - { "iacute", 237 }, - { "icirc", 238 }, - { "iexcl", 161 }, - { "igrave", 236 }, - { "image", 8465 }, - { "infin", 8734 }, - { "int", 8747 }, - { "iota", 953 }, - { "iquest", 191 }, - { "isin", 8712 }, - { "iuml", 239 }, - { "kappa", 954 }, - { "lArr", 8656 }, - { "lambda", 955 }, - { "lang", 9001 }, - { "laquo", 171 }, - { "larr", 8592 }, - { "lceil", 8968 }, - { "ldquo", 8220 }, - { "le", 8804 }, - { "lfloor", 8970 }, - { "lowast", 8727 }, - { "loz", 9674 }, - { "lrm", 8206 }, - { "lsaquo", 8249 }, - { "lsquo", 8216 }, - { "lt", '<' }, - { "macr", 175 }, - { "mdash", 8212 }, - { "micro", 181 }, - { "middot", 183 }, - { "minus", 8722 }, - { "mu", 956 }, - { "nabla", 8711 }, - { "nbsp", 160 }, - { "ndash", 8211 }, - { "ne", 8800 }, - { "ni", 8715 }, - { "not", 172 }, - { "notin", 8713 }, - { "nsub", 8836 }, - { "ntilde", 241 }, - { "nu", 957 }, - { "oacute", 243 }, - { "ocirc", 244 }, - { "oelig", 339 }, - { "ograve", 242 }, - { "oline", 8254 }, - { "omega", 969 }, - { "omicron", 959 }, - { "oplus", 8853 }, - { "or", 8744 }, - { "ordf", 170 }, - { "ordm", 186 }, - { "oslash", 248 }, - { "otilde", 245 }, - { "otimes", 8855 }, - { "ouml", 246 }, - { "para", 182 }, - { "part", 8706 }, - { "permil", 8240 }, - { "perp", 8869 }, - { "phi", 966 }, - { "pi", 960 }, - { "piv", 982 }, - { "plusmn", 177 }, - { "pound", 163 }, - { "prime", 8242 }, - { "prod", 8719 }, - { "prop", 8733 }, - { "psi", 968 }, - { "quot", '\"' }, - { "rArr", 8658 }, - { "radic", 8730 }, - { "rang", 9002 }, - { "raquo", 187 }, - { "rarr", 8594 }, - { "rceil", 8969 }, - { "rdquo", 8221 }, - { "real", 8476 }, - { "reg", 174 }, - { "rfloor", 8971 }, - { "rho", 961 }, - { "rlm", 8207 }, - { "rsaquo", 8250 }, - { "rsquo", 8217 }, - { "sbquo", 8218 }, - { "scaron", 353 }, - { "sdot", 8901 }, - { "sect", 167 }, - { "shy", 173 }, - { "sigma", 963 }, - { "sigmaf", 962 }, - { "sim", 8764 }, - { "spades", 9824 }, - { "sub", 8834 }, - { "sube", 8838 }, - { "sum", 8721 }, - { "sup", 8835 }, - { "sup1", 185 }, - { "sup2", 178 }, - { "sup3", 179 }, - { "supe", 8839 }, - { "szlig", 223 }, - { "tau", 964 }, - { "there4", 8756 }, - { "theta", 952 }, - { "thetasym", 977 }, - { "thinsp", 8201 }, - { "thorn", 254 }, - { "tilde", 732 }, - { "times", 215 }, - { "trade", 8482 }, - { "uArr", 8657 }, - { "uacute", 250 }, - { "uarr", 8593 }, - { "ucirc", 251 }, - { "ugrave", 249 }, - { "uml", 168 }, - { "upsih", 978 }, - { "upsilon", 965 }, - { "uuml", 252 }, - { "weierp", 8472 }, - { "xi", 958 }, - { "yacute", 253 }, - { "yen", 165 }, - { "yuml", 255 }, - { "zeta", 950 }, - { "zwj", 8205 }, - { "zwnj", 8204 } - }; - - - /* - * Do a binary search for the named entity... - */ - - first = 0; - last = (int)(sizeof(entities) / sizeof(entities[0]) - 1); - - while ((last - first) > 1) - { - current = (first + last) / 2; - - if ((diff = strcmp(name, entities[current].name)) == 0) - return (entities[current].val); - else if (diff < 0) - last = current; - else - first = current; - } - - /* - * If we get here, there is a small chance that there is still - * a match; check first and last... - */ - - if (!strcmp(name, entities[first].name)) - return (entities[first].val); - else if (!strcmp(name, entities[last].name)) - return (entities[last].val); - else - return (-1); -} - - -/* - * End of "$Id: mxml-entity.c 309 2007-09-21 04:46:02Z mike $". - */ diff --git a/plugins/zynaddsubfx/mxml/mxml-file.c b/plugins/zynaddsubfx/mxml/mxml-file.c deleted file mode 100644 index dc51d766d..000000000 --- a/plugins/zynaddsubfx/mxml/mxml-file.c +++ /dev/null @@ -1,3124 +0,0 @@ -/* - * "$Id: mxml-file.c 329 2008-01-13 00:42:35Z mike $" - * - * File loading code for Mini-XML, a small XML-like file parsing library. - * - * Copyright 2003-2008 by Michael Sweet. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2, 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. - * - * Contents: - * - * mxmlLoadFd() - Load a file descriptor into an XML node tree. - * mxmlLoadFile() - Load a file into an XML node tree. - * mxmlLoadString() - Load a string into an XML node tree. - * mxmlSaveAllocString() - Save an XML node tree to an allocated string. - * mxmlSaveFd() - Save an XML tree to a file descriptor. - * mxmlSaveFile() - Save an XML tree to a file. - * mxmlSaveString() - Save an XML node tree to a string. - * mxmlSAXLoadFd() - Load a file descriptor into an XML node tree - * using a SAX callback. - * mxmlSAXLoadFile() - Load a file into an XML node tree - * using a SAX callback. - * mxmlSAXLoadString() - Load a string into an XML node tree - * using a SAX callback. - * mxmlSetCustomHandlers() - Set the handling functions for custom data. - * mxmlSetErrorCallback() - Set the error message callback. - * mxmlSetWrapMargin() - Set the the wrap margin when saving XML data. - * mxml_add_char() - Add a character to a buffer, expanding as needed. - * mxml_fd_getc() - Read a character from a file descriptor. - * mxml_fd_putc() - Write a character to a file descriptor. - * mxml_fd_read() - Read a buffer of data from a file descriptor. - * mxml_fd_write() - Write a buffer of data to a file descriptor. - * mxml_file_getc() - Get a character from a file. - * mxml_file_putc() - Write a character to a file. - * mxml_get_entity() - Get the character corresponding to an entity... - * mxml_load_data() - Load data into an XML node tree. - * mxml_parse_element() - Parse an element for any attributes... - * mxml_string_getc() - Get a character from a string. - * mxml_string_putc() - Write a character to a string. - * mxml_write_name() - Write a name string. - * mxml_write_node() - Save an XML node to a file. - * mxml_write_string() - Write a string, escaping & and < as needed. - * mxml_write_ws() - Do whitespace callback... - */ - -/* - * Include necessary headers... - */ - -#include "mxml-private.h" -#ifdef WIN32 -# include -#else -# include -#endif /* WIN32 */ - - -/* - * Character encoding... - */ - -#define ENCODE_UTF8 0 /* UTF-8 */ -#define ENCODE_UTF16BE 1 /* UTF-16 Big-Endian */ -#define ENCODE_UTF16LE 2 /* UTF-16 Little-Endian */ - - -/* - * Macro to test for a bad XML character... - */ - -#define mxml_bad_char(ch) ((ch) < ' ' && (ch) != '\n' && (ch) != '\r' && (ch) != '\t') - - -/* - * Types and structures... - */ - -typedef int (*_mxml_getc_cb_t)(void *, int *); -typedef int (*_mxml_putc_cb_t)(int, void *); - -typedef struct _mxml_fdbuf_s /**** File descriptor buffer ****/ -{ - int fd; /* File descriptor */ - unsigned char *current, /* Current position in buffer */ - *end, /* End of buffer */ - buffer[8192]; /* Character buffer */ -} _mxml_fdbuf_t; - - -/* - * Local functions... - */ - -static int mxml_add_char(int ch, char **ptr, char **buffer, - int *bufsize); -static int mxml_fd_getc(void *p, int *encoding); -static int mxml_fd_putc(int ch, void *p); -static int mxml_fd_read(_mxml_fdbuf_t *buf); -static int mxml_fd_write(_mxml_fdbuf_t *buf); -static int mxml_file_getc(void *p, int *encoding); -static int mxml_file_putc(int ch, void *p); -static int mxml_get_entity(mxml_node_t *parent, void *p, - int *encoding, - _mxml_getc_cb_t getc_cb); -static inline int mxml_isspace(int ch) - { - return (ch == ' ' || ch == '\t' || ch == '\r' || - ch == '\n'); - } -static mxml_node_t *mxml_load_data(mxml_node_t *top, void *p, - mxml_load_cb_t cb, - _mxml_getc_cb_t getc_cb, - mxml_sax_cb_t sax_cb, void *sax_data); -static int mxml_parse_element(mxml_node_t *node, void *p, - int *encoding, - _mxml_getc_cb_t getc_cb); -static int mxml_string_getc(void *p, int *encoding); -static int mxml_string_putc(int ch, void *p); -static int mxml_write_name(const char *s, void *p, - _mxml_putc_cb_t putc_cb); -static int mxml_write_node(mxml_node_t *node, void *p, - mxml_save_cb_t cb, int col, - _mxml_putc_cb_t putc_cb, - _mxml_global_t *global); -static int mxml_write_string(const char *s, void *p, - _mxml_putc_cb_t putc_cb); -static int mxml_write_ws(mxml_node_t *node, void *p, - mxml_save_cb_t cb, int ws, - int col, _mxml_putc_cb_t putc_cb); - - -/* - * 'mxmlLoadFd()' - Load a file descriptor into an XML node tree. - * - * The nodes in the specified file are added to the specified top node. - * If no top node is provided, the XML file MUST be well-formed with a - * single parent node like for the entire file. The callback - * function returns the value type that should be used for child nodes. - * If MXML_NO_CALLBACK is specified then all child nodes will be either - * MXML_ELEMENT or MXML_TEXT nodes. - * - * The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, - * MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading - * child nodes of the specified type. - */ - -mxml_node_t * /* O - First node or NULL if the file could not be read. */ -mxmlLoadFd(mxml_node_t *top, /* I - Top node */ - int fd, /* I - File descriptor to read from */ - mxml_load_cb_t cb) /* I - Callback function or MXML_NO_CALLBACK */ -{ - _mxml_fdbuf_t buf; /* File descriptor buffer */ - - - /* - * Initialize the file descriptor buffer... - */ - - buf.fd = fd; - buf.current = buf.buffer; - buf.end = buf.buffer; - - /* - * Read the XML data... - */ - - return (mxml_load_data(top, &buf, cb, mxml_fd_getc, MXML_NO_CALLBACK, NULL)); -} - - -/* - * 'mxmlLoadFile()' - Load a file into an XML node tree. - * - * The nodes in the specified file are added to the specified top node. - * If no top node is provided, the XML file MUST be well-formed with a - * single parent node like for the entire file. The callback - * function returns the value type that should be used for child nodes. - * If MXML_NO_CALLBACK is specified then all child nodes will be either - * MXML_ELEMENT or MXML_TEXT nodes. - * - * The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, - * MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading - * child nodes of the specified type. - */ - -mxml_node_t * /* O - First node or NULL if the file could not be read. */ -mxmlLoadFile(mxml_node_t *top, /* I - Top node */ - FILE *fp, /* I - File to read from */ - mxml_load_cb_t cb) /* I - Callback function or MXML_NO_CALLBACK */ -{ - /* - * Read the XML data... - */ - - return (mxml_load_data(top, fp, cb, mxml_file_getc, MXML_NO_CALLBACK, NULL)); -} - - -/* - * 'mxmlLoadString()' - Load a string into an XML node tree. - * - * The nodes in the specified string are added to the specified top node. - * If no top node is provided, the XML string MUST be well-formed with a - * single parent node like for the entire string. The callback - * function returns the value type that should be used for child nodes. - * If MXML_NO_CALLBACK is specified then all child nodes will be either - * MXML_ELEMENT or MXML_TEXT nodes. - * - * The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, - * MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading - * child nodes of the specified type. - */ - -mxml_node_t * /* O - First node or NULL if the string has errors. */ -mxmlLoadString(mxml_node_t *top, /* I - Top node */ - const char *s, /* I - String to load */ - mxml_load_cb_t cb) /* I - Callback function or MXML_NO_CALLBACK */ -{ - /* - * Read the XML data... - */ - - return (mxml_load_data(top, (void *)&s, cb, mxml_string_getc, MXML_NO_CALLBACK, - NULL)); -} - - -/* - * 'mxmlSaveAllocString()' - Save an XML node tree to an allocated string. - * - * This function returns a pointer to a string containing the textual - * representation of the XML node tree. The string should be freed - * using the free() function when you are done with it. NULL is returned - * if the node would produce an empty string or if the string cannot be - * allocated. - * - * The callback argument specifies a function that returns a whitespace - * string or NULL before and after each element. If MXML_NO_CALLBACK - * is specified, whitespace will only be added before MXML_TEXT nodes - * with leading whitespace and before attribute names inside opening - * element tags. - */ - -char * /* O - Allocated string or NULL */ -mxmlSaveAllocString( - mxml_node_t *node, /* I - Node to write */ - mxml_save_cb_t cb) /* I - Whitespace callback or MXML_NO_CALLBACK */ -{ - int bytes; /* Required bytes */ - char buffer[8192]; /* Temporary buffer */ - char *s; /* Allocated string */ - - - /* - * Write the node to the temporary buffer... - */ - - bytes = mxmlSaveString(node, buffer, sizeof(buffer), cb); - - if (bytes <= 0) - return (NULL); - - if (bytes < (int)(sizeof(buffer) - 1)) - { - /* - * Node fit inside the buffer, so just duplicate that string and - * return... - */ - - return (strdup(buffer)); - } - - /* - * Allocate a buffer of the required size and save the node to the - * new buffer... - */ - - if ((s = malloc(bytes + 1)) == NULL) - return (NULL); - - mxmlSaveString(node, s, bytes + 1, cb); - - /* - * Return the allocated string... - */ - - return (s); -} - - -/* - * 'mxmlSaveFd()' - Save an XML tree to a file descriptor. - * - * The callback argument specifies a function that returns a whitespace - * string or NULL before and after each element. If MXML_NO_CALLBACK - * is specified, whitespace will only be added before MXML_TEXT nodes - * with leading whitespace and before attribute names inside opening - * element tags. - */ - -int /* O - 0 on success, -1 on error. */ -mxmlSaveFd(mxml_node_t *node, /* I - Node to write */ - int fd, /* I - File descriptor to write to */ - mxml_save_cb_t cb) /* I - Whitespace callback or MXML_NO_CALLBACK */ -{ - int col; /* Final column */ - _mxml_fdbuf_t buf; /* File descriptor buffer */ - _mxml_global_t *global = _mxml_global(); - /* Global data */ - - - /* - * Initialize the file descriptor buffer... - */ - - buf.fd = fd; - buf.current = buf.buffer; - buf.end = buf.buffer + sizeof(buf.buffer) - 4; - - /* - * Write the node... - */ - - if ((col = mxml_write_node(node, &buf, cb, 0, mxml_fd_putc, global)) < 0) - return (-1); - - if (col > 0) - if (mxml_fd_putc('\n', &buf) < 0) - return (-1); - - /* - * Flush and return... - */ - - return (mxml_fd_write(&buf)); -} - - -/* - * 'mxmlSaveFile()' - Save an XML tree to a file. - * - * The callback argument specifies a function that returns a whitespace - * string or NULL before and after each element. If MXML_NO_CALLBACK - * is specified, whitespace will only be added before MXML_TEXT nodes - * with leading whitespace and before attribute names inside opening - * element tags. - */ - -int /* O - 0 on success, -1 on error. */ -mxmlSaveFile(mxml_node_t *node, /* I - Node to write */ - FILE *fp, /* I - File to write to */ - mxml_save_cb_t cb) /* I - Whitespace callback or MXML_NO_CALLBACK */ -{ - int col; /* Final column */ - _mxml_global_t *global = _mxml_global(); - /* Global data */ - - - /* - * Write the node... - */ - - if ((col = mxml_write_node(node, fp, cb, 0, mxml_file_putc, global)) < 0) - return (-1); - - if (col > 0) - if (putc('\n', fp) < 0) - return (-1); - - /* - * Return 0 (success)... - */ - - return (0); -} - - -/* - * 'mxmlSaveString()' - Save an XML node tree to a string. - * - * This function returns the total number of bytes that would be - * required for the string but only copies (bufsize - 1) characters - * into the specified buffer. - * - * The callback argument specifies a function that returns a whitespace - * string or NULL before and after each element. If MXML_NO_CALLBACK - * is specified, whitespace will only be added before MXML_TEXT nodes - * with leading whitespace and before attribute names inside opening - * element tags. - */ - -int /* O - Size of string */ -mxmlSaveString(mxml_node_t *node, /* I - Node to write */ - char *buffer, /* I - String buffer */ - int bufsize, /* I - Size of string buffer */ - mxml_save_cb_t cb) /* I - Whitespace callback or MXML_NO_CALLBACK */ -{ - int col; /* Final column */ - char *ptr[2]; /* Pointers for putc_cb */ - _mxml_global_t *global = _mxml_global(); - /* Global data */ - - - /* - * Write the node... - */ - - ptr[0] = buffer; - ptr[1] = buffer + bufsize; - - if ((col = mxml_write_node(node, ptr, cb, 0, mxml_string_putc, global)) < 0) - return (-1); - - if (col > 0) - mxml_string_putc('\n', ptr); - - /* - * Nul-terminate the buffer... - */ - - if (ptr[0] >= ptr[1]) - buffer[bufsize - 1] = '\0'; - else - ptr[0][0] = '\0'; - - /* - * Return the number of characters... - */ - - return (ptr[0] - buffer); -} - - -/* - * 'mxmlSAXLoadFd()' - Load a file descriptor into an XML node tree - * using a SAX callback. - * - * The nodes in the specified file are added to the specified top node. - * If no top node is provided, the XML file MUST be well-formed with a - * single parent node like for the entire file. The callback - * function returns the value type that should be used for child nodes. - * If MXML_NO_CALLBACK is specified then all child nodes will be either - * MXML_ELEMENT or MXML_TEXT nodes. - * - * The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, - * MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading - * child nodes of the specified type. - * - * The SAX callback must call mxmlRetain() for any nodes that need to - * be kept for later use. Otherwise, nodes are deleted when the parent - * node is closed or after each data, comment, CDATA, or directive node. - * - * @since Mini-XML 2.3@ - */ - -mxml_node_t * /* O - First node or NULL if the file could not be read. */ -mxmlSAXLoadFd(mxml_node_t *top, /* I - Top node */ - int fd, /* I - File descriptor to read from */ - mxml_load_cb_t cb, /* I - Callback function or MXML_NO_CALLBACK */ - mxml_sax_cb_t sax_cb, /* I - SAX callback or MXML_NO_CALLBACK */ - void *sax_data) /* I - SAX user data */ -{ - _mxml_fdbuf_t buf; /* File descriptor buffer */ - - - /* - * Initialize the file descriptor buffer... - */ - - buf.fd = fd; - buf.current = buf.buffer; - buf.end = buf.buffer; - - /* - * Read the XML data... - */ - - return (mxml_load_data(top, &buf, cb, mxml_fd_getc, sax_cb, sax_data)); -} - - -/* - * 'mxmlSAXLoadFile()' - Load a file into an XML node tree - * using a SAX callback. - * - * The nodes in the specified file are added to the specified top node. - * If no top node is provided, the XML file MUST be well-formed with a - * single parent node like for the entire file. The callback - * function returns the value type that should be used for child nodes. - * If MXML_NO_CALLBACK is specified then all child nodes will be either - * MXML_ELEMENT or MXML_TEXT nodes. - * - * The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, - * MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading - * child nodes of the specified type. - * - * The SAX callback must call mxmlRetain() for any nodes that need to - * be kept for later use. Otherwise, nodes are deleted when the parent - * node is closed or after each data, comment, CDATA, or directive node. - * - * @since Mini-XML 2.3@ - */ - -mxml_node_t * /* O - First node or NULL if the file could not be read. */ -mxmlSAXLoadFile( - mxml_node_t *top, /* I - Top node */ - FILE *fp, /* I - File to read from */ - mxml_load_cb_t cb, /* I - Callback function or MXML_NO_CALLBACK */ - mxml_sax_cb_t sax_cb, /* I - SAX callback or MXML_NO_CALLBACK */ - void *sax_data) /* I - SAX user data */ -{ - /* - * Read the XML data... - */ - - return (mxml_load_data(top, fp, cb, mxml_file_getc, sax_cb, sax_data)); -} - - -/* - * 'mxmlSAXLoadString()' - Load a string into an XML node tree - * using a SAX callback. - * - * The nodes in the specified string are added to the specified top node. - * If no top node is provided, the XML string MUST be well-formed with a - * single parent node like for the entire string. The callback - * function returns the value type that should be used for child nodes. - * If MXML_NO_CALLBACK is specified then all child nodes will be either - * MXML_ELEMENT or MXML_TEXT nodes. - * - * The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, - * MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading - * child nodes of the specified type. - * - * The SAX callback must call mxmlRetain() for any nodes that need to - * be kept for later use. Otherwise, nodes are deleted when the parent - * node is closed or after each data, comment, CDATA, or directive node. - * - * @since Mini-XML 2.3@ - */ - -mxml_node_t * /* O - First node or NULL if the string has errors. */ -mxmlSAXLoadString( - mxml_node_t *top, /* I - Top node */ - const char *s, /* I - String to load */ - mxml_load_cb_t cb, /* I - Callback function or MXML_NO_CALLBACK */ - mxml_sax_cb_t sax_cb, /* I - SAX callback or MXML_NO_CALLBACK */ - void *sax_data) /* I - SAX user data */ -{ - /* - * Read the XML data... - */ - - return (mxml_load_data(top, (void *)&s, cb, mxml_string_getc, sax_cb, sax_data)); -} - - -/* - * 'mxmlSetCustomHandlers()' - Set the handling functions for custom data. - * - * The load function accepts a node pointer and a data string and must - * return 0 on success and non-zero on error. - * - * The save function accepts a node pointer and must return a malloc'd - * string on success and NULL on error. - * - */ - -void -mxmlSetCustomHandlers( - mxml_custom_load_cb_t load, /* I - Load function */ - mxml_custom_save_cb_t save) /* I - Save function */ -{ - _mxml_global_t *global = _mxml_global(); - /* Global data */ - - - global->custom_load_cb = load; - global->custom_save_cb = save; -} - - -/* - * 'mxmlSetErrorCallback()' - Set the error message callback. - */ - -void -mxmlSetErrorCallback(mxml_error_cb_t cb)/* I - Error callback function */ -{ - _mxml_global_t *global = _mxml_global(); - /* Global data */ - - - global->error_cb = cb; -} - - -/* - * 'mxmlSetWrapMargin()' - Set the the wrap margin when saving XML data. - * - * Wrapping is disabled when "column" is <= 0. - * - * @since Mini-XML 2.3@ - */ - -void -mxmlSetWrapMargin(int column) /* I - Column for wrapping */ -{ - _mxml_global_t *global = _mxml_global(); - /* Global data */ - - - if (column <= 0) - global->wrap = 2147483647; - else - global->wrap = column; -} - - -/* - * 'mxml_add_char()' - Add a character to a buffer, expanding as needed. - */ - -static int /* O - 0 on success, -1 on error */ -mxml_add_char(int ch, /* I - Character to add */ - char **bufptr, /* IO - Current position in buffer */ - char **buffer, /* IO - Current buffer */ - int *bufsize) /* IO - Current buffer size */ -{ - char *newbuffer; /* New buffer value */ - - - if (*bufptr >= (*buffer + *bufsize - 4)) - { - /* - * Increase the size of the buffer... - */ - - if (*bufsize < 1024) - (*bufsize) *= 2; - else - (*bufsize) += 1024; - - if ((newbuffer = realloc(*buffer, *bufsize)) == NULL) - { - free(*buffer); - - mxml_error("Unable to expand string buffer to %d bytes!", *bufsize); - - return (-1); - } - - *bufptr = newbuffer + (*bufptr - *buffer); - *buffer = newbuffer; - } - - if (ch < 0x80) - { - /* - * Single byte ASCII... - */ - - *(*bufptr)++ = ch; - } - else if (ch < 0x800) - { - /* - * Two-byte UTF-8... - */ - - *(*bufptr)++ = 0xc0 | (ch >> 6); - *(*bufptr)++ = 0x80 | (ch & 0x3f); - } - else if (ch < 0x10000) - { - /* - * Three-byte UTF-8... - */ - - *(*bufptr)++ = 0xe0 | (ch >> 12); - *(*bufptr)++ = 0x80 | ((ch >> 6) & 0x3f); - *(*bufptr)++ = 0x80 | (ch & 0x3f); - } - else - { - /* - * Four-byte UTF-8... - */ - - *(*bufptr)++ = 0xf0 | (ch >> 18); - *(*bufptr)++ = 0x80 | ((ch >> 12) & 0x3f); - *(*bufptr)++ = 0x80 | ((ch >> 6) & 0x3f); - *(*bufptr)++ = 0x80 | (ch & 0x3f); - } - - return (0); -} - - -/* - * 'mxml_fd_getc()' - Read a character from a file descriptor. - */ - -static int /* O - Character or EOF */ -mxml_fd_getc(void *p, /* I - File descriptor buffer */ - int *encoding) /* IO - Encoding */ -{ - _mxml_fdbuf_t *buf; /* File descriptor buffer */ - int ch, /* Current character */ - temp; /* Temporary character */ - - - /* - * Grab the next character in the buffer... - */ - - buf = (_mxml_fdbuf_t *)p; - - if (buf->current >= buf->end) - if (mxml_fd_read(buf) < 0) - return (EOF); - - ch = *(buf->current)++; - - switch (*encoding) - { - case ENCODE_UTF8 : - /* - * Got a UTF-8 character; convert UTF-8 to Unicode and return... - */ - - if (!(ch & 0x80)) - { -#if DEBUG > 1 - printf("mxml_fd_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ - - if (mxml_bad_char(ch)) - { - mxml_error("Bad control character 0x%02x not allowed by XML standard!", - ch); - return (EOF); - } - - return (ch); - } - else if (ch == 0xfe) - { - /* - * UTF-16 big-endian BOM? - */ - - if (buf->current >= buf->end) - if (mxml_fd_read(buf) < 0) - return (EOF); - - ch = *(buf->current)++; - - if (ch != 0xff) - return (EOF); - - *encoding = ENCODE_UTF16BE; - - return (mxml_fd_getc(p, encoding)); - } - else if (ch == 0xff) - { - /* - * UTF-16 little-endian BOM? - */ - - if (buf->current >= buf->end) - if (mxml_fd_read(buf) < 0) - return (EOF); - - ch = *(buf->current)++; - - if (ch != 0xfe) - return (EOF); - - *encoding = ENCODE_UTF16LE; - - return (mxml_fd_getc(p, encoding)); - } - else if ((ch & 0xe0) == 0xc0) - { - /* - * Two-byte value... - */ - - if (buf->current >= buf->end) - if (mxml_fd_read(buf) < 0) - return (EOF); - - temp = *(buf->current)++; - - if ((temp & 0xc0) != 0x80) - return (EOF); - - ch = ((ch & 0x1f) << 6) | (temp & 0x3f); - - if (ch < 0x80) - return (EOF); - } - else if ((ch & 0xf0) == 0xe0) - { - /* - * Three-byte value... - */ - - if (buf->current >= buf->end) - if (mxml_fd_read(buf) < 0) - return (EOF); - - temp = *(buf->current)++; - - if ((temp & 0xc0) != 0x80) - return (EOF); - - ch = ((ch & 0x0f) << 6) | (temp & 0x3f); - - if (buf->current >= buf->end) - if (mxml_fd_read(buf) < 0) - return (EOF); - - temp = *(buf->current)++; - - if ((temp & 0xc0) != 0x80) - return (EOF); - - ch = (ch << 6) | (temp & 0x3f); - - if (ch < 0x800) - return (EOF); - } - else if ((ch & 0xf8) == 0xf0) - { - /* - * Four-byte value... - */ - - if (buf->current >= buf->end) - if (mxml_fd_read(buf) < 0) - return (EOF); - - temp = *(buf->current)++; - - if ((temp & 0xc0) != 0x80) - return (EOF); - - ch = ((ch & 0x07) << 6) | (temp & 0x3f); - - if (buf->current >= buf->end) - if (mxml_fd_read(buf) < 0) - return (EOF); - - temp = *(buf->current)++; - - if ((temp & 0xc0) != 0x80) - return (EOF); - - ch = (ch << 6) | (temp & 0x3f); - - if (buf->current >= buf->end) - if (mxml_fd_read(buf) < 0) - return (EOF); - - temp = *(buf->current)++; - - if ((temp & 0xc0) != 0x80) - return (EOF); - - ch = (ch << 6) | (temp & 0x3f); - - if (ch < 0x10000) - return (EOF); - } - else - return (EOF); - break; - - case ENCODE_UTF16BE : - /* - * Read UTF-16 big-endian char... - */ - - if (buf->current >= buf->end) - if (mxml_fd_read(buf) < 0) - return (EOF); - - temp = *(buf->current)++; - - ch = (ch << 8) | temp; - - if (mxml_bad_char(ch)) - { - mxml_error("Bad control character 0x%02x not allowed by XML standard!", - ch); - return (EOF); - } - else if (ch >= 0xd800 && ch <= 0xdbff) - { - /* - * Multi-word UTF-16 char... - */ - - int lch; - - if (buf->current >= buf->end) - if (mxml_fd_read(buf) < 0) - return (EOF); - - lch = *(buf->current)++; - - if (buf->current >= buf->end) - if (mxml_fd_read(buf) < 0) - return (EOF); - - temp = *(buf->current)++; - - lch = (lch << 8) | temp; - - if (lch < 0xdc00 || lch >= 0xdfff) - return (EOF); - - ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; - } - break; - - case ENCODE_UTF16LE : - /* - * Read UTF-16 little-endian char... - */ - - if (buf->current >= buf->end) - if (mxml_fd_read(buf) < 0) - return (EOF); - - temp = *(buf->current)++; - - ch |= (temp << 8); - - if (mxml_bad_char(ch)) - { - mxml_error("Bad control character 0x%02x not allowed by XML standard!", - ch); - return (EOF); - } - else if (ch >= 0xd800 && ch <= 0xdbff) - { - /* - * Multi-word UTF-16 char... - */ - - int lch; - - if (buf->current >= buf->end) - if (mxml_fd_read(buf) < 0) - return (EOF); - - lch = *(buf->current)++; - - if (buf->current >= buf->end) - if (mxml_fd_read(buf) < 0) - return (EOF); - - temp = *(buf->current)++; - - lch |= (temp << 8); - - if (lch < 0xdc00 || lch >= 0xdfff) - return (EOF); - - ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; - } - break; - } - -#if DEBUG > 1 - printf("mxml_fd_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ - - return (ch); -} - - -/* - * 'mxml_fd_putc()' - Write a character to a file descriptor. - */ - -static int /* O - 0 on success, -1 on error */ -mxml_fd_putc(int ch, /* I - Character */ - void *p) /* I - File descriptor buffer */ -{ - _mxml_fdbuf_t *buf; /* File descriptor buffer */ - - - /* - * Flush the write buffer as needed - note above that "end" still leaves - * 4 characters at the end so that we can avoid a lot of extra tests... - */ - - buf = (_mxml_fdbuf_t *)p; - - if (buf->current >= buf->end) - if (mxml_fd_write(buf) < 0) - return (-1); - - if (ch < 0x80) - { - /* - * Write ASCII character directly... - */ - - *(buf->current)++ = ch; - } - else if (ch < 0x800) - { - /* - * Two-byte UTF-8 character... - */ - - *(buf->current)++ = 0xc0 | (ch >> 6); - *(buf->current)++ = 0x80 | (ch & 0x3f); - } - else if (ch < 0x10000) - { - /* - * Three-byte UTF-8 character... - */ - - *(buf->current)++ = 0xe0 | (ch >> 12); - *(buf->current)++ = 0x80 | ((ch >> 6) & 0x3f); - *(buf->current)++ = 0x80 | (ch & 0x3f); - } - else - { - /* - * Four-byte UTF-8 character... - */ - - *(buf->current)++ = 0xf0 | (ch >> 18); - *(buf->current)++ = 0x80 | ((ch >> 12) & 0x3f); - *(buf->current)++ = 0x80 | ((ch >> 6) & 0x3f); - *(buf->current)++ = 0x80 | (ch & 0x3f); - } - - /* - * Return successfully... - */ - - return (0); -} - - -/* - * 'mxml_fd_read()' - Read a buffer of data from a file descriptor. - */ - -static int /* O - 0 on success, -1 on error */ -mxml_fd_read(_mxml_fdbuf_t *buf) /* I - File descriptor buffer */ -{ - int bytes; /* Bytes read... */ - - - /* - * Range check input... - */ - - if (!buf) - return (-1); - - /* - * Read from the file descriptor... - */ - - while ((bytes = read(buf->fd, buf->buffer, sizeof(buf->buffer))) < 0) -#ifdef EINTR - if (errno != EAGAIN && errno != EINTR) -#else - if (errno != EAGAIN) -#endif /* EINTR */ - return (-1); - - if (bytes == 0) - return (-1); - - /* - * Update the pointers and return success... - */ - - buf->current = buf->buffer; - buf->end = buf->buffer + bytes; - - return (0); -} - - -/* - * 'mxml_fd_write()' - Write a buffer of data to a file descriptor. - */ - -static int /* O - 0 on success, -1 on error */ -mxml_fd_write(_mxml_fdbuf_t *buf) /* I - File descriptor buffer */ -{ - int bytes; /* Bytes written */ - unsigned char *ptr; /* Pointer into buffer */ - - - /* - * Range check... - */ - - if (!buf) - return (-1); - - /* - * Return 0 if there is nothing to write... - */ - - if (buf->current == buf->buffer) - return (0); - - /* - * Loop until we have written everything... - */ - - for (ptr = buf->buffer; ptr < buf->current; ptr += bytes) - if ((bytes = write(buf->fd, ptr, buf->current - ptr)) < 0) - return (-1); - - /* - * All done, reset pointers and return success... - */ - - buf->current = buf->buffer; - - return (0); -} - - -/* - * 'mxml_file_getc()' - Get a character from a file. - */ - -static int /* O - Character or EOF */ -mxml_file_getc(void *p, /* I - Pointer to file */ - int *encoding) /* IO - Encoding */ -{ - int ch, /* Character from file */ - temp; /* Temporary character */ - FILE *fp; /* Pointer to file */ - - - /* - * Read a character from the file and see if it is EOF or ASCII... - */ - - fp = (FILE *)p; - ch = getc(fp); - - if (ch == EOF) - return (EOF); - - switch (*encoding) - { - case ENCODE_UTF8 : - /* - * Got a UTF-8 character; convert UTF-8 to Unicode and return... - */ - - if (!(ch & 0x80)) - { - if (mxml_bad_char(ch)) - { - mxml_error("Bad control character 0x%02x not allowed by XML standard!", - ch); - return (EOF); - } - -#if DEBUG > 1 - printf("mxml_file_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ - - return (ch); - } - else if (ch == 0xfe) - { - /* - * UTF-16 big-endian BOM? - */ - - ch = getc(fp); - if (ch != 0xff) - return (EOF); - - *encoding = ENCODE_UTF16BE; - - return (mxml_file_getc(p, encoding)); - } - else if (ch == 0xff) - { - /* - * UTF-16 little-endian BOM? - */ - - ch = getc(fp); - if (ch != 0xfe) - return (EOF); - - *encoding = ENCODE_UTF16LE; - - return (mxml_file_getc(p, encoding)); - } - else if ((ch & 0xe0) == 0xc0) - { - /* - * Two-byte value... - */ - - if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) - return (EOF); - - ch = ((ch & 0x1f) << 6) | (temp & 0x3f); - - if (ch < 0x80) - return (EOF); - } - else if ((ch & 0xf0) == 0xe0) - { - /* - * Three-byte value... - */ - - if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) - return (EOF); - - ch = ((ch & 0x0f) << 6) | (temp & 0x3f); - - if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) - return (EOF); - - ch = (ch << 6) | (temp & 0x3f); - - if (ch < 0x800) - return (EOF); - } - else if ((ch & 0xf8) == 0xf0) - { - /* - * Four-byte value... - */ - - if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) - return (EOF); - - ch = ((ch & 0x07) << 6) | (temp & 0x3f); - - if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) - return (EOF); - - ch = (ch << 6) | (temp & 0x3f); - - if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) - return (EOF); - - ch = (ch << 6) | (temp & 0x3f); - - if (ch < 0x10000) - return (EOF); - } - else - return (EOF); - break; - - case ENCODE_UTF16BE : - /* - * Read UTF-16 big-endian char... - */ - - ch = (ch << 8) | getc(fp); - - if (mxml_bad_char(ch)) - { - mxml_error("Bad control character 0x%02x not allowed by XML standard!", - ch); - return (EOF); - } - else if (ch >= 0xd800 && ch <= 0xdbff) - { - /* - * Multi-word UTF-16 char... - */ - - int lch = (getc(fp) << 8) | getc(fp); - - if (lch < 0xdc00 || lch >= 0xdfff) - return (EOF); - - ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; - } - break; - - case ENCODE_UTF16LE : - /* - * Read UTF-16 little-endian char... - */ - - ch |= (getc(fp) << 8); - - if (mxml_bad_char(ch)) - { - mxml_error("Bad control character 0x%02x not allowed by XML standard!", - ch); - return (EOF); - } - else if (ch >= 0xd800 && ch <= 0xdbff) - { - /* - * Multi-word UTF-16 char... - */ - - int lch = getc(fp) | (getc(fp) << 8); - - if (lch < 0xdc00 || lch >= 0xdfff) - return (EOF); - - ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; - } - break; - } - -#if DEBUG > 1 - printf("mxml_file_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ - - return (ch); -} - - -/* - * 'mxml_file_putc()' - Write a character to a file. - */ - -static int /* O - 0 on success, -1 on failure */ -mxml_file_putc(int ch, /* I - Character to write */ - void *p) /* I - Pointer to file */ -{ - char buffer[4], /* Buffer for character */ - *bufptr; /* Pointer into buffer */ - int buflen; /* Number of bytes to write */ - - - if (ch < 0x80) - return (putc(ch, (FILE *)p) == EOF ? -1 : 0); - - bufptr = buffer; - - if (ch < 0x800) - { - /* - * Two-byte UTF-8 character... - */ - - *bufptr++ = 0xc0 | (ch >> 6); - *bufptr++ = 0x80 | (ch & 0x3f); - } - else if (ch < 0x10000) - { - /* - * Three-byte UTF-8 character... - */ - - *bufptr++ = 0xe0 | (ch >> 12); - *bufptr++ = 0x80 | ((ch >> 6) & 0x3f); - *bufptr++ = 0x80 | (ch & 0x3f); - } - else - { - /* - * Four-byte UTF-8 character... - */ - - *bufptr++ = 0xf0 | (ch >> 18); - *bufptr++ = 0x80 | ((ch >> 12) & 0x3f); - *bufptr++ = 0x80 | ((ch >> 6) & 0x3f); - *bufptr++ = 0x80 | (ch & 0x3f); - } - - buflen = bufptr - buffer; - - return (fwrite(buffer, 1, buflen, (FILE *)p) < buflen ? -1 : 0); -} - - -/* - * 'mxml_get_entity()' - Get the character corresponding to an entity... - */ - -static int /* O - Character value or EOF on error */ -mxml_get_entity(mxml_node_t *parent, /* I - Parent node */ - void *p, /* I - Pointer to source */ - int *encoding, /* IO - Character encoding */ - int (*getc_cb)(void *, int *)) - /* I - Get character function */ -{ - int ch; /* Current character */ - char entity[64], /* Entity string */ - *entptr; /* Pointer into entity */ - - - entptr = entity; - - while ((ch = (*getc_cb)(p, encoding)) != EOF) - if (ch > 126 || (!isalnum(ch) && ch != '#')) - break; - else if (entptr < (entity + sizeof(entity) - 1)) - *entptr++ = ch; - else - { - mxml_error("Entity name too long under parent <%s>!", - parent ? parent->value.element.name : "null"); - break; - } - - *entptr = '\0'; - - if (ch != ';') - { - mxml_error("Character entity \"%s\" not terminated under parent <%s>!", - entity, parent ? parent->value.element.name : "null"); - return (EOF); - } - - if (entity[0] == '#') - { - if (entity[1] == 'x') - ch = strtol(entity + 2, NULL, 16); - else - ch = strtol(entity + 1, NULL, 10); - } - else if ((ch = mxmlEntityGetValue(entity)) < 0) - mxml_error("Entity name \"%s;\" not supported under parent <%s>!", - entity, parent ? parent->value.element.name : "null"); - - if (mxml_bad_char(ch)) - { - mxml_error("Bad control character 0x%02x under parent <%s> not allowed by XML standard!", - ch, parent ? parent->value.element.name : "null"); - return (EOF); - } - - return (ch); -} - - -/* - * 'mxml_load_data()' - Load data into an XML node tree. - */ - -static mxml_node_t * /* O - First node or NULL if the file could not be read. */ -mxml_load_data( - mxml_node_t *top, /* I - Top node */ - void *p, /* I - Pointer to data */ - mxml_load_cb_t cb, /* I - Callback function or MXML_NO_CALLBACK */ - _mxml_getc_cb_t getc_cb, /* I - Read function */ - mxml_sax_cb_t sax_cb, /* I - SAX callback or MXML_NO_CALLBACK */ - void *sax_data) /* I - SAX user data */ -{ - mxml_node_t *node, /* Current node */ - *first, /* First node added */ - *parent; /* Current parent node */ - int ch, /* Character from file */ - whitespace; /* Non-zero if whitespace seen */ - char *buffer, /* String buffer */ - *bufptr; /* Pointer into buffer */ - int bufsize; /* Size of buffer */ - mxml_type_t type; /* Current node type */ - int encoding; /* Character encoding */ - _mxml_global_t *global = _mxml_global(); - /* Global data */ - static const char * const types[] = /* Type strings... */ - { - "MXML_ELEMENT", /* XML element with attributes */ - "MXML_INTEGER", /* Integer value */ - "MXML_OPAQUE", /* Opaque string */ - "MXML_REAL", /* Real value */ - "MXML_TEXT", /* Text fragment */ - "MXML_CUSTOM" /* Custom data */ - }; - - - /* - * Read elements and other nodes from the file... - */ - - if ((buffer = malloc(64)) == NULL) - { - mxml_error("Unable to allocate string buffer!"); - return (NULL); - } - - bufsize = 64; - bufptr = buffer; - parent = top; - first = NULL; - whitespace = 0; - encoding = ENCODE_UTF8; - - if (cb && parent) - type = (*cb)(parent); - else - type = MXML_TEXT; - - while ((ch = (*getc_cb)(p, &encoding)) != EOF) - { - if ((ch == '<' || - (mxml_isspace(ch) && type != MXML_OPAQUE && type != MXML_CUSTOM)) && - bufptr > buffer) - { - /* - * Add a new value node... - */ - - *bufptr = '\0'; - - switch (type) - { - case MXML_INTEGER : - node = mxmlNewInteger(parent, strtol(buffer, &bufptr, 0)); - break; - - case MXML_OPAQUE : - node = mxmlNewOpaque(parent, buffer); - break; - - case MXML_REAL : - node = mxmlNewReal(parent, strtod(buffer, &bufptr)); - break; - - case MXML_TEXT : - node = mxmlNewText(parent, whitespace, buffer); - break; - - case MXML_CUSTOM : - if (global->custom_load_cb) - { - /* - * Use the callback to fill in the custom data... - */ - - node = mxmlNewCustom(parent, NULL, NULL); - - if ((*global->custom_load_cb)(node, buffer)) - { - mxml_error("Bad custom value '%s' in parent <%s>!", - buffer, parent ? parent->value.element.name : "null"); - mxmlDelete(node); - node = NULL; - } - break; - } - - default : /* Ignore... */ - node = NULL; - break; - } - - if (*bufptr) - { - /* - * Bad integer/real number value... - */ - - mxml_error("Bad %s value '%s' in parent <%s>!", - type == MXML_INTEGER ? "integer" : "real", buffer, - parent ? parent->value.element.name : "null"); - break; - } - - bufptr = buffer; - whitespace = mxml_isspace(ch) && type == MXML_TEXT; - - if (!node && type != MXML_IGNORE) - { - /* - * Print error and return... - */ - - mxml_error("Unable to add value node of type %s to parent <%s>!", - types[type], parent ? parent->value.element.name : "null"); - goto error; - } - - if (sax_cb) - { - (*sax_cb)(node, MXML_SAX_DATA, sax_data); - - if (!mxmlRelease(node)) - node = NULL; - } - - if (!first && node) - first = node; - } - else if (mxml_isspace(ch) && type == MXML_TEXT) - whitespace = 1; - - /* - * Add lone whitespace node if we have an element and existing - * whitespace... - */ - - if (ch == '<' && whitespace && type == MXML_TEXT) - { - node = mxmlNewText(parent, whitespace, ""); - - if (sax_cb) - { - (*sax_cb)(node, MXML_SAX_DATA, sax_data); - - if (!mxmlRelease(node)) - node = NULL; - } - - if (!first && node) - first = node; - - whitespace = 0; - } - - if (ch == '<') - { - /* - * Start of open/close tag... - */ - - bufptr = buffer; - - while ((ch = (*getc_cb)(p, &encoding)) != EOF) - if (mxml_isspace(ch) || ch == '>' || (ch == '/' && bufptr > buffer)) - break; - else if (ch == '<') - { - mxml_error("Bare < in element!"); - goto error; - } - else if (ch == '&') - { - if ((ch = mxml_get_entity(parent, p, &encoding, getc_cb)) == EOF) - goto error; - - if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) - goto error; - } - else if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) - goto error; - else if (((bufptr - buffer) == 1 && buffer[0] == '?') || - ((bufptr - buffer) == 3 && !strncmp(buffer, "!--", 3)) || - ((bufptr - buffer) == 8 && !strncmp(buffer, "![CDATA[", 8))) - break; - - *bufptr = '\0'; - - if (!strcmp(buffer, "!--")) - { - /* - * Gather rest of comment... - */ - - while ((ch = (*getc_cb)(p, &encoding)) != EOF) - { - if (ch == '>' && bufptr > (buffer + 4) && - bufptr[-3] != '-' && bufptr[-2] == '-' && bufptr[-1] == '-') - break; - else if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) - goto error; - } - - /* - * Error out if we didn't get the whole comment... - */ - - if (ch != '>') - { - /* - * Print error and return... - */ - - mxml_error("Early EOF in comment node!"); - goto error; - } - - - /* - * Otherwise add this as an element under the current parent... - */ - - *bufptr = '\0'; - - if ((node = mxmlNewElement(parent, buffer)) == NULL) - { - /* - * Just print error for now... - */ - - mxml_error("Unable to add comment node to parent <%s>!", - parent ? parent->value.element.name : "null"); - break; - } - - if (sax_cb) - { - (*sax_cb)(node, MXML_SAX_COMMENT, sax_data); - - if (!mxmlRelease(node)) - node = NULL; - } - - if (node && !first) - first = node; - } - else if (!strcmp(buffer, "![CDATA[")) - { - /* - * Gather CDATA section... - */ - - while ((ch = (*getc_cb)(p, &encoding)) != EOF) - { - if (ch == '>' && !strncmp(bufptr - 2, "]]", 2)) - break; - else if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) - goto error; - } - - /* - * Error out if we didn't get the whole comment... - */ - - if (ch != '>') - { - /* - * Print error and return... - */ - - mxml_error("Early EOF in CDATA node!"); - goto error; - } - - - /* - * Otherwise add this as an element under the current parent... - */ - - *bufptr = '\0'; - - if ((node = mxmlNewElement(parent, buffer)) == NULL) - { - /* - * Print error and return... - */ - - mxml_error("Unable to add CDATA node to parent <%s>!", - parent ? parent->value.element.name : "null"); - goto error; - } - - if (sax_cb) - { - (*sax_cb)(node, MXML_SAX_CDATA, sax_data); - - if (!mxmlRelease(node)) - node = NULL; - } - - if (node && !first) - first = node; - } - else if (buffer[0] == '?') - { - /* - * Gather rest of processing instruction... - */ - - while ((ch = (*getc_cb)(p, &encoding)) != EOF) - { - if (ch == '>' && bufptr > buffer && bufptr[-1] == '?') - break; - else if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) - goto error; - } - - /* - * Error out if we didn't get the whole processing instruction... - */ - - if (ch != '>') - { - /* - * Print error and return... - */ - - mxml_error("Early EOF in processing instruction node!"); - goto error; - } - - /* - * Otherwise add this as an element under the current parent... - */ - - *bufptr = '\0'; - - if ((node = mxmlNewElement(parent, buffer)) == NULL) - { - /* - * Print error and return... - */ - - mxml_error("Unable to add processing instruction node to parent <%s>!", - parent ? parent->value.element.name : "null"); - goto error; - } - - if (sax_cb) - { - (*sax_cb)(node, MXML_SAX_DIRECTIVE, sax_data); - - if (!mxmlRelease(node)) - node = NULL; - } - - if (node) - { - if (!first) - first = node; - - if (!parent) - { - parent = node; - - if (cb) - type = (*cb)(parent); - } - } - } - else if (buffer[0] == '!') - { - /* - * Gather rest of declaration... - */ - - do - { - if (ch == '>') - break; - else - { - if (ch == '&') - if ((ch = mxml_get_entity(parent, p, &encoding, getc_cb)) == EOF) - goto error; - - if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) - goto error; - } - } - while ((ch = (*getc_cb)(p, &encoding)) != EOF); - - /* - * Error out if we didn't get the whole declaration... - */ - - if (ch != '>') - { - /* - * Print error and return... - */ - - mxml_error("Early EOF in declaration node!"); - goto error; - } - - /* - * Otherwise add this as an element under the current parent... - */ - - *bufptr = '\0'; - - if ((node = mxmlNewElement(parent, buffer)) == NULL) - { - /* - * Print error and return... - */ - - mxml_error("Unable to add declaration node to parent <%s>!", - parent ? parent->value.element.name : "null"); - goto error; - } - - if (sax_cb) - { - (*sax_cb)(node, MXML_SAX_DIRECTIVE, sax_data); - - if (!mxmlRelease(node)) - node = NULL; - } - - if (node) - { - if (!first) - first = node; - - if (!parent) - { - parent = node; - - if (cb) - type = (*cb)(parent); - } - } - } - else if (buffer[0] == '/') - { - /* - * Handle close tag... - */ - - if (!parent || strcmp(buffer + 1, parent->value.element.name)) - { - /* - * Close tag doesn't match tree; print an error for now... - */ - - mxml_error("Mismatched close tag <%s> under parent <%s>!", - buffer, parent ? parent->value.element.name : "(null)"); - goto error; - } - - /* - * Keep reading until we see >... - */ - - while (ch != '>' && ch != EOF) - ch = (*getc_cb)(p, &encoding); - - node = parent; - parent = parent->parent; - - if (sax_cb) - { - (*sax_cb)(node, MXML_SAX_ELEMENT_CLOSE, sax_data); - - mxmlRelease(node); - } - - /* - * Ascend into the parent and set the value type as needed... - */ - - if (cb && parent) - type = (*cb)(parent); - } - else - { - /* - * Handle open tag... - */ - - if ((node = mxmlNewElement(parent, buffer)) == NULL) - { - /* - * Just print error for now... - */ - - mxml_error("Unable to add element node to parent <%s>!", - parent ? parent->value.element.name : "null"); - goto error; - } - - if (mxml_isspace(ch)) - { - if ((ch = mxml_parse_element(node, p, &encoding, getc_cb)) == EOF) - goto error; - } - else if (ch == '/') - { - if ((ch = (*getc_cb)(p, &encoding)) != '>') - { - mxml_error("Expected > but got '%c' instead for element <%s/>!", - ch, buffer); - mxmlDelete(node); - goto error; - } - - ch = '/'; - } - - if (sax_cb) - (*sax_cb)(node, MXML_SAX_ELEMENT_OPEN, sax_data); - - if (!first) - first = node; - - if (ch == EOF) - break; - - if (ch != '/') - { - /* - * Descend into this node, setting the value type as needed... - */ - - parent = node; - - if (cb && parent) - type = (*cb)(parent); - } - else if (sax_cb) - { - (*sax_cb)(node, MXML_SAX_ELEMENT_CLOSE, sax_data); - - if (!mxmlRelease(node) && first == node) - first = NULL; - } - } - - bufptr = buffer; - } - else if (ch == '&') - { - /* - * Add character entity to current buffer... - */ - - if ((ch = mxml_get_entity(parent, p, &encoding, getc_cb)) == EOF) - goto error; - - if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) - goto error; - } - else if (type == MXML_OPAQUE || type == MXML_CUSTOM || !mxml_isspace(ch)) - { - /* - * Add character to current buffer... - */ - - if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) - goto error; - } - } - - /* - * Free the string buffer - we don't need it anymore... - */ - - free(buffer); - - /* - * Find the top element and return it... - */ - - if (parent) - { - node = parent; - - while (parent->parent != top && parent->parent) - parent = parent->parent; - - if (node != parent) - { - mxml_error("Missing close tag under parent <%s>!", - node->value.element.name, - node->parent ? node->parent->value.element.name : "(null)"); - - mxmlDelete(first); - - return (NULL); - } - } - - if (parent) - return (parent); - else - return (first); - - /* - * Common error return... - */ - -error: - - mxmlDelete(first); - - free(buffer); - - return (NULL); -} - - -/* - * 'mxml_parse_element()' - Parse an element for any attributes... - */ - -static int /* O - Terminating character */ -mxml_parse_element( - mxml_node_t *node, /* I - Element node */ - void *p, /* I - Data to read from */ - int *encoding, /* IO - Encoding */ - _mxml_getc_cb_t getc_cb) /* I - Data callback */ -{ - int ch, /* Current character in file */ - quote; /* Quoting character */ - char *name, /* Attribute name */ - *value, /* Attribute value */ - *ptr; /* Pointer into name/value */ - int namesize, /* Size of name string */ - valsize; /* Size of value string */ - - - /* - * Initialize the name and value buffers... - */ - - if ((name = malloc(64)) == NULL) - { - mxml_error("Unable to allocate memory for name!"); - return (EOF); - } - - namesize = 64; - - if ((value = malloc(64)) == NULL) - { - free(name); - mxml_error("Unable to allocate memory for value!"); - return (EOF); - } - - valsize = 64; - - /* - * Loop until we hit a >, /, ?, or EOF... - */ - - while ((ch = (*getc_cb)(p, encoding)) != EOF) - { -#if DEBUG > 1 - fprintf(stderr, "parse_element: ch='%c'\n", ch); -#endif /* DEBUG > 1 */ - - /* - * Skip leading whitespace... - */ - - if (mxml_isspace(ch)) - continue; - - /* - * Stop at /, ?, or >... - */ - - if (ch == '/' || ch == '?') - { - /* - * Grab the > character and print an error if it isn't there... - */ - - quote = (*getc_cb)(p, encoding); - - if (quote != '>') - { - mxml_error("Expected '>' after '%c' for element %s, but got '%c'!", - ch, node->value.element.name, quote); - goto error; - } - - break; - } - else if (ch == '<') - { - mxml_error("Bare < in element %s!", node->value.element.name); - goto error; - } - else if (ch == '>') - break; - - /* - * Read the attribute name... - */ - - name[0] = ch; - ptr = name + 1; - - if (ch == '\"' || ch == '\'') - { - /* - * Name is in quotes, so get a quoted string... - */ - - quote = ch; - - while ((ch = (*getc_cb)(p, encoding)) != EOF) - { - if (ch == '&') - if ((ch = mxml_get_entity(node, p, encoding, getc_cb)) == EOF) - goto error; - - if (mxml_add_char(ch, &ptr, &name, &namesize)) - goto error; - - if (ch == quote) - break; - } - } - else - { - /* - * Grab an normal, non-quoted name... - */ - - while ((ch = (*getc_cb)(p, encoding)) != EOF) - if (mxml_isspace(ch) || ch == '=' || ch == '/' || ch == '>' || - ch == '?') - break; - else - { - if (ch == '&') - if ((ch = mxml_get_entity(node, p, encoding, getc_cb)) == EOF) - goto error; - - if (mxml_add_char(ch, &ptr, &name, &namesize)) - goto error; - } - } - - *ptr = '\0'; - - if (mxmlElementGetAttr(node, name)) - goto error; - - while (ch != EOF && mxml_isspace(ch)) - ch = (*getc_cb)(p, encoding); - - if (ch == '=') - { - /* - * Read the attribute value... - */ - - while ((ch = (*getc_cb)(p, encoding)) != EOF && mxml_isspace(ch)); - - if (ch == EOF) - { - mxml_error("Missing value for attribute '%s' in element %s!", - name, node->value.element.name); - goto error; - } - - if (ch == '\'' || ch == '\"') - { - /* - * Read quoted value... - */ - - quote = ch; - ptr = value; - - while ((ch = (*getc_cb)(p, encoding)) != EOF) - if (ch == quote) - break; - else - { - if (ch == '&') - if ((ch = mxml_get_entity(node, p, encoding, getc_cb)) == EOF) - goto error; - - if (mxml_add_char(ch, &ptr, &value, &valsize)) - goto error; - } - - *ptr = '\0'; - } - else - { - /* - * Read unquoted value... - */ - - value[0] = ch; - ptr = value + 1; - - while ((ch = (*getc_cb)(p, encoding)) != EOF) - if (mxml_isspace(ch) || ch == '=' || ch == '/' || ch == '>') - break; - else - { - if (ch == '&') - if ((ch = mxml_get_entity(node, p, encoding, getc_cb)) == EOF) - goto error; - - if (mxml_add_char(ch, &ptr, &value, &valsize)) - goto error; - } - - *ptr = '\0'; - } - - /* - * Set the attribute with the given string value... - */ - - mxmlElementSetAttr(node, name, value); - } - else - { - mxml_error("Missing value for attribute '%s' in element %s!", - name, node->value.element.name); - goto error; - } - - /* - * Check the end character... - */ - - if (ch == '/' || ch == '?') - { - /* - * Grab the > character and print an error if it isn't there... - */ - - quote = (*getc_cb)(p, encoding); - - if (quote != '>') - { - mxml_error("Expected '>' after '%c' for element %s, but got '%c'!", - ch, node->value.element.name, quote); - ch = EOF; - } - - break; - } - else if (ch == '>') - break; - } - - /* - * Free the name and value buffers and return... - */ - - free(name); - free(value); - - return (ch); - - /* - * Common error return point... - */ - -error: - - free(name); - free(value); - - return (EOF); -} - - -/* - * 'mxml_string_getc()' - Get a character from a string. - */ - -static int /* O - Character or EOF */ -mxml_string_getc(void *p, /* I - Pointer to file */ - int *encoding) /* IO - Encoding */ -{ - int ch; /* Character */ - const char **s; /* Pointer to string pointer */ - - - s = (const char **)p; - - if ((ch = (*s)[0] & 255) != 0 || *encoding == ENCODE_UTF16LE) - { - /* - * Got character; convert UTF-8 to integer and return... - */ - - (*s)++; - - switch (*encoding) - { - case ENCODE_UTF8 : - if (!(ch & 0x80)) - { -#if DEBUG > 1 - printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ - - if (mxml_bad_char(ch)) - { - mxml_error("Bad control character 0x%02x not allowed by XML standard!", - ch); - return (EOF); - } - - return (ch); - } - else if (ch == 0xfe) - { - /* - * UTF-16 big-endian BOM? - */ - - if (((*s)[0] & 255) != 0xff) - return (EOF); - - *encoding = ENCODE_UTF16BE; - (*s)++; - - return (mxml_string_getc(p, encoding)); - } - else if (ch == 0xff) - { - /* - * UTF-16 little-endian BOM? - */ - - if (((*s)[0] & 255) != 0xfe) - return (EOF); - - *encoding = ENCODE_UTF16LE; - (*s)++; - - return (mxml_string_getc(p, encoding)); - } - else if ((ch & 0xe0) == 0xc0) - { - /* - * Two-byte value... - */ - - if (((*s)[0] & 0xc0) != 0x80) - return (EOF); - - ch = ((ch & 0x1f) << 6) | ((*s)[0] & 0x3f); - - (*s)++; - - if (ch < 0x80) - return (EOF); - -#if DEBUG > 1 - printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ - - return (ch); - } - else if ((ch & 0xf0) == 0xe0) - { - /* - * Three-byte value... - */ - - if (((*s)[0] & 0xc0) != 0x80 || - ((*s)[1] & 0xc0) != 0x80) - return (EOF); - - ch = ((((ch & 0x0f) << 6) | ((*s)[0] & 0x3f)) << 6) | ((*s)[1] & 0x3f); - - (*s) += 2; - - if (ch < 0x800) - return (EOF); - -#if DEBUG > 1 - printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ - - return (ch); - } - else if ((ch & 0xf8) == 0xf0) - { - /* - * Four-byte value... - */ - - if (((*s)[0] & 0xc0) != 0x80 || - ((*s)[1] & 0xc0) != 0x80 || - ((*s)[2] & 0xc0) != 0x80) - return (EOF); - - ch = ((((((ch & 0x07) << 6) | ((*s)[0] & 0x3f)) << 6) | - ((*s)[1] & 0x3f)) << 6) | ((*s)[2] & 0x3f); - - (*s) += 3; - - if (ch < 0x10000) - return (EOF); - -#if DEBUG > 1 - printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ - - return (ch); - } - else - return (EOF); - - case ENCODE_UTF16BE : - /* - * Read UTF-16 big-endian char... - */ - - ch = (ch << 8) | ((*s)[0] & 255); - (*s) ++; - - if (mxml_bad_char(ch)) - { - mxml_error("Bad control character 0x%02x not allowed by XML standard!", - ch); - return (EOF); - } - else if (ch >= 0xd800 && ch <= 0xdbff) - { - /* - * Multi-word UTF-16 char... - */ - - int lch; /* Lower word */ - - - if (!(*s)[0]) - return (EOF); - - lch = (((*s)[0] & 255) << 8) | ((*s)[1] & 255); - (*s) += 2; - - if (lch < 0xdc00 || lch >= 0xdfff) - return (EOF); - - ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; - } - -#if DEBUG > 1 - printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ - - return (ch); - - case ENCODE_UTF16LE : - /* - * Read UTF-16 little-endian char... - */ - - ch = ch | (((*s)[0] & 255) << 8); - - if (!ch) - { - (*s) --; - return (EOF); - } - - (*s) ++; - - if (mxml_bad_char(ch)) - { - mxml_error("Bad control character 0x%02x not allowed by XML standard!", - ch); - return (EOF); - } - else if (ch >= 0xd800 && ch <= 0xdbff) - { - /* - * Multi-word UTF-16 char... - */ - - int lch; /* Lower word */ - - - if (!(*s)[1]) - return (EOF); - - lch = (((*s)[1] & 255) << 8) | ((*s)[0] & 255); - (*s) += 2; - - if (lch < 0xdc00 || lch >= 0xdfff) - return (EOF); - - ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; - } - -#if DEBUG > 1 - printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ - - return (ch); - } - } - - return (EOF); -} - - -/* - * 'mxml_string_putc()' - Write a character to a string. - */ - -static int /* O - 0 on success, -1 on failure */ -mxml_string_putc(int ch, /* I - Character to write */ - void *p) /* I - Pointer to string pointers */ -{ - char **pp; /* Pointer to string pointers */ - - - pp = (char **)p; - - if (ch < 0x80) - { - /* - * Plain ASCII doesn't need special encoding... - */ - - if (pp[0] < pp[1]) - pp[0][0] = ch; - - pp[0] ++; - } - else if (ch < 0x800) - { - /* - * Two-byte UTF-8 character... - */ - - if ((pp[0] + 1) < pp[1]) - { - pp[0][0] = 0xc0 | (ch >> 6); - pp[0][1] = 0x80 | (ch & 0x3f); - } - - pp[0] += 2; - } - else if (ch < 0x10000) - { - /* - * Three-byte UTF-8 character... - */ - - if ((pp[0] + 2) < pp[1]) - { - pp[0][0] = 0xe0 | (ch >> 12); - pp[0][1] = 0x80 | ((ch >> 6) & 0x3f); - pp[0][2] = 0x80 | (ch & 0x3f); - } - - pp[0] += 3; - } - else - { - /* - * Four-byte UTF-8 character... - */ - - if ((pp[0] + 2) < pp[1]) - { - pp[0][0] = 0xf0 | (ch >> 18); - pp[0][1] = 0x80 | ((ch >> 12) & 0x3f); - pp[0][2] = 0x80 | ((ch >> 6) & 0x3f); - pp[0][3] = 0x80 | (ch & 0x3f); - } - - pp[0] += 4; - } - - return (0); -} - - -/* - * 'mxml_write_name()' - Write a name string. - */ - -static int /* O - 0 on success, -1 on failure */ -mxml_write_name(const char *s, /* I - Name to write */ - void *p, /* I - Write pointer */ - int (*putc_cb)(int, void *)) - /* I - Write callback */ -{ - char quote; /* Quote character */ - const char *name; /* Entity name */ - - - if (*s == '\"' || *s == '\'') - { - /* - * Write a quoted name string... - */ - - if ((*putc_cb)(*s, p) < 0) - return (-1); - - quote = *s++; - - while (*s && *s != quote) - { - if ((name = mxmlEntityGetName(*s)) != NULL) - { - if ((*putc_cb)('&', p) < 0) - return (-1); - - while (*name) - { - if ((*putc_cb)(*name, p) < 0) - return (-1); - - name ++; - } - - if ((*putc_cb)(';', p) < 0) - return (-1); - } - else if ((*putc_cb)(*s, p) < 0) - return (-1); - - s ++; - } - - /* - * Write the end quote... - */ - - if ((*putc_cb)(quote, p) < 0) - return (-1); - } - else - { - /* - * Write a non-quoted name string... - */ - - while (*s) - { - if ((*putc_cb)(*s, p) < 0) - return (-1); - - s ++; - } - } - - return (0); -} - - -/* - * 'mxml_write_node()' - Save an XML node to a file. - */ - -static int /* O - Column or -1 on error */ -mxml_write_node(mxml_node_t *node, /* I - Node to write */ - void *p, /* I - File to write to */ - mxml_save_cb_t cb, /* I - Whitespace callback */ - int col, /* I - Current column */ - _mxml_putc_cb_t putc_cb,/* I - Output callback */ - _mxml_global_t *global)/* I - Global data */ -{ - int i, /* Looping var */ - width; /* Width of attr + value */ - mxml_attr_t *attr; /* Current attribute */ - char s[255]; /* Temporary string */ - - - while (node != NULL) - { - /* - * Print the node value... - */ - - switch (node->type) - { - case MXML_ELEMENT : - col = mxml_write_ws(node, p, cb, MXML_WS_BEFORE_OPEN, col, putc_cb); - - if ((*putc_cb)('<', p) < 0) - return (-1); - if (node->value.element.name[0] == '?' || - !strncmp(node->value.element.name, "!--", 3) || - !strncmp(node->value.element.name, "![CDATA[", 8)) - { - /* - * Comments, CDATA, and processing instructions do not - * use character entities. - */ - - const char *ptr; /* Pointer into name */ - - - for (ptr = node->value.element.name; *ptr; ptr ++) - if ((*putc_cb)(*ptr, p) < 0) - return (-1); - - /* - * Prefer a newline for whitespace after ?xml... - */ - - if (!strncmp(node->value.element.name, "?xml", 4)) - col = global->wrap; - } - else if (mxml_write_name(node->value.element.name, p, putc_cb) < 0) - return (-1); - - col += strlen(node->value.element.name) + 1; - - for (i = node->value.element.num_attrs, attr = node->value.element.attrs; - i > 0; - i --, attr ++) - { - width = strlen(attr->name); - - if (attr->value) - width += strlen(attr->value) + 3; - - if ((col + width) > global->wrap) - { - if ((*putc_cb)('\n', p) < 0) - return (-1); - - col = 0; - } - else - { - if ((*putc_cb)(' ', p) < 0) - return (-1); - - col ++; - } - - if (mxml_write_name(attr->name, p, putc_cb) < 0) - return (-1); - - if (attr->value) - { - if ((*putc_cb)('=', p) < 0) - return (-1); - if ((*putc_cb)('\"', p) < 0) - return (-1); - if (mxml_write_string(attr->value, p, putc_cb) < 0) - return (-1); - if ((*putc_cb)('\"', p) < 0) - return (-1); - } - - col += width; - } - - if (node->child) - { - /* - * Write children... - */ - - if ((*putc_cb)('>', p) < 0) - return (-1); - else - col ++; - - col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); - - if ((col = mxml_write_node(node->child, p, cb, col, putc_cb, - global)) < 0) - return (-1); - - /* - * The ? and ! elements are special-cases and have no end tags... - */ - - if (node->value.element.name[0] != '!' && - node->value.element.name[0] != '?') - { - col = mxml_write_ws(node, p, cb, MXML_WS_BEFORE_CLOSE, col, putc_cb); - - if ((*putc_cb)('<', p) < 0) - return (-1); - if ((*putc_cb)('/', p) < 0) - return (-1); - if (mxml_write_string(node->value.element.name, p, putc_cb) < 0) - return (-1); - if ((*putc_cb)('>', p) < 0) - return (-1); - - col += strlen(node->value.element.name) + 3; - - col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_CLOSE, col, putc_cb); - } - } - else if (node->value.element.name[0] == '!' || - node->value.element.name[0] == '?') - { - /* - * The ? and ! elements are special-cases... - */ - - if ((*putc_cb)('>', p) < 0) - return (-1); - else - col ++; - - col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); - } - else - { - if ((*putc_cb)(' ', p) < 0) - return (-1); - if ((*putc_cb)('/', p) < 0) - return (-1); - if ((*putc_cb)('>', p) < 0) - return (-1); - - col += 3; - - col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); - } - break; - - case MXML_INTEGER : - if (node->prev) - { - if (col > global->wrap) - { - if ((*putc_cb)('\n', p) < 0) - return (-1); - - col = 0; - } - else if ((*putc_cb)(' ', p) < 0) - return (-1); - else - col ++; - } - - sprintf(s, "%d", node->value.integer); - if (mxml_write_string(s, p, putc_cb) < 0) - return (-1); - - col += strlen(s); - break; - - case MXML_OPAQUE : - if (mxml_write_string(node->value.opaque, p, putc_cb) < 0) - return (-1); - - col += strlen(node->value.opaque); - break; - - case MXML_REAL : - if (node->prev) - { - if (col > global->wrap) - { - if ((*putc_cb)('\n', p) < 0) - return (-1); - - col = 0; - } - else if ((*putc_cb)(' ', p) < 0) - return (-1); - else - col ++; - } - - sprintf(s, "%f", node->value.real); - if (mxml_write_string(s, p, putc_cb) < 0) - return (-1); - - col += strlen(s); - break; - - case MXML_TEXT : - if (node->value.text.whitespace && col > 0) - { - if (col > global->wrap) - { - if ((*putc_cb)('\n', p) < 0) - return (-1); - - col = 0; - } - else if ((*putc_cb)(' ', p) < 0) - return (-1); - else - col ++; - } - - if (mxml_write_string(node->value.text.string, p, putc_cb) < 0) - return (-1); - - col += strlen(node->value.text.string); - break; - - case MXML_CUSTOM : - if (global->custom_save_cb) - { - char *data; /* Custom data string */ - const char *newline; /* Last newline in string */ - - - if ((data = (*global->custom_save_cb)(node)) == NULL) - return (-1); - - if (mxml_write_string(data, p, putc_cb) < 0) - return (-1); - - if ((newline = strrchr(data, '\n')) == NULL) - col += strlen(data); - else - col = strlen(newline); - - free(data); - break; - } - - default : /* Should never happen */ - return (-1); - } - - /* - * Next node... - */ - - node = node->next; - } - - return (col); -} - - -/* - * 'mxml_write_string()' - Write a string, escaping & and < as needed. - */ - -static int /* O - 0 on success, -1 on failure */ -mxml_write_string( - const char *s, /* I - String to write */ - void *p, /* I - Write pointer */ - _mxml_putc_cb_t putc_cb) /* I - Write callback */ -{ - const char *name; /* Entity name, if any */ - - - while (*s) - { - if ((name = mxmlEntityGetName(*s)) != NULL) - { - if ((*putc_cb)('&', p) < 0) - return (-1); - - while (*name) - { - if ((*putc_cb)(*name, p) < 0) - return (-1); - name ++; - } - - if ((*putc_cb)(';', p) < 0) - return (-1); - } - else if ((*putc_cb)(*s, p) < 0) - return (-1); - - s ++; - } - - return (0); -} - - -/* - * 'mxml_write_ws()' - Do whitespace callback... - */ - -static int /* O - New column */ -mxml_write_ws(mxml_node_t *node, /* I - Current node */ - void *p, /* I - Write pointer */ - mxml_save_cb_t cb, /* I - Callback function */ - int ws, /* I - Where value */ - int col, /* I - Current column */ - _mxml_putc_cb_t putc_cb) /* I - Write callback */ -{ - const char *s; /* Whitespace string */ - - - if (cb && (s = (*cb)(node, ws)) != NULL) - { - while (*s) - { - if ((*putc_cb)(*s, p) < 0) - return (-1); - else if (*s == '\n') - col = 0; - else if (*s == '\t') - { - col += MXML_TAB; - col = col - (col % MXML_TAB); - } - else - col ++; - - s ++; - } - } - - return (col); -} - - -/* - * End of "$Id: mxml-file.c 329 2008-01-13 00:42:35Z mike $". - */ diff --git a/plugins/zynaddsubfx/mxml/mxml-index.c b/plugins/zynaddsubfx/mxml/mxml-index.c deleted file mode 100644 index f8a7c0fcb..000000000 --- a/plugins/zynaddsubfx/mxml/mxml-index.c +++ /dev/null @@ -1,649 +0,0 @@ -/* - * "$Id: mxml-index.c 184 2005-01-29 07:21:44Z mike $" - * - * Index support code for Mini-XML, a small XML-like file parsing library. - * - * Copyright 2003-2005 by Michael Sweet. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2, 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. - * - * Contents: - * - * mxmlIndexDelete() - Delete an index. - * mxmlIndexEnum() - Return the next node in the index. - * mxmlIndexFind() - Find the next matching node. - * mxmlIndexNew() - Create a new index. - * mxmlIndexReset() - Reset the enumeration/find pointer in the index and - * return the first node in the index. - * index_compare() - Compare two nodes. - * index_find() - Compare a node with index values. - * index_sort() - Sort the nodes in the index... - */ - -/* - * Include necessary headers... - */ - -#include "mxml-config.h" -#include "mxml.h" - - -/* - * Sort functions... - */ - -static int index_compare(mxml_index_t *ind, mxml_node_t *first, - mxml_node_t *second); -static int index_find(mxml_index_t *ind, const char *element, - const char *value, mxml_node_t *node); -static void index_sort(mxml_index_t *ind, int left, int right); - - -/* - * 'mxmlIndexDelete()' - Delete an index. - */ - -void -mxmlIndexDelete(mxml_index_t *ind) /* I - Index to delete */ -{ - /* - * Range check input.. - */ - - if (!ind) - return; - - /* - * Free memory... - */ - - if (ind->attr) - free(ind->attr); - - if (ind->alloc_nodes) - free(ind->nodes); - - free(ind); -} - - -/* - * 'mxmlIndexEnum()' - Return the next node in the index. - * - * Nodes are returned in the sorted order of the index. - */ - -mxml_node_t * /* O - Next node or NULL if there is none */ -mxmlIndexEnum(mxml_index_t *ind) /* I - Index to enumerate */ -{ - /* - * Range check input... - */ - - if (!ind) - return (NULL); - - /* - * Return the next node... - */ - - if (ind->cur_node < ind->num_nodes) - return (ind->nodes[ind->cur_node ++]); - else - return (NULL); -} - - -/* - * 'mxmlIndexFind()' - Find the next matching node. - * - * You should call mxmlIndexReset() prior to using this function for - * the first time with a particular set of "element" and "value" - * strings. Passing NULL for both "element" and "value" is equivalent - * to calling mxmlIndexEnum(). - */ - -mxml_node_t * /* O - Node or NULL if none found */ -mxmlIndexFind(mxml_index_t *ind, /* I - Index to search */ - const char *element, /* I - Element name to find, if any */ - const char *value) /* I - Attribute value, if any */ -{ - int diff, /* Difference between names */ - current, /* Current entity in search */ - first, /* First entity in search */ - last; /* Last entity in search */ - - -#ifdef DEBUG - printf("mxmlIndexFind(ind=%p, element=\"%s\", value=\"%s\")\n", - ind, element ? element : "(null)", value ? value : "(null)"); -#endif /* DEBUG */ - - /* - * Range check input... - */ - - if (!ind || (!ind->attr && value)) - { -#ifdef DEBUG - puts(" returning NULL..."); - printf(" ind->attr=\"%s\"\n", ind->attr ? ind->attr : "(null)"); -#endif /* DEBUG */ - - return (NULL); - } - - /* - * If both element and value are NULL, just enumerate the nodes in the - * index... - */ - - if (!element && !value) - return (mxmlIndexEnum(ind)); - - /* - * If there are no nodes in the index, return NULL... - */ - - if (!ind->num_nodes) - { -#ifdef DEBUG - puts(" returning NULL..."); - puts(" no nodes!"); -#endif /* DEBUG */ - - return (NULL); - } - - /* - * If cur_node == 0, then find the first matching node... - */ - - if (ind->cur_node == 0) - { - /* - * Find the first node using a modified binary search algorithm... - */ - - first = 0; - last = ind->num_nodes - 1; - -#ifdef DEBUG - printf(" find first time, num_nodes=%d...\n", ind->num_nodes); -#endif /* DEBUG */ - - while ((last - first) > 1) - { - current = (first + last) / 2; - -#ifdef DEBUG - printf(" first=%d, last=%d, current=%d\n", first, last, current); -#endif /* DEBUG */ - - if ((diff = index_find(ind, element, value, ind->nodes[current])) == 0) - { - /* - * Found a match, move back to find the first... - */ - -#ifdef DEBUG - puts(" match!"); -#endif /* DEBUG */ - - while (current > 0 && - !index_find(ind, element, value, ind->nodes[current - 1])) - current --; - -#ifdef DEBUG - printf(" returning first match=%d\n", current); -#endif /* DEBUG */ - - /* - * Return the first match and save the index to the next... - */ - - ind->cur_node = current + 1; - - return (ind->nodes[current]); - } - else if (diff < 0) - last = current; - else - first = current; - -#ifdef DEBUG - printf(" diff=%d\n", diff); -#endif /* DEBUG */ - } - - /* - * If we get this far, then we found exactly 0 or 1 matches... - */ - - for (current = first; current <= last; current ++) - if (!index_find(ind, element, value, ind->nodes[current])) - { - /* - * Found exactly one (or possibly two) match... - */ - -#ifdef DEBUG - printf(" returning only match %d...\n", current); -#endif /* DEBUG */ - - ind->cur_node = current + 1; - - return (ind->nodes[current]); - } - - /* - * No matches... - */ - - ind->cur_node = ind->num_nodes; - -#ifdef DEBUG - puts(" returning NULL..."); -#endif /* DEBUG */ - - return (NULL); - } - else if (ind->cur_node < ind->num_nodes && - !index_find(ind, element, value, ind->nodes[ind->cur_node])) - { - /* - * Return the next matching node... - */ - -#ifdef DEBUG - printf(" returning next match %d...\n", ind->cur_node); -#endif /* DEBUG */ - - return (ind->nodes[ind->cur_node ++]); - } - - /* - * If we get this far, then we have no matches... - */ - - ind->cur_node = ind->num_nodes; - -#ifdef DEBUG - puts(" returning NULL..."); -#endif /* DEBUG */ - - return (NULL); -} - - -/* - * 'mxmlIndexNew()' - Create a new index. - * - * The index will contain all nodes that contain the named element and/or - * attribute. If both "element" and "attr" are NULL, then the index will - * contain a sorted list of the elements in the node tree. Nodes are - * sorted by element name and optionally by attribute value if the "attr" - * argument is not NULL. - */ - -mxml_index_t * /* O - New index */ -mxmlIndexNew(mxml_node_t *node, /* I - XML node tree */ - const char *element, /* I - Element to index or NULL for all */ - const char *attr) /* I - Attribute to index or NULL for none */ -{ - mxml_index_t *ind; /* New index */ - mxml_node_t *current, /* Current node in index */ - **temp; /* Temporary node pointer array */ - - - /* - * Range check input... - */ - -#ifdef DEBUG - printf("mxmlIndexNew(node=%p, element=\"%s\", attr=\"%s\")\n", - node, element ? element : "(null)", attr ? attr : "(null)"); -#endif /* DEBUG */ - - if (!node) - return (NULL); - - /* - * Create a new index... - */ - - if ((ind = calloc(1, sizeof(mxml_index_t))) == NULL) - { - mxml_error("Unable to allocate %d bytes for index - %s", - sizeof(mxml_index_t), strerror(errno)); - return (NULL); - } - - if (attr) - ind->attr = strdup(attr); - - if (!element && !attr) - current = node; - else - current = mxmlFindElement(node, node, element, attr, NULL, MXML_DESCEND); - - while (current) - { - if (ind->num_nodes >= ind->alloc_nodes) - { - if (!ind->alloc_nodes) - temp = malloc(64 * sizeof(mxml_node_t *)); - else - temp = realloc(ind->nodes, (ind->alloc_nodes + 64) * sizeof(mxml_node_t *)); - - if (!temp) - { - /* - * Unable to allocate memory for the index, so abort... - */ - - mxml_error("Unable to allocate %d bytes for index: %s", - (ind->alloc_nodes + 64) * sizeof(mxml_node_t *), - strerror(errno)); - - mxmlIndexDelete(ind); - return (NULL); - } - - ind->nodes = temp; - ind->alloc_nodes += 64; - } - - ind->nodes[ind->num_nodes ++] = current; - - current = mxmlFindElement(current, node, element, attr, NULL, MXML_DESCEND); - } - - /* - * Sort nodes based upon the search criteria... - */ - -#ifdef DEBUG - { - int i; /* Looping var */ - - - printf("%d node(s) in index.\n\n", ind->num_nodes); - - if (attr) - { - printf("Node Address Element %s\n", attr); - puts("-------- -------- -------------- ------------------------------"); - - for (i = 0; i < ind->num_nodes; i ++) - printf("%8d %-8p %-14.14s %s\n", i, ind->nodes[i], - ind->nodes[i]->value.element.name, - mxmlElementGetAttr(ind->nodes[i], attr)); - } - else - { - puts("Node Address Element"); - puts("-------- -------- --------------"); - - for (i = 0; i < ind->num_nodes; i ++) - printf("%8d %-8p %s\n", i, ind->nodes[i], - ind->nodes[i]->value.element.name); - } - - putchar('\n'); - } -#endif /* DEBUG */ - - if (ind->num_nodes > 1) - index_sort(ind, 0, ind->num_nodes - 1); - -#ifdef DEBUG - { - int i; /* Looping var */ - - - puts("After sorting:\n"); - - if (attr) - { - printf("Node Address Element %s\n", attr); - puts("-------- -------- -------------- ------------------------------"); - - for (i = 0; i < ind->num_nodes; i ++) - printf("%8d %-8p %-14.14s %s\n", i, ind->nodes[i], - ind->nodes[i]->value.element.name, - mxmlElementGetAttr(ind->nodes[i], attr)); - } - else - { - puts("Node Address Element"); - puts("-------- -------- --------------"); - - for (i = 0; i < ind->num_nodes; i ++) - printf("%8d %-8p %s\n", i, ind->nodes[i], - ind->nodes[i]->value.element.name); - } - - putchar('\n'); - } -#endif /* DEBUG */ - - /* - * Return the new index... - */ - - return (ind); -} - - -/* - * 'mxmlIndexReset()' - Reset the enumeration/find pointer in the index and - * return the first node in the index. - * - * This function should be called prior to using mxmlIndexEnum() or - * mxmlIndexFind() for the first time. - */ - -mxml_node_t * /* O - First node or NULL if there is none */ -mxmlIndexReset(mxml_index_t *ind) /* I - Index to reset */ -{ -#ifdef DEBUG - printf("mxmlIndexReset(ind=%p)\n", ind); -#endif /* DEBUG */ - - /* - * Range check input... - */ - - if (!ind) - return (NULL); - - /* - * Set the index to the first element... - */ - - ind->cur_node = 0; - - /* - * Return the first node... - */ - - if (ind->num_nodes) - return (ind->nodes[0]); - else - return (NULL); -} - - -/* - * 'index_compare()' - Compare two nodes. - */ - -static int /* O - Result of comparison */ -index_compare(mxml_index_t *ind, /* I - Index */ - mxml_node_t *first, /* I - First node */ - mxml_node_t *second) /* I - Second node */ -{ - int diff; /* Difference */ - - - /* - * Check the element name... - */ - - if ((diff = strcmp(first->value.element.name, - second->value.element.name)) != 0) - return (diff); - - /* - * Check the attribute value... - */ - - if (ind->attr) - { - if ((diff = strcmp(mxmlElementGetAttr(first, ind->attr), - mxmlElementGetAttr(second, ind->attr))) != 0) - return (diff); - } - - /* - * No difference, return 0... - */ - - return (0); -} - - -/* - * 'index_find()' - Compare a node with index values. - */ - -static int /* O - Result of comparison */ -index_find(mxml_index_t *ind, /* I - Index */ - const char *element, /* I - Element name or NULL */ - const char *value, /* I - Attribute value or NULL */ - mxml_node_t *node) /* I - Node */ -{ - int diff; /* Difference */ - - - /* - * Check the element name... - */ - - if (element) - { - if ((diff = strcmp(element, node->value.element.name)) != 0) - return (diff); - } - - /* - * Check the attribute value... - */ - - if (value) - { - if ((diff = strcmp(value, mxmlElementGetAttr(node, ind->attr))) != 0) - return (diff); - } - - /* - * No difference, return 0... - */ - - return (0); -} - - -/* - * 'index_sort()' - Sort the nodes in the index... - * - * This function implements the classic quicksort algorithm... - */ - -static void -index_sort(mxml_index_t *ind, /* I - Index to sort */ - int left, /* I - Left node in partition */ - int right) /* I - Right node in partition */ -{ - mxml_node_t *pivot, /* Pivot node */ - *temp; /* Swap node */ - int templ, /* Temporary left node */ - tempr; /* Temporary right node */ - - - /* - * Loop until we have sorted all the way to the right... - */ - - do - { - /* - * Sort the pivot in the current partition... - */ - - pivot = ind->nodes[left]; - - for (templ = left, tempr = right; templ < tempr;) - { - /* - * Move left while left node <= pivot node... - */ - - while ((templ < right) && - index_compare(ind, ind->nodes[templ], pivot) <= 0) - templ ++; - - /* - * Move right while right node > pivot node... - */ - - while ((tempr > left) && - index_compare(ind, ind->nodes[tempr], pivot) > 0) - tempr --; - - /* - * Swap nodes if needed... - */ - - if (templ < tempr) - { - temp = ind->nodes[templ]; - ind->nodes[templ] = ind->nodes[tempr]; - ind->nodes[tempr] = temp; - } - } - - /* - * When we get here, the right (tempr) node is the new position for the - * pivot node... - */ - - if (index_compare(ind, pivot, ind->nodes[tempr]) > 0) - { - ind->nodes[left] = ind->nodes[tempr]; - ind->nodes[tempr] = pivot; - } - - /* - * Recursively sort the left partition as needed... - */ - - if (left < (tempr - 1)) - index_sort(ind, left, tempr - 1); - } - while (right > (left = tempr + 1)); -} - - -/* - * End of "$Id: mxml-index.c 184 2005-01-29 07:21:44Z mike $". - */ diff --git a/plugins/zynaddsubfx/mxml/mxml-node.c b/plugins/zynaddsubfx/mxml/mxml-node.c deleted file mode 100644 index 56c30db05..000000000 --- a/plugins/zynaddsubfx/mxml/mxml-node.c +++ /dev/null @@ -1,780 +0,0 @@ -/* - * "$Id: mxml-node.c 270 2007-04-23 21:48:03Z mike $" - * - * Node support code for Mini-XML, a small XML-like file parsing library. - * - * Copyright 2003-2007 by Michael Sweet. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2, 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. - * - * Contents: - * - * mxmlAdd() - Add a node to a tree. - * mxmlDelete() - Delete a node and all of its children. - * mxmlNewCDATA() - Create a new CDATA node. - * mxmlNewCustom() - Create a new custom data node. - * mxmlNewElement() - Create a new element node. - * mxmlNewInteger() - Create a new integer node. - * mxmlNewOpaque() - Create a new opaque string. - * mxmlNewReal() - Create a new real number node. - * mxmlNewText() - Create a new text fragment node. - * mxmlNewTextf() - Create a new formatted text fragment node. - * mxmlNewXML() - Create a new XML document tree. - * mxmlRelease() - Release a node. - * mxmlRemove() - Remove a node from its parent. - * mxmlRetain() - Retain a node. - * mxml_new() - Create a new node. - */ - -/* - * Include necessary headers... - */ - -#include "mxml-config.h" -#include "mxml.h" - - -/* - * Local functions... - */ - -static mxml_node_t *mxml_new(mxml_node_t *parent, mxml_type_t type); - - -/* - * 'mxmlAdd()' - Add a node to a tree. - * - * Adds the specified node to the parent. If the child argument is not - * NULL, puts the new node before or after the specified child depending - * on the value of the where argument. If the child argument is NULL, - * puts the new node at the beginning of the child list (MXML_ADD_BEFORE) - * or at the end of the child list (MXML_ADD_AFTER). The constant - * MXML_ADD_TO_PARENT can be used to specify a NULL child pointer. - */ - -void -mxmlAdd(mxml_node_t *parent, /* I - Parent node */ - int where, /* I - Where to add, MXML_ADD_BEFORE or MXML_ADD_AFTER */ - mxml_node_t *child, /* I - Child node for where or MXML_ADD_TO_PARENT */ - mxml_node_t *node) /* I - Node to add */ -{ -#ifdef DEBUG - fprintf(stderr, "mxmlAdd(parent=%p, where=%d, child=%p, node=%p)\n", parent, - where, child, node); -#endif /* DEBUG */ - - /* - * Range check input... - */ - - if (!parent || !node) - return; - -#if DEBUG > 1 - fprintf(stderr, " BEFORE: node->parent=%p\n", node->parent); - if (parent) - { - fprintf(stderr, " BEFORE: parent->child=%p\n", parent->child); - fprintf(stderr, " BEFORE: parent->last_child=%p\n", parent->last_child); - fprintf(stderr, " BEFORE: parent->prev=%p\n", parent->prev); - fprintf(stderr, " BEFORE: parent->next=%p\n", parent->next); - } -#endif /* DEBUG > 1 */ - - /* - * Remove the node from any existing parent... - */ - - if (node->parent) - mxmlRemove(node); - - /* - * Reset pointers... - */ - - node->parent = parent; - - switch (where) - { - case MXML_ADD_BEFORE : - if (!child || child == parent->child || child->parent != parent) - { - /* - * Insert as first node under parent... - */ - - node->next = parent->child; - - if (parent->child) - parent->child->prev = node; - else - parent->last_child = node; - - parent->child = node; - } - else - { - /* - * Insert node before this child... - */ - - node->next = child; - node->prev = child->prev; - - if (child->prev) - child->prev->next = node; - else - parent->child = node; - - child->prev = node; - } - break; - - case MXML_ADD_AFTER : - if (!child || child == parent->last_child || child->parent != parent) - { - /* - * Insert as last node under parent... - */ - - node->parent = parent; - node->prev = parent->last_child; - - if (parent->last_child) - parent->last_child->next = node; - else - parent->child = node; - - parent->last_child = node; - } - else - { - /* - * Insert node after this child... - */ - - node->prev = child; - node->next = child->next; - - if (child->next) - child->next->prev = node; - else - parent->last_child = node; - - child->next = node; - } - break; - } - -#if DEBUG > 1 - fprintf(stderr, " AFTER: node->parent=%p\n", node->parent); - if (parent) - { - fprintf(stderr, " AFTER: parent->child=%p\n", parent->child); - fprintf(stderr, " AFTER: parent->last_child=%p\n", parent->last_child); - fprintf(stderr, " AFTER: parent->prev=%p\n", parent->prev); - fprintf(stderr, " AFTER: parent->next=%p\n", parent->next); - } -#endif /* DEBUG > 1 */ -} - - -/* - * 'mxmlDelete()' - Delete a node and all of its children. - * - * If the specified node has a parent, this function first removes the - * node from its parent using the mxmlRemove() function. - */ - -void -mxmlDelete(mxml_node_t *node) /* I - Node to delete */ -{ - int i; /* Looping var */ - - -#ifdef DEBUG - fprintf(stderr, "mxmlDelete(node=%p)\n", node); -#endif /* DEBUG */ - - /* - * Range check input... - */ - - if (!node) - return; - - /* - * Remove the node from its parent, if any... - */ - - mxmlRemove(node); - - /* - * Delete children... - */ - - while (node->child) - mxmlDelete(node->child); - - /* - * Now delete any node data... - */ - - switch (node->type) - { - case MXML_ELEMENT : - if (node->value.element.name) - free(node->value.element.name); - - if (node->value.element.num_attrs) - { - for (i = 0; i < node->value.element.num_attrs; i ++) - { - if (node->value.element.attrs[i].name) - free(node->value.element.attrs[i].name); - if (node->value.element.attrs[i].value) - free(node->value.element.attrs[i].value); - } - - free(node->value.element.attrs); - } - break; - case MXML_INTEGER : - /* Nothing to do */ - break; - case MXML_OPAQUE : - if (node->value.opaque) - free(node->value.opaque); - break; - case MXML_REAL : - /* Nothing to do */ - break; - case MXML_TEXT : - if (node->value.text.string) - free(node->value.text.string); - break; - case MXML_CUSTOM : - if (node->value.custom.data && - node->value.custom.destroy) - (*(node->value.custom.destroy))(node->value.custom.data); - break; - default : - break; - } - - /* - * Free this node... - */ - - free(node); -} - - -/* - * 'mxmlNewCDATA()' - Create a new CDATA node. - * - * The new CDATA node is added to the end of the specified parent's child - * list. The constant MXML_NO_PARENT can be used to specify that the new - * CDATA node has no parent. The data string must be nul-terminated and - * is copied into the new node. CDATA nodes use the MXML_ELEMENT type. - * - * @since Mini-XML 2.3@ - */ - -mxml_node_t * /* O - New node */ -mxmlNewCDATA(mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */ - const char *data) /* I - Data string */ -{ - mxml_node_t *node; /* New node */ - - -#ifdef DEBUG - fprintf(stderr, "mxmlNewCDATA(parent=%p, data=\"%s\")\n", - parent, data ? data : "(null)"); -#endif /* DEBUG */ - - /* - * Range check input... - */ - - if (!data) - return (NULL); - - /* - * Create the node and set the name value... - */ - - if ((node = mxml_new(parent, MXML_ELEMENT)) != NULL) - node->value.element.name = _mxml_strdupf("![CDATA[%s]]", data); - - return (node); -} - - -/* - * 'mxmlNewCustom()' - Create a new custom data node. - * - * The new custom node is added to the end of the specified parent's child - * list. The constant MXML_NO_PARENT can be used to specify that the new - * element node has no parent. NULL can be passed when the data in the - * node is not dynamically allocated or is separately managed. - * - * @since Mini-XML 2.1@ - */ - -mxml_node_t * /* O - New node */ -mxmlNewCustom( - mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */ - void *data, /* I - Pointer to data */ - mxml_custom_destroy_cb_t destroy) /* I - Function to destroy data */ -{ - mxml_node_t *node; /* New node */ - - -#ifdef DEBUG - fprintf(stderr, "mxmlNewCustom(parent=%p, data=%p, destroy=%p)\n", parent, - data, destroy); -#endif /* DEBUG */ - - /* - * Create the node and set the value... - */ - - if ((node = mxml_new(parent, MXML_CUSTOM)) != NULL) - { - node->value.custom.data = data; - node->value.custom.destroy = destroy; - } - - return (node); -} - - -/* - * 'mxmlNewElement()' - Create a new element node. - * - * The new element node is added to the end of the specified parent's child - * list. The constant MXML_NO_PARENT can be used to specify that the new - * element node has no parent. - */ - -mxml_node_t * /* O - New node */ -mxmlNewElement(mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */ - const char *name) /* I - Name of element */ -{ - mxml_node_t *node; /* New node */ - - -#ifdef DEBUG - fprintf(stderr, "mxmlNewElement(parent=%p, name=\"%s\")\n", parent, - name ? name : "(null)"); -#endif /* DEBUG */ - - /* - * Range check input... - */ - - if (!name) - return (NULL); - - /* - * Create the node and set the element name... - */ - - if ((node = mxml_new(parent, MXML_ELEMENT)) != NULL) - node->value.element.name = strdup(name); - - return (node); -} - - -/* - * 'mxmlNewInteger()' - Create a new integer node. - * - * The new integer node is added to the end of the specified parent's child - * list. The constant MXML_NO_PARENT can be used to specify that the new - * integer node has no parent. - */ - -mxml_node_t * /* O - New node */ -mxmlNewInteger(mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */ - int integer) /* I - Integer value */ -{ - mxml_node_t *node; /* New node */ - - -#ifdef DEBUG - fprintf(stderr, "mxmlNewInteger(parent=%p, integer=%d)\n", parent, integer); -#endif /* DEBUG */ - - /* - * Create the node and set the element name... - */ - - if ((node = mxml_new(parent, MXML_INTEGER)) != NULL) - node->value.integer = integer; - - return (node); -} - - -/* - * 'mxmlNewOpaque()' - Create a new opaque string. - * - * The new opaque node is added to the end of the specified parent's child - * list. The constant MXML_NO_PARENT can be used to specify that the new - * opaque node has no parent. The opaque string must be nul-terminated and - * is copied into the new node. - */ - -mxml_node_t * /* O - New node */ -mxmlNewOpaque(mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */ - const char *opaque) /* I - Opaque string */ -{ - mxml_node_t *node; /* New node */ - - -#ifdef DEBUG - fprintf(stderr, "mxmlNewOpaque(parent=%p, opaque=\"%s\")\n", parent, - opaque ? opaque : "(null)"); -#endif /* DEBUG */ - - /* - * Range check input... - */ - - if (!opaque) - return (NULL); - - /* - * Create the node and set the element name... - */ - - if ((node = mxml_new(parent, MXML_OPAQUE)) != NULL) - node->value.opaque = strdup(opaque); - - return (node); -} - - -/* - * 'mxmlNewReal()' - Create a new real number node. - * - * The new real number node is added to the end of the specified parent's - * child list. The constant MXML_NO_PARENT can be used to specify that - * the new real number node has no parent. - */ - -mxml_node_t * /* O - New node */ -mxmlNewReal(mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */ - double real) /* I - Real number value */ -{ - mxml_node_t *node; /* New node */ - - -#ifdef DEBUG - fprintf(stderr, "mxmlNewReal(parent=%p, real=%g)\n", parent, real); -#endif /* DEBUG */ - - /* - * Create the node and set the element name... - */ - - if ((node = mxml_new(parent, MXML_REAL)) != NULL) - node->value.real = real; - - return (node); -} - - -/* - * 'mxmlNewText()' - Create a new text fragment node. - * - * The new text node is added to the end of the specified parent's child - * list. The constant MXML_NO_PARENT can be used to specify that the new - * text node has no parent. The whitespace parameter is used to specify - * whether leading whitespace is present before the node. The text - * string must be nul-terminated and is copied into the new node. - */ - -mxml_node_t * /* O - New node */ -mxmlNewText(mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */ - int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */ - const char *string) /* I - String */ -{ - mxml_node_t *node; /* New node */ - - -#ifdef DEBUG - fprintf(stderr, "mxmlNewText(parent=%p, whitespace=%d, string=\"%s\")\n", - parent, whitespace, string ? string : "(null)"); -#endif /* DEBUG */ - - /* - * Range check input... - */ - - if (!string) - return (NULL); - - /* - * Create the node and set the text value... - */ - - if ((node = mxml_new(parent, MXML_TEXT)) != NULL) - { - node->value.text.whitespace = whitespace; - node->value.text.string = strdup(string); - } - - return (node); -} - - -/* - * 'mxmlNewTextf()' - Create a new formatted text fragment node. - * - * The new text node is added to the end of the specified parent's child - * list. The constant MXML_NO_PARENT can be used to specify that the new - * text node has no parent. The whitespace parameter is used to specify - * whether leading whitespace is present before the node. The format - * string must be nul-terminated and is formatted into the new node. - */ - -mxml_node_t * /* O - New node */ -mxmlNewTextf(mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */ - int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */ - const char *format, /* I - Printf-style frmat string */ - ...) /* I - Additional args as needed */ -{ - mxml_node_t *node; /* New node */ - va_list ap; /* Pointer to arguments */ - - -#ifdef DEBUG - fprintf(stderr, "mxmlNewTextf(parent=%p, whitespace=%d, format=\"%s\", ...)\n", - parent, whitespace, format ? format : "(null)"); -#endif /* DEBUG */ - - /* - * Range check input... - */ - - if (!format) - return (NULL); - - /* - * Create the node and set the text value... - */ - - if ((node = mxml_new(parent, MXML_TEXT)) != NULL) - { - va_start(ap, format); - - node->value.text.whitespace = whitespace; - node->value.text.string = _mxml_vstrdupf(format, ap); - - va_end(ap); - } - - return (node); -} - - -/* - * 'mxmlRemove()' - Remove a node from its parent. - * - * Does not free memory used by the node - use mxmlDelete() for that. - * This function does nothing if the node has no parent. - */ - -void -mxmlRemove(mxml_node_t *node) /* I - Node to remove */ -{ -#ifdef DEBUG - fprintf(stderr, "mxmlRemove(node=%p)\n", node); -#endif /* DEBUG */ - - /* - * Range check input... - */ - - if (!node || !node->parent) - return; - - /* - * Remove from parent... - */ - -#if DEBUG > 1 - fprintf(stderr, " BEFORE: node->parent=%p\n", node->parent); - if (node->parent) - { - fprintf(stderr, " BEFORE: node->parent->child=%p\n", node->parent->child); - fprintf(stderr, " BEFORE: node->parent->last_child=%p\n", node->parent->last_child); - } - fprintf(stderr, " BEFORE: node->child=%p\n", node->child); - fprintf(stderr, " BEFORE: node->last_child=%p\n", node->last_child); - fprintf(stderr, " BEFORE: node->prev=%p\n", node->prev); - fprintf(stderr, " BEFORE: node->next=%p\n", node->next); -#endif /* DEBUG > 1 */ - - if (node->prev) - node->prev->next = node->next; - else - node->parent->child = node->next; - - if (node->next) - node->next->prev = node->prev; - else - node->parent->last_child = node->prev; - - node->parent = NULL; - node->prev = NULL; - node->next = NULL; - -#if DEBUG > 1 - fprintf(stderr, " AFTER: node->parent=%p\n", node->parent); - if (node->parent) - { - fprintf(stderr, " AFTER: node->parent->child=%p\n", node->parent->child); - fprintf(stderr, " AFTER: node->parent->last_child=%p\n", node->parent->last_child); - } - fprintf(stderr, " AFTER: node->child=%p\n", node->child); - fprintf(stderr, " AFTER: node->last_child=%p\n", node->last_child); - fprintf(stderr, " AFTER: node->prev=%p\n", node->prev); - fprintf(stderr, " AFTER: node->next=%p\n", node->next); -#endif /* DEBUG > 1 */ -} - - -/* - * 'mxmlNewXML()' - Create a new XML document tree. - * - * The "version" argument specifies the version number to put in the - * ?xml element node. If NULL, version 1.0 is assumed. - * - * @since Mini-XML 2.3@ - */ - -mxml_node_t * /* O - New ?xml node */ -mxmlNewXML(const char *version) /* I - Version number to use */ -{ - char element[1024]; /* Element text */ - - - snprintf(element, sizeof(element), "?xml version=\"%s\"?", - version ? version : "1.0"); - - return (mxmlNewElement(NULL, element)); -} - - -/* - * 'mxmlRelease()' - Release a node. - * - * When the reference count reaches zero, the node (and any children) - * is deleted via mxmlDelete(). - * - * @since Mini-XML 2.3@ - */ - -int /* O - New reference count */ -mxmlRelease(mxml_node_t *node) /* I - Node */ -{ - if (node) - { - if ((-- node->ref_count) <= 0) - { - mxmlDelete(node); - return (0); - } - else - return (node->ref_count); - } - else - return (-1); -} - - -/* - * 'mxmlRetain()' - Retain a node. - * - * @since Mini-XML 2.3@ - */ - -int /* O - New reference count */ -mxmlRetain(mxml_node_t *node) /* I - Node */ -{ - if (node) - return (++ node->ref_count); - else - return (-1); -} - - -/* - * 'mxml_new()' - Create a new node. - */ - -static mxml_node_t * /* O - New node */ -mxml_new(mxml_node_t *parent, /* I - Parent node */ - mxml_type_t type) /* I - Node type */ -{ - mxml_node_t *node; /* New node */ - - -#if DEBUG > 1 - fprintf(stderr, "mxml_new(parent=%p, type=%d)\n", parent, type); -#endif /* DEBUG > 1 */ - - /* - * Allocate memory for the node... - */ - - if ((node = calloc(1, sizeof(mxml_node_t))) == NULL) - { -#if DEBUG > 1 - fputs(" returning NULL\n", stderr); -#endif /* DEBUG > 1 */ - - return (NULL); - } - -#if DEBUG > 1 - fprintf(stderr, " returning %p\n", node); -#endif /* DEBUG > 1 */ - - /* - * Set the node type... - */ - - node->type = type; - node->ref_count = 1; - - /* - * Add to the parent if present... - */ - - if (parent) - mxmlAdd(parent, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, node); - - /* - * Return the new node... - */ - - return (node); -} - - -/* - * End of "$Id: mxml-node.c 270 2007-04-23 21:48:03Z mike $". - */ diff --git a/plugins/zynaddsubfx/mxml/mxml-private.c b/plugins/zynaddsubfx/mxml/mxml-private.c deleted file mode 100644 index fa5258056..000000000 --- a/plugins/zynaddsubfx/mxml/mxml-private.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * "$Id: mxml-private.c 315 2007-11-22 18:01:52Z mike $" - * - * Private functions for Mini-XML, a small XML-like file parsing library. - * - * Copyright 2003-2007 by Michael Sweet. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2, 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. - * - * Contents: - * - * mxml_error() - Display an error message. - * mxml_integer_cb() - Default callback for integer values. - * mxml_opaque_cb() - Default callback for opaque values. - * mxml_real_cb() - Default callback for real number values. - * _mxml_global() - Get global data. - */ - -/* - * Include necessary headers... - */ - -#include "mxml-private.h" - - -/* - * 'mxml_error()' - Display an error message. - */ - -void -mxml_error(const char *format, /* I - Printf-style format string */ - ...) /* I - Additional arguments as needed */ -{ - va_list ap; /* Pointer to arguments */ - char s[1024]; /* Message string */ - _mxml_global_t *global = _mxml_global(); - /* Global data */ - - - /* - * Range check input... - */ - - if (!format) - return; - - /* - * Format the error message string... - */ - - va_start(ap, format); - - vsnprintf(s, sizeof(s), format, ap); - - va_end(ap); - - /* - * And then display the error message... - */ - - if (global->error_cb) - (*global->error_cb)(s); - else - fprintf(stderr, "mxml: %s\n", s); -} - - -/* - * 'mxml_ignore_cb()' - Default callback for ignored values. - */ - -mxml_type_t /* O - Node type */ -mxml_ignore_cb(mxml_node_t *node) /* I - Current node */ -{ - (void)node; - - return (MXML_IGNORE); -} - - -/* - * 'mxml_integer_cb()' - Default callback for integer values. - */ - -mxml_type_t /* O - Node type */ -mxml_integer_cb(mxml_node_t *node) /* I - Current node */ -{ - (void)node; - - return (MXML_INTEGER); -} - - -/* - * 'mxml_opaque_cb()' - Default callback for opaque values. - */ - -mxml_type_t /* O - Node type */ -mxml_opaque_cb(mxml_node_t *node) /* I - Current node */ -{ - (void)node; - - return (MXML_OPAQUE); -} - - -/* - * 'mxml_real_cb()' - Default callback for real number values. - */ - -mxml_type_t /* O - Node type */ -mxml_real_cb(mxml_node_t *node) /* I - Current node */ -{ - (void)node; - - return (MXML_REAL); -} - - -#ifdef HAVE_PTHREAD_H /**** POSIX threading ****/ -# include - -static pthread_key_t _mxml_key = -1; /* Thread local storage key */ -static pthread_once_t _mxml_key_once = PTHREAD_ONCE_INIT; - /* One-time initialization object */ -static void _mxml_init(void); -static void _mxml_destructor(void *g); - - -/* - * '_mxml_global()' - Get global data. - */ - -_mxml_global_t * /* O - Global data */ -_mxml_global(void) -{ - _mxml_global_t *global; /* Global data */ - - - pthread_once(&_mxml_key_once, _mxml_init); - - if ((global = (_mxml_global_t *)pthread_getspecific(_mxml_key)) == NULL) - { - global = (_mxml_global_t *)calloc(1, sizeof(_mxml_global_t)); - pthread_setspecific(_mxml_key, global); - - global->num_entity_cbs = 1; - global->entity_cbs[0] = _mxml_entity_cb; - global->wrap = 72; - } - - return (global); -} - - -/* - * '_mxml_init()' - Initialize global data... - */ - -static void -_mxml_init(void) -{ - pthread_key_create(&_mxml_key, _mxml_destructor); -} - - -/* - * '_mxml_destructor()' - Free memory used for globals... - */ - -static void -_mxml_destructor(void *g) /* I - Global data */ -{ - free(g); -} - - -#elif defined(WIN32) /**** WIN32 threading ****/ -# include - -static DWORD _mxml_tls_index; /* Index for global storage */ - - -/* - * 'DllMain()' - Main entry for library. - */ - -BOOL WINAPI /* O - Success/failure */ -DllMain(HINSTANCE hinst, /* I - DLL module handle */ - DWORD reason, /* I - Reason */ - LPVOID reserved) /* I - Unused */ -{ - _mxml_global_t *global; /* Global data */ - - - (void)hinst; - (void)reserved; - - switch (reason) - { - case DLL_PROCESS_ATTACH : /* Called on library initialization */ - if ((_mxml_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) - return (FALSE); - break; - - case DLL_THREAD_DETACH : /* Called when a thread terminates */ - if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) != NULL) - free(global); - break; - - case DLL_PROCESS_DETACH : /* Called when library is unloaded */ - if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) != NULL) - free(global); - - TlsFree(_mxml_tls_index); - break; - - default: - break; - } - - return (TRUE); -} - - -/* - * '_mxml_global()' - Get global data. - */ - -_mxml_global_t * /* O - Global data */ -_mxml_global(void) -{ - _mxml_global_t *global; /* Global data */ - - - if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) == NULL) - { - global = (_mxml_global_t *)calloc(1, sizeof(_mxml_global_t)); - - global->num_entity_cbs = 1; - global->entity_cbs[0] = _mxml_entity_cb; - global->wrap = 72; - - TlsSetValue(_mxml_tls_index, (LPVOID)global); - } - - return (global); -} - - -#else /**** No threading ****/ -/* - * '_mxml_global()' - Get global data. - */ - -_mxml_global_t * /* O - Global data */ -_mxml_global(void) -{ - static _mxml_global_t global = /* Global data */ - { - NULL, /* error_cb */ - 1, /* num_entity_cbs */ - { _mxml_entity_cb }, /* entity_cbs */ - 72, /* wrap */ - NULL, /* custom_load_cb */ - NULL /* custom_save_cb */ - }; - - - return (&global); -} -#endif /* HAVE_PTHREAD_H */ - - -/* - * End of "$Id: mxml-private.c 315 2007-11-22 18:01:52Z mike $". - */ diff --git a/plugins/zynaddsubfx/mxml/mxml-private.h b/plugins/zynaddsubfx/mxml/mxml-private.h deleted file mode 100644 index 82deb67cd..000000000 --- a/plugins/zynaddsubfx/mxml/mxml-private.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * "$Id: mxml-private.h 309 2007-09-21 04:46:02Z mike $" - * - * Private definitions for Mini-XML, a small XML-like file parsing library. - * - * Copyright 2007 by Michael Sweet. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2, 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. - */ - -/* - * Include necessary headers... - */ - -#include "mxml-config.h" -#include "mxml.h" - - -/* - * Global, per-thread data... - */ - -typedef struct _mxml_global_s -{ - void (*error_cb)(const char *); - int num_entity_cbs; - int (*entity_cbs[100])(const char *name); - int wrap; - mxml_custom_load_cb_t custom_load_cb; - mxml_custom_save_cb_t custom_save_cb; -} _mxml_global_t; - - -/* - * Functions... - */ - -extern _mxml_global_t *_mxml_global(void); -extern int _mxml_entity_cb(const char *name); - - -/* - * End of "$Id: mxml-private.h 309 2007-09-21 04:46:02Z mike $". - */ diff --git a/plugins/zynaddsubfx/mxml/mxml-search.c b/plugins/zynaddsubfx/mxml/mxml-search.c deleted file mode 100644 index 72b24484e..000000000 --- a/plugins/zynaddsubfx/mxml/mxml-search.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * "$Id: mxml-search.c 297 2007-09-09 07:16:52Z mike $" - * - * Search/navigation functions for Mini-XML, a small XML-like file - * parsing library. - * - * Copyright 2003-2007 by Michael Sweet. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2, 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. - * - * Contents: - * - * mxmlFindElement() - Find the named element. - * mxmlWalkNext() - Walk to the next logical node in the tree. - * mxmlWalkPrev() - Walk to the previous logical node in the tree. - */ - -/* - * Include necessary headers... - */ - -#include "mxml-config.h" -#include "mxml.h" - - -/* - * 'mxmlFindElement()' - Find the named element. - * - * The search is constrained by the name, attribute name, and value; any - * NULL names or values are treated as wildcards, so different kinds of - * searches can be implemented by looking for all elements of a given name - * or all elements with a specific attribute. The descend argument determines - * whether the search descends into child nodes; normally you will use - * MXML_DESCEND_FIRST for the initial search and MXML_NO_DESCEND to find - * additional direct descendents of the node. The top node argument - * constrains the search to a particular node's children. - */ - -mxml_node_t * /* O - Element node or NULL */ -mxmlFindElement(mxml_node_t *node, /* I - Current node */ - mxml_node_t *top, /* I - Top node */ - const char *name, /* I - Element name or NULL for any */ - const char *attr, /* I - Attribute name, or NULL for none */ - const char *value, /* I - Attribute value, or NULL for any */ - int descend) /* I - Descend into tree - MXML_DESCEND, MXML_NO_DESCEND, or MXML_DESCEND_FIRST */ -{ - const char *temp; /* Current attribute value */ - - - /* - * Range check input... - */ - - if (!node || !top || (!attr && value)) - return (NULL); - - /* - * Start with the next node... - */ - - node = mxmlWalkNext(node, top, descend); - - /* - * Loop until we find a matching element... - */ - - while (node != NULL) - { - /* - * See if this node matches... - */ - - if (node->type == MXML_ELEMENT && - node->value.element.name && - (!name || !strcmp(node->value.element.name, name))) - { - /* - * See if we need to check for an attribute... - */ - - if (!attr) - return (node); /* No attribute search, return it... */ - - /* - * Check for the attribute... - */ - - if ((temp = mxmlElementGetAttr(node, attr)) != NULL) - { - /* - * OK, we have the attribute, does it match? - */ - - if (!value || !strcmp(value, temp)) - return (node); /* Yes, return it... */ - } - } - - /* - * No match, move on to the next node... - */ - - if (descend == MXML_DESCEND) - node = mxmlWalkNext(node, top, MXML_DESCEND); - else - node = node->next; - } - - return (NULL); -} - - -/* - * 'mxmlWalkNext()' - Walk to the next logical node in the tree. - * - * The descend argument controls whether the first child is considered - * to be the next node. The top node argument constrains the walk to - * the node's children. - */ - -mxml_node_t * /* O - Next node or NULL */ -mxmlWalkNext(mxml_node_t *node, /* I - Current node */ - mxml_node_t *top, /* I - Top node */ - int descend) /* I - Descend into tree - MXML_DESCEND, MXML_NO_DESCEND, or MXML_DESCEND_FIRST */ -{ - if (!node) - return (NULL); - else if (node->child && descend) - return (node->child); - else if (node == top) - return (NULL); - else if (node->next) - return (node->next); - else if (node->parent && node->parent != top) - { - node = node->parent; - - while (!node->next) - if (node->parent == top || !node->parent) - return (NULL); - else - node = node->parent; - - return (node->next); - } - else - return (NULL); -} - - -/* - * 'mxmlWalkPrev()' - Walk to the previous logical node in the tree. - * - * The descend argument controls whether the previous node's last child - * is considered to be the previous node. The top node argument constrains - * the walk to the node's children. - */ - -mxml_node_t * /* O - Previous node or NULL */ -mxmlWalkPrev(mxml_node_t *node, /* I - Current node */ - mxml_node_t *top, /* I - Top node */ - int descend) /* I - Descend into tree - MXML_DESCEND, MXML_NO_DESCEND, or MXML_DESCEND_FIRST */ -{ - if (!node || node == top) - return (NULL); - else if (node->prev) - { - if (node->prev->last_child && descend) - { - /* - * Find the last child under the previous node... - */ - - node = node->prev->last_child; - - while (node->last_child) - node = node->last_child; - - return (node); - } - else - return (node->prev); - } - else if (node->parent != top) - return (node->parent); - else - return (NULL); -} - - -/* - * End of "$Id: mxml-search.c 297 2007-09-09 07:16:52Z mike $". - */ diff --git a/plugins/zynaddsubfx/mxml/mxml-set.c b/plugins/zynaddsubfx/mxml/mxml-set.c deleted file mode 100644 index 788004bf4..000000000 --- a/plugins/zynaddsubfx/mxml/mxml-set.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * "$Id: mxml-set.c 270 2007-04-23 21:48:03Z mike $" - * - * Node set functions for Mini-XML, a small XML-like file parsing library. - * - * Copyright 2003-2007 by Michael Sweet. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2, 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. - * - * Contents: - * - * mxmlSetCustom() - Set the data and destructor of a custom data node. - * mxmlSetCDATA() - Set the element name of a CDATA node. - * mxmlSetElement() - Set the name of an element node. - * mxmlSetInteger() - Set the value of an integer node. - * mxmlSetOpaque() - Set the value of an opaque node. - * mxmlSetReal() - Set the value of a real number node. - * mxmlSetText() - Set the value of a text node. - * mxmlSetTextf() - Set the value of a text node to a formatted string. - */ - -/* - * Include necessary headers... - */ - -#include "mxml-config.h" -#include "mxml.h" - - -/* - * 'mxmlSetCustom()' - Set the data and destructor of a custom data node. - * - * The node is not changed if it is not a custom node. - * - * @since Mini-XML 2.1@ - */ - -int /* O - 0 on success, -1 on failure */ -mxmlSetCustom( - mxml_node_t *node, /* I - Node to set */ - void *data, /* I - New data pointer */ - mxml_custom_destroy_cb_t destroy) /* I - New destructor function */ -{ - /* - * Range check input... - */ - - if (!node || node->type != MXML_CUSTOM) - return (-1); - - /* - * Free any old element value and set the new value... - */ - - if (node->value.custom.data && node->value.custom.destroy) - (*(node->value.custom.destroy))(node->value.custom.data); - - node->value.custom.data = data; - node->value.custom.destroy = destroy; - - return (0); -} - - -/* - * 'mxmlSetCDATA()' - Set the element name of a CDATA node. - * - * The node is not changed if it is not a CDATA element node. - * - * @since Mini-XML 2.3@ - */ - -int /* O - 0 on success, -1 on failure */ -mxmlSetCDATA(mxml_node_t *node, /* I - Node to set */ - const char *data) /* I - New data string */ -{ - /* - * Range check input... - */ - - if (!node || node->type != MXML_ELEMENT || !data || - strncmp(node->value.element.name, "![CDATA[", 8)) - return (-1); - - /* - * Free any old element value and set the new value... - */ - - if (node->value.element.name) - free(node->value.element.name); - - node->value.element.name = _mxml_strdupf("![CDATA[%s]]", data); - - return (0); -} - - -/* - * 'mxmlSetElement()' - Set the name of an element node. - * - * The node is not changed if it is not an element node. - */ - -int /* O - 0 on success, -1 on failure */ -mxmlSetElement(mxml_node_t *node, /* I - Node to set */ - const char *name) /* I - New name string */ -{ - /* - * Range check input... - */ - - if (!node || node->type != MXML_ELEMENT || !name) - return (-1); - - /* - * Free any old element value and set the new value... - */ - - if (node->value.element.name) - free(node->value.element.name); - - node->value.element.name = strdup(name); - - return (0); -} - - -/* - * 'mxmlSetInteger()' - Set the value of an integer node. - * - * The node is not changed if it is not an integer node. - */ - -int /* O - 0 on success, -1 on failure */ -mxmlSetInteger(mxml_node_t *node, /* I - Node to set */ - int integer) /* I - Integer value */ -{ - /* - * Range check input... - */ - - if (!node || node->type != MXML_INTEGER) - return (-1); - - /* - * Set the new value and return... - */ - - node->value.integer = integer; - - return (0); -} - - -/* - * 'mxmlSetOpaque()' - Set the value of an opaque node. - * - * The node is not changed if it is not an opaque node. - */ - -int /* O - 0 on success, -1 on failure */ -mxmlSetOpaque(mxml_node_t *node, /* I - Node to set */ - const char *opaque) /* I - Opaque string */ -{ - /* - * Range check input... - */ - - if (!node || node->type != MXML_OPAQUE || !opaque) - return (-1); - - /* - * Free any old opaque value and set the new value... - */ - - if (node->value.opaque) - free(node->value.opaque); - - node->value.opaque = strdup(opaque); - - return (0); -} - - -/* - * 'mxmlSetReal()' - Set the value of a real number node. - * - * The node is not changed if it is not a real number node. - */ - -int /* O - 0 on success, -1 on failure */ -mxmlSetReal(mxml_node_t *node, /* I - Node to set */ - double real) /* I - Real number value */ -{ - /* - * Range check input... - */ - - if (!node || node->type != MXML_REAL) - return (-1); - - /* - * Set the new value and return... - */ - - node->value.real = real; - - return (0); -} - - -/* - * 'mxmlSetText()' - Set the value of a text node. - * - * The node is not changed if it is not a text node. - */ - -int /* O - 0 on success, -1 on failure */ -mxmlSetText(mxml_node_t *node, /* I - Node to set */ - int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */ - const char *string) /* I - String */ -{ - /* - * Range check input... - */ - - if (!node || node->type != MXML_TEXT || !string) - return (-1); - - /* - * Free any old string value and set the new value... - */ - - if (node->value.text.string) - free(node->value.text.string); - - node->value.text.whitespace = whitespace; - node->value.text.string = strdup(string); - - return (0); -} - - -/* - * 'mxmlSetTextf()' - Set the value of a text node to a formatted string. - * - * The node is not changed if it is not a text node. - */ - -int /* O - 0 on success, -1 on failure */ -mxmlSetTextf(mxml_node_t *node, /* I - Node to set */ - int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */ - const char *format, /* I - Printf-style format string */ - ...) /* I - Additional arguments as needed */ -{ - va_list ap; /* Pointer to arguments */ - - - /* - * Range check input... - */ - - if (!node || node->type != MXML_TEXT || !format) - return (-1); - - /* - * Free any old string value and set the new value... - */ - - if (node->value.text.string) - free(node->value.text.string); - - va_start(ap, format); - - node->value.text.whitespace = whitespace; - node->value.text.string = _mxml_strdupf(format, ap); - - va_end(ap); - - return (0); -} - - -/* - * End of "$Id: mxml-set.c 270 2007-04-23 21:48:03Z mike $". - */ diff --git a/plugins/zynaddsubfx/mxml/mxml-string.c b/plugins/zynaddsubfx/mxml/mxml-string.c deleted file mode 100644 index 7cb30e399..000000000 --- a/plugins/zynaddsubfx/mxml/mxml-string.c +++ /dev/null @@ -1,457 +0,0 @@ -/* - * "$Id: mxml-string.c 312 2007-10-03 06:25:07Z mike $" - * - * String functions for Mini-XML, a small XML-like file parsing library. - * - * Copyright 2003-2007 by Michael Sweet. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2, 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. - * - * Contents: - * - * _mxml_snprintf() - Format a string. - * _mxml_strdup() - Duplicate a string. - * _mxml_strdupf() - Format and duplicate a string. - * _mxml_vsnprintf() - Format a string into a fixed size buffer. - * _mxml_vstrdupf() - Format and duplicate a string. - */ - -/* - * Include necessary headers... - */ - -#include "mxml-config.h" - - -#ifndef HAVE_SNPRINTF -/* - * '_mxml_snprintf()' - Format a string. - */ - -int /* O - Number of bytes formatted */ -_mxml_snprintf(char *buffer, /* I - Output buffer */ - size_t bufsize, /* I - Size of output buffer */ - const char *format, /* I - Printf-style format string */ - ...) /* I - Additional arguments as needed */ -{ - va_list ap; /* Argument list */ - int bytes; /* Number of bytes formatted */ - - - va_start(ap, format); - bytes = vsnprintf(buffer, bufsize, format, ap); - va_end(ap); - - return (bytes); -} -#endif /* !HAVE_SNPRINTF */ - - -/* - * '_mxml_strdup()' - Duplicate a string. - */ - -#ifndef HAVE_STRDUP -char * /* O - New string pointer */ -_mxml_strdup(const char *s) /* I - String to duplicate */ -{ - char *t; /* New string pointer */ - - - if (s == NULL) - return (NULL); - - if ((t = malloc(strlen(s) + 1)) == NULL) - return (NULL); - - return (strcpy(t, s)); -} -#endif /* !HAVE_STRDUP */ - - -/* - * '_mxml_strdupf()' - Format and duplicate a string. - */ - -char * /* O - New string pointer */ -_mxml_strdupf(const char *format, /* I - Printf-style format string */ - ...) /* I - Additional arguments as needed */ -{ - va_list ap; /* Pointer to additional arguments */ - char *s; /* Pointer to formatted string */ - - - /* - * Get a pointer to the additional arguments, format the string, - * and return it... - */ - - va_start(ap, format); - s = _mxml_vstrdupf(format, ap); - va_end(ap); - - return (s); -} - - -#ifndef HAVE_VSNPRINTF -/* - * '_mxml_vsnprintf()' - Format a string into a fixed size buffer. - */ - -int /* O - Number of bytes formatted */ -_mxml_vsnprintf(char *buffer, /* O - Output buffer */ - size_t bufsize, /* O - Size of output buffer */ - const char *format, /* I - Printf-style format string */ - va_list ap) /* I - Pointer to additional arguments */ -{ - char *bufptr, /* Pointer to position in buffer */ - *bufend, /* Pointer to end of buffer */ - sign, /* Sign of format width */ - size, /* Size character (h, l, L) */ - type; /* Format type character */ - int width, /* Width of field */ - prec; /* Number of characters of precision */ - char tformat[100], /* Temporary format string for sprintf() */ - *tptr, /* Pointer into temporary format */ - temp[1024]; /* Buffer for formatted numbers */ - char *s; /* Pointer to string */ - int slen; /* Length of string */ - int bytes; /* Total number of bytes needed */ - - - /* - * Loop through the format string, formatting as needed... - */ - - bufptr = buffer; - bufend = buffer + bufsize - 1; - bytes = 0; - - while (*format) - { - if (*format == '%') - { - tptr = tformat; - *tptr++ = *format++; - - if (*format == '%') - { - if (bufptr && bufptr < bufend) *bufptr++ = *format; - bytes ++; - format ++; - continue; - } - else if (strchr(" -+#\'", *format)) - { - *tptr++ = *format; - sign = *format++; - } - else - sign = 0; - - if (*format == '*') - { - /* - * Get width from argument... - */ - - format ++; - width = va_arg(ap, int); - - snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", width); - tptr += strlen(tptr); - } - else - { - width = 0; - - while (isdigit(*format & 255)) - { - if (tptr < (tformat + sizeof(tformat) - 1)) - *tptr++ = *format; - - width = width * 10 + *format++ - '0'; - } - } - - if (*format == '.') - { - if (tptr < (tformat + sizeof(tformat) - 1)) - *tptr++ = *format; - - format ++; - - if (*format == '*') - { - /* - * Get precision from argument... - */ - - format ++; - prec = va_arg(ap, int); - - snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", prec); - tptr += strlen(tptr); - } - else - { - prec = 0; - - while (isdigit(*format & 255)) - { - if (tptr < (tformat + sizeof(tformat) - 1)) - *tptr++ = *format; - - prec = prec * 10 + *format++ - '0'; - } - } - } - else - prec = -1; - - if (*format == 'l' && format[1] == 'l') - { - size = 'L'; - - if (tptr < (tformat + sizeof(tformat) - 2)) - { - *tptr++ = 'l'; - *tptr++ = 'l'; - } - - format += 2; - } - else if (*format == 'h' || *format == 'l' || *format == 'L') - { - if (tptr < (tformat + sizeof(tformat) - 1)) - *tptr++ = *format; - - size = *format++; - } - - if (!*format) - break; - - if (tptr < (tformat + sizeof(tformat) - 1)) - *tptr++ = *format; - - type = *format++; - *tptr = '\0'; - - switch (type) - { - case 'E' : /* Floating point formats */ - case 'G' : - case 'e' : - case 'f' : - case 'g' : - if ((width + 2) > sizeof(temp)) - break; - - sprintf(temp, tformat, va_arg(ap, double)); - - bytes += strlen(temp); - - if (bufptr) - { - if ((bufptr + strlen(temp)) > bufend) - { - strncpy(bufptr, temp, (size_t)(bufend - bufptr)); - bufptr = bufend; - } - else - { - strcpy(bufptr, temp); - bufptr += strlen(temp); - } - } - break; - - case 'B' : /* Integer formats */ - case 'X' : - case 'b' : - case 'd' : - case 'i' : - case 'o' : - case 'u' : - case 'x' : - if ((width + 2) > sizeof(temp)) - break; - - sprintf(temp, tformat, va_arg(ap, int)); - - bytes += strlen(temp); - - if (bufptr) - { - if ((bufptr + strlen(temp)) > bufend) - { - strncpy(bufptr, temp, (size_t)(bufend - bufptr)); - bufptr = bufend; - } - else - { - strcpy(bufptr, temp); - bufptr += strlen(temp); - } - } - break; - - case 'p' : /* Pointer value */ - if ((width + 2) > sizeof(temp)) - break; - - sprintf(temp, tformat, va_arg(ap, void *)); - - bytes += strlen(temp); - - if (bufptr) - { - if ((bufptr + strlen(temp)) > bufend) - { - strncpy(bufptr, temp, (size_t)(bufend - bufptr)); - bufptr = bufend; - } - else - { - strcpy(bufptr, temp); - bufptr += strlen(temp); - } - } - break; - - case 'c' : /* Character or character array */ - bytes += width; - - if (bufptr) - { - if (width <= 1) - *bufptr++ = va_arg(ap, int); - else - { - if ((bufptr + width) > bufend) - width = bufend - bufptr; - - memcpy(bufptr, va_arg(ap, char *), (size_t)width); - bufptr += width; - } - } - break; - - case 's' : /* String */ - if ((s = va_arg(ap, char *)) == NULL) - s = "(null)"; - - slen = strlen(s); - if (slen > width && prec != width) - width = slen; - - bytes += width; - - if (bufptr) - { - if ((bufptr + width) > bufend) - width = bufend - bufptr; - - if (slen > width) - slen = width; - - if (sign == '-') - { - strncpy(bufptr, s, (size_t)slen); - memset(bufptr + slen, ' ', (size_t)(width - slen)); - } - else - { - memset(bufptr, ' ', (size_t)(width - slen)); - strncpy(bufptr + width - slen, s, (size_t)slen); - } - - bufptr += width; - } - break; - - case 'n' : /* Output number of chars so far */ - *(va_arg(ap, int *)) = bytes; - break; - } - } - else - { - bytes ++; - - if (bufptr && bufptr < bufend) - *bufptr++ = *format; - - format ++; - } - } - - /* - * Nul-terminate the string and return the number of characters needed. - */ - - *bufptr = '\0'; - - return (bytes); -} -#endif /* !HAVE_VSNPRINTF */ - - -/* - * '_mxml_vstrdupf()' - Format and duplicate a string. - */ - -char * /* O - New string pointer */ -_mxml_vstrdupf(const char *format, /* I - Printf-style format string */ - va_list ap) /* I - Pointer to additional arguments */ -{ - int bytes; /* Number of bytes required */ - char *buffer, /* String buffer */ - temp[256]; /* Small buffer for first vsnprintf */ - - - /* - * First format with a tiny buffer; this will tell us how many bytes are - * needed... - */ - - bytes = vsnprintf(temp, sizeof(temp), format, ap); - - if (bytes < sizeof(temp)) - { - /* - * Hey, the formatted string fits in the tiny buffer, so just dup that... - */ - - return (strdup(temp)); - } - - /* - * Allocate memory for the whole thing and reformat to the new, larger - * buffer... - */ - - if ((buffer = calloc(1, bytes + 1)) != NULL) - vsnprintf(buffer, bytes + 1, format, ap); - - /* - * Return the new string... - */ - - return (buffer); -} - - -/* - * End of "$Id: mxml-string.c 312 2007-10-03 06:25:07Z mike $". - */ diff --git a/plugins/zynaddsubfx/mxml/mxml.h b/plugins/zynaddsubfx/mxml/mxml.h deleted file mode 100644 index 0b7d7d245..000000000 --- a/plugins/zynaddsubfx/mxml/mxml.h +++ /dev/null @@ -1,305 +0,0 @@ -/* - * "$Id: mxml.h 307 2007-09-15 20:03:15Z mike $" - * - * Header file for Mini-XML, a small XML-like file parsing library. - * - * Copyright 2003-2007 by Michael Sweet. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2, 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. - */ - -/* - * Prevent multiple inclusion... - */ - -#ifndef _mxml_h_ -# define _mxml_h_ - -/* - * Include necessary headers... - */ - -# include -# include -# include -# include -# include - - -/* - * Constants... - */ - -# define MXML_TAB 8 /* Tabs every N columns */ - -# define MXML_NO_CALLBACK 0 /* Don't use a type callback */ -# define MXML_INTEGER_CALLBACK mxml_integer_cb - /* Treat all data as integers */ -# define MXML_OPAQUE_CALLBACK mxml_opaque_cb - /* Treat all data as opaque */ -# define MXML_REAL_CALLBACK mxml_real_cb - /* Treat all data as real numbers */ -# define MXML_TEXT_CALLBACK 0 /* Treat all data as text */ -# define MXML_IGNORE_CALLBACK mxml_ignore_cb - /* Ignore all non-element content */ - -# define MXML_NO_PARENT 0 /* No parent for the node */ - -# define MXML_DESCEND 1 /* Descend when finding/walking */ -# define MXML_NO_DESCEND 0 /* Don't descend when finding/walking */ -# define MXML_DESCEND_FIRST -1 /* Descend for first find */ - -# define MXML_WS_BEFORE_OPEN 0 /* Callback for before open tag */ -# define MXML_WS_AFTER_OPEN 1 /* Callback for after open tag */ -# define MXML_WS_BEFORE_CLOSE 2 /* Callback for before close tag */ -# define MXML_WS_AFTER_CLOSE 3 /* Callback for after close tag */ - -# define MXML_ADD_BEFORE 0 /* Add node before specified node */ -# define MXML_ADD_AFTER 1 /* Add node after specified node */ -# define MXML_ADD_TO_PARENT NULL /* Add node relative to parent */ - - -/* - * Data types... - */ - -typedef enum mxml_sax_event_e /**** SAX event type. ****/ -{ - MXML_SAX_CDATA, /* CDATA node */ - MXML_SAX_COMMENT, /* Comment node */ - MXML_SAX_DATA, /* Data node */ - MXML_SAX_DIRECTIVE, /* Processing directive node */ - MXML_SAX_ELEMENT_CLOSE, /* Element closed */ - MXML_SAX_ELEMENT_OPEN /* Element opened */ -} mxml_sax_event_t; - -typedef enum mxml_type_e /**** The XML node type. ****/ -{ - MXML_IGNORE = -1, /* Ignore/throw away node @since Mini-XML 2.3@ */ - MXML_ELEMENT, /* XML element with attributes */ - MXML_INTEGER, /* Integer value */ - MXML_OPAQUE, /* Opaque string */ - MXML_REAL, /* Real value */ - MXML_TEXT, /* Text fragment */ - MXML_CUSTOM /* Custom data @since Mini-XML 2.1@ */ -} mxml_type_t; - -typedef void (*mxml_custom_destroy_cb_t)(void *); - /**** Custom data destructor ****/ - -typedef void (*mxml_error_cb_t)(const char *); - /**** Error callback function ****/ - -typedef struct mxml_attr_s /**** An XML element attribute value. ****/ -{ - char *name; /* Attribute name */ - char *value; /* Attribute value */ -} mxml_attr_t; - -typedef struct mxml_element_s /**** An XML element value. ****/ -{ - char *name; /* Name of element */ - int num_attrs; /* Number of attributes */ - mxml_attr_t *attrs; /* Attributes */ -} mxml_element_t; - -typedef struct mxml_text_s /**** An XML text value. ****/ -{ - int whitespace; /* Leading whitespace? */ - char *string; /* Fragment string */ -} mxml_text_t; - -typedef struct mxml_custom_s /**** An XML custom value. @since Mini-XML 2.1@ ****/ -{ - void *data; /* Pointer to (allocated) custom data */ - mxml_custom_destroy_cb_t destroy; /* Pointer to destructor function */ -} mxml_custom_t; - -typedef union mxml_value_u /**** An XML node value. ****/ -{ - mxml_element_t element; /* Element */ - int integer; /* Integer number */ - char *opaque; /* Opaque string */ - double real; /* Real number */ - mxml_text_t text; /* Text fragment */ - mxml_custom_t custom; /* Custom data @since Mini-XML 2.1@ */ -} mxml_value_t; - -typedef struct mxml_node_s /**** An XML node. ****/ -{ - mxml_type_t type; /* Node type */ - struct mxml_node_s *next; /* Next node under same parent */ - struct mxml_node_s *prev; /* Previous node under same parent */ - struct mxml_node_s *parent; /* Parent node */ - struct mxml_node_s *child; /* First child node */ - struct mxml_node_s *last_child; /* Last child node */ - mxml_value_t value; /* Node value */ - int ref_count; /* Use count */ - void *user_data; /* User data */ -} mxml_node_t; - -typedef struct mxml_index_s /**** An XML node index. ****/ -{ - char *attr; /* Attribute used for indexing or NULL */ - int num_nodes; /* Number of nodes in index */ - int alloc_nodes; /* Allocated nodes in index */ - int cur_node; /* Current node */ - mxml_node_t **nodes; /* Node array */ -} mxml_index_t; - -typedef int (*mxml_custom_load_cb_t)(mxml_node_t *, const char *); - /**** Custom data load callback function ****/ - -typedef char *(*mxml_custom_save_cb_t)(mxml_node_t *); - /**** Custom data save callback function ****/ - -typedef mxml_type_t (*mxml_load_cb_t)(mxml_node_t *); - /**** Load callback function ****/ - -typedef const char *(*mxml_save_cb_t)(mxml_node_t *, int); - /**** Save callback function ****/ - -typedef void (*mxml_sax_cb_t)(mxml_node_t *, mxml_sax_event_t, void *); - /**** SAX callback function ****/ - - -/* - * C++ support... - */ - -# ifdef __cplusplus -extern "C" { -# endif /* __cplusplus */ - -/* - * Prototypes... - */ - -extern void mxmlAdd(mxml_node_t *parent, int where, - mxml_node_t *child, mxml_node_t *node); -extern void mxmlDelete(mxml_node_t *node); -extern void mxmlElementDeleteAttr(mxml_node_t *node, - const char *name); -extern const char *mxmlElementGetAttr(mxml_node_t *node, const char *name); -extern void mxmlElementSetAttr(mxml_node_t *node, const char *name, - const char *value); -extern void mxmlElementSetAttrf(mxml_node_t *node, const char *name, - const char *format, ...) -# ifdef __GNUC__ -__attribute__ ((__format__ (__printf__, 3, 4))) -# endif /* __GNUC__ */ -; -extern int mxmlEntityAddCallback(int (*cb)(const char *name)); -extern const char *mxmlEntityGetName(int val); -extern int mxmlEntityGetValue(const char *name); -extern void mxmlEntityRemoveCallback(int (*cb)(const char *name)); -extern mxml_node_t *mxmlFindElement(mxml_node_t *node, mxml_node_t *top, - const char *name, const char *attr, - const char *value, int descend); -extern void mxmlIndexDelete(mxml_index_t *ind); -extern mxml_node_t *mxmlIndexEnum(mxml_index_t *ind); -extern mxml_node_t *mxmlIndexFind(mxml_index_t *ind, - const char *element, - const char *value); -extern mxml_index_t *mxmlIndexNew(mxml_node_t *node, const char *element, - const char *attr); -extern mxml_node_t *mxmlIndexReset(mxml_index_t *ind); -extern mxml_node_t *mxmlLoadFd(mxml_node_t *top, int fd, - mxml_type_t (*cb)(mxml_node_t *)); -extern mxml_node_t *mxmlLoadFile(mxml_node_t *top, FILE *fp, - mxml_type_t (*cb)(mxml_node_t *)); -extern mxml_node_t *mxmlLoadString(mxml_node_t *top, const char *s, - mxml_type_t (*cb)(mxml_node_t *)); -extern mxml_node_t *mxmlNewCDATA(mxml_node_t *parent, const char *string); -extern mxml_node_t *mxmlNewCustom(mxml_node_t *parent, void *data, - mxml_custom_destroy_cb_t destroy); -extern mxml_node_t *mxmlNewElement(mxml_node_t *parent, const char *name); -extern mxml_node_t *mxmlNewInteger(mxml_node_t *parent, int integer); -extern mxml_node_t *mxmlNewOpaque(mxml_node_t *parent, const char *opaque); -extern mxml_node_t *mxmlNewReal(mxml_node_t *parent, double real); -extern mxml_node_t *mxmlNewText(mxml_node_t *parent, int whitespace, - const char *string); -extern mxml_node_t *mxmlNewTextf(mxml_node_t *parent, int whitespace, - const char *format, ...) -# ifdef __GNUC__ -__attribute__ ((__format__ (__printf__, 3, 4))) -# endif /* __GNUC__ */ -; -extern mxml_node_t *mxmlNewXML(const char *version); -extern int mxmlRelease(mxml_node_t *node); -extern void mxmlRemove(mxml_node_t *node); -extern int mxmlRetain(mxml_node_t *node); -extern char *mxmlSaveAllocString(mxml_node_t *node, - mxml_save_cb_t cb); -extern int mxmlSaveFd(mxml_node_t *node, int fd, - mxml_save_cb_t cb); -extern int mxmlSaveFile(mxml_node_t *node, FILE *fp, - mxml_save_cb_t cb); -extern int mxmlSaveString(mxml_node_t *node, char *buffer, - int bufsize, mxml_save_cb_t cb); -extern mxml_node_t *mxmlSAXLoadFd(mxml_node_t *top, int fd, - mxml_type_t (*cb)(mxml_node_t *), - mxml_sax_cb_t sax, void *sax_data); -extern mxml_node_t *mxmlSAXLoadFile(mxml_node_t *top, FILE *fp, - mxml_type_t (*cb)(mxml_node_t *), - mxml_sax_cb_t sax, void *sax_data); -extern mxml_node_t *mxmlSAXLoadString(mxml_node_t *top, const char *s, - mxml_type_t (*cb)(mxml_node_t *), - mxml_sax_cb_t sax, void *sax_data); -extern int mxmlSetCDATA(mxml_node_t *node, const char *data); -extern int mxmlSetCustom(mxml_node_t *node, void *data, - mxml_custom_destroy_cb_t destroy); -extern void mxmlSetCustomHandlers(mxml_custom_load_cb_t load, - mxml_custom_save_cb_t save); -extern int mxmlSetElement(mxml_node_t *node, const char *name); -extern void mxmlSetErrorCallback(mxml_error_cb_t cb); -extern int mxmlSetInteger(mxml_node_t *node, int integer); -extern int mxmlSetOpaque(mxml_node_t *node, const char *opaque); -extern int mxmlSetReal(mxml_node_t *node, double real); -extern int mxmlSetText(mxml_node_t *node, int whitespace, - const char *string); -extern int mxmlSetTextf(mxml_node_t *node, int whitespace, - const char *format, ...) -# ifdef __GNUC__ -__attribute__ ((__format__ (__printf__, 3, 4))) -# endif /* __GNUC__ */ -; -extern void mxmlSetWrapMargin(int column); -extern mxml_node_t *mxmlWalkNext(mxml_node_t *node, mxml_node_t *top, - int descend); -extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top, - int descend); - - -/* - * Semi-private functions... - */ - -extern void mxml_error(const char *format, ...); -extern mxml_type_t mxml_ignore_cb(mxml_node_t *node); -extern mxml_type_t mxml_integer_cb(mxml_node_t *node); -extern mxml_type_t mxml_opaque_cb(mxml_node_t *node); -extern mxml_type_t mxml_real_cb(mxml_node_t *node); - - -/* - * C++ support... - */ - -# ifdef __cplusplus -} -# endif /* __cplusplus */ -#endif /* !_mxml_h_ */ - - -/* - * End of "$Id: mxml.h 307 2007-09-15 20:03:15Z mike $". - */ diff --git a/plugins/zynaddsubfx/src/Controls/CMakeLists.txt b/plugins/zynaddsubfx/src/Controls/CMakeLists.txt deleted file mode 100644 index 07ee3eaf4..000000000 --- a/plugins/zynaddsubfx/src/Controls/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -set(zynaddsubfx_controls_SRCS - Control.cpp - DelayCtl.cpp -) - -add_library(zynaddsubfx_controls STATIC - ${zynaddsubfx_controls_SRCS} - ) diff --git a/plugins/zynaddsubfx/src/Controls/Control.cpp b/plugins/zynaddsubfx/src/Controls/Control.cpp deleted file mode 100644 index d7cf5cb9d..000000000 --- a/plugins/zynaddsubfx/src/Controls/Control.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - ZynAddSubFX - a software synthesizer - - Control.C - Control base class - Copyright (C) 2009-2009 Mark McCurry - Author: Mark McCurry - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License - as published by the Free Software Foundation. - - 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 (version 2 or later) for more details. - - You should have received a copy of the GNU General Public License (version 2) - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ -#include "Control.h" - -Control::Control(char ndefaultval) - :defaultval(ndefaultval), lockqueue(-1), locked(false) -{} - -void Control::lock() -{ - locked = true; - lockqueue = -1; -} - -void Control::ulock() -{ - if(locked && (lockqueue >= 0)) - setmVal(lockqueue); - locked = false; -} - diff --git a/plugins/zynaddsubfx/src/Controls/Control.h b/plugins/zynaddsubfx/src/Controls/Control.h deleted file mode 100644 index 931a4745c..000000000 --- a/plugins/zynaddsubfx/src/Controls/Control.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - ZynAddSubFX - a software synthesizer - - Control.h - Control base class - Copyright (C) 2009-2009 Mark McCurry - Author: Mark McCurry - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License - as published by the Free Software Foundation. - - 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 (version 2 or later) for more details. - - You should have received a copy of the GNU General Public License (version 2) - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ -#ifndef CONTROL_H -#define CONTROL_H -#include -/**A control for a parameter within the program*/ -class Control -{ - public: - Control(char ndefaultval); /**\todo create proper initialization list*/ - ~Control() {} - /**Return the string, which represents the internal value - * @return a string representation of the current value*/ - virtual std::string getString() const = 0; - /**Set the Control to the given value - * @param nval A number 0-127*/ - virtual void setmVal(char nval) = 0; - /**Return the midi value (aka the char) - * @return the current value*/ - virtual char getmVal() const = 0; - /** Will lock the Control until it is ulocked - * - * Locking a Control will Stop it from having - * its internal data altered*/ - void lock(); - /** Will unlock the Control - * - * This will also update the Control - * if something attempted to update it while it was locked*/ - void ulock(); - private: - char defaultval; /** - -DelayCtl::DelayCtl() - :Control(64), value(64 / 127.0 * 1.5) {} /**\todo finishme*/ - -std::string DelayCtl::getString() const -{ - std::ostringstream buf; - buf << value; - return buf.str() + " Seconds"; -} - -void DelayCtl::setmVal(char nval) -{ - /**\todo add locking code*/ - //value=1+(int)(nval/127.0*SAMPLE_RATE*1.5);//0 .. 1.5 sec - value = (nval / 127.0 * 1.5); //0 .. 1.5 sec -} - -char DelayCtl::getmVal() const -{ - return (char)(value / 1.5 * 127.0); -} - -float DelayCtl::getiVal() const -{ - return value; -} - diff --git a/plugins/zynaddsubfx/src/Controls/DelayCtl.h b/plugins/zynaddsubfx/src/Controls/DelayCtl.h deleted file mode 100644 index e63020876..000000000 --- a/plugins/zynaddsubfx/src/Controls/DelayCtl.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - ZynAddSubFX - a software synthesizer - - DelayCtl.h - Control For Delays - Copyright (C) 2009-2009 Mark McCurry - Author: Mark McCurry - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License - as published by the Free Software Foundation. - - 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 (version 2 or later) for more details. - - You should have received a copy of the GNU General Public License (version 2) - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ -#include "Control.h" - -#ifndef DELAYCTL_H -#define DELAYCTL_H -/**A Control for Delays - * - * Will vary from 0 seconds to 1.5 seconds*/ -class DelayCtl:public Control -{ - public: - DelayCtl(); - ~DelayCtl() {} - std::string getString() const; - void setmVal(char nval); - char getmVal() const; - float getiVal() const; - private: - float value; -}; - -#endif - diff --git a/plugins/zynaddsubfx/src/DSP/AnalogFilter.cpp b/plugins/zynaddsubfx/src/DSP/AnalogFilter.cpp index 2c2ed5525..bb1ad75c8 100644 --- a/plugins/zynaddsubfx/src/DSP/AnalogFilter.cpp +++ b/plugins/zynaddsubfx/src/DSP/AnalogFilter.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - AnalogFilter.C - Several analog filters (lowpass, highpass...) + AnalogFilter.cpp - Several analog filters (lowpass, highpass...) Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/DSP/CMakeLists.txt b/plugins/zynaddsubfx/src/DSP/CMakeLists.txt index c13cd316c..263a1babb 100644 --- a/plugins/zynaddsubfx/src/DSP/CMakeLists.txt +++ b/plugins/zynaddsubfx/src/DSP/CMakeLists.txt @@ -4,7 +4,7 @@ set(zynaddsubfx_dsp_SRCS Filter.cpp FormantFilter.cpp SVFilter.cpp - Unison.cpp + Unison.cpp ) add_library(zynaddsubfx_dsp STATIC diff --git a/plugins/zynaddsubfx/src/DSP/Filter.cpp b/plugins/zynaddsubfx/src/DSP/Filter.cpp index d95abe448..c6a3ce976 100644 --- a/plugins/zynaddsubfx/src/DSP/Filter.cpp +++ b/plugins/zynaddsubfx/src/DSP/Filter.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Filter.C - Filters, uses analog,formant,etc. filters + Filter.cpp - Filters, uses analog,formant,etc. filters Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/DSP/Filter_.h b/plugins/zynaddsubfx/src/DSP/Filter_.h index b577193f3..88716f0b2 100644 --- a/plugins/zynaddsubfx/src/DSP/Filter_.h +++ b/plugins/zynaddsubfx/src/DSP/Filter_.h @@ -33,7 +33,7 @@ class Filter_ virtual void setfreq(REALTYPE frequency) = 0; virtual void setfreq_and_q(REALTYPE frequency, REALTYPE q_) = 0; virtual void setq(REALTYPE q_) = 0; - virtual void setgain(REALTYPE dBgain) {} + virtual void setgain(REALTYPE dBgain) = 0; REALTYPE outgain; private: }; diff --git a/plugins/zynaddsubfx/src/DSP/FormantFilter.cpp b/plugins/zynaddsubfx/src/DSP/FormantFilter.cpp index 39c1002d9..6d6771901 100644 --- a/plugins/zynaddsubfx/src/DSP/FormantFilter.cpp +++ b/plugins/zynaddsubfx/src/DSP/FormantFilter.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - FormantFilter.C - formant filters + FormantFilter.cpp - formant filters Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -191,6 +191,10 @@ void FormantFilter::setq(REALTYPE q_) formant[i]->setq(Qfactor * currentformants[i].q); } +void FormantFilter::setgain(REALTYPE dBgain) +{} + + void FormantFilter::setfreq_and_q(REALTYPE frequency, REALTYPE q_) { Qfactor = q_; diff --git a/plugins/zynaddsubfx/src/DSP/FormantFilter.h b/plugins/zynaddsubfx/src/DSP/FormantFilter.h index f62536123..4efe24fa5 100644 --- a/plugins/zynaddsubfx/src/DSP/FormantFilter.h +++ b/plugins/zynaddsubfx/src/DSP/FormantFilter.h @@ -38,6 +38,7 @@ class FormantFilter:public Filter_ void setfreq(REALTYPE frequency); void setfreq_and_q(REALTYPE frequency, REALTYPE q_); void setq(REALTYPE q_); + void setgain(REALTYPE dBgain); void cleanup(); private: diff --git a/plugins/zynaddsubfx/src/DSP/SVFilter.cpp b/plugins/zynaddsubfx/src/DSP/SVFilter.cpp index d79c80fa3..636835a8c 100644 --- a/plugins/zynaddsubfx/src/DSP/SVFilter.cpp +++ b/plugins/zynaddsubfx/src/DSP/SVFilter.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - SVFilter.C - Several state-variable filters + SVFilter.cpp - Several state-variable filters Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Effects/Alienwah.cpp b/plugins/zynaddsubfx/src/Effects/Alienwah.cpp index fb07d4f11..9d13ea8c1 100644 --- a/plugins/zynaddsubfx/src/Effects/Alienwah.cpp +++ b/plugins/zynaddsubfx/src/Effects/Alienwah.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Alienwah.C - "AlienWah" effect + Alienwah.cpp - "AlienWah" effect Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -46,7 +46,7 @@ Alienwah::~Alienwah() /* * Apply the effect */ -void Alienwah::out(REALTYPE *smpsl, REALTYPE *smpsr) +void Alienwah::out(const Stereo &smp) { REALTYPE lfol, lfor; //Left/Right LFOs complex clfol, clfor, out, tmp; @@ -67,7 +67,7 @@ void Alienwah::out(REALTYPE *smpsl, REALTYPE *smpsr) tmp = clfol * x + oldclfol * x1; out = tmp * oldl[oldk]; - out.real() += (1 - fabs(fb)) * smpsr[i] * (1.0 - panning); + out.real() += (1 - fabs(fb)) * smp.l[i] * (1.0 - panning); oldl[oldk] = out; REALTYPE l = out.real() * 10.0 * (fb + 0.1); @@ -76,7 +76,7 @@ void Alienwah::out(REALTYPE *smpsl, REALTYPE *smpsr) tmp = clfor * x + oldclfor * x1; out = tmp * oldr[oldk]; - out.real() += (1 - fabs(fb)) * smpsr[i] * (1.0 - panning); + out.real() += (1 - fabs(fb)) * smp.r[i] * (1.0 - panning); oldr[oldk] = out; REALTYPE r = out.real() * 10.0 * (fb + 0.1); @@ -110,13 +110,13 @@ void Alienwah::cleanup() * Parameter control */ -void Alienwah::setdepth(const unsigned char &Pdepth) +void Alienwah::setdepth(unsigned char Pdepth) { this->Pdepth = Pdepth; depth = (Pdepth / 127.0); } -void Alienwah::setfb(const unsigned char &Pfb) +void Alienwah::setfb(unsigned char Pfb) { this->Pfb = Pfb; fb = fabs((Pfb - 64.0) / 64.1); @@ -127,7 +127,7 @@ void Alienwah::setfb(const unsigned char &Pfb) fb = -fb; } -void Alienwah::setvolume(const unsigned char &Pvolume) +void Alienwah::setvolume(unsigned char Pvolume) { this->Pvolume = Pvolume; outvolume = Pvolume / 127.0; @@ -137,25 +137,25 @@ void Alienwah::setvolume(const unsigned char &Pvolume) volume = outvolume; } -void Alienwah::setpanning(const unsigned char &Ppanning) +void Alienwah::setpanning(unsigned char Ppanning) { this->Ppanning = Ppanning; panning = Ppanning / 127.0; } -void Alienwah::setlrcross(const unsigned char &Plrcross) +void Alienwah::setlrcross(unsigned char Plrcross) { this->Plrcross = Plrcross; lrcross = Plrcross / 127.0; } -void Alienwah::setphase(const unsigned char &Pphase) +void Alienwah::setphase(unsigned char Pphase) { this->Pphase = Pphase; phase = (Pphase - 64.0) / 64.0 * PI; } -void Alienwah::setdelay(const unsigned char &Pdelay) +void Alienwah::setdelay(unsigned char Pdelay) { if(oldl != NULL) delete [] oldl; @@ -190,12 +190,12 @@ void Alienwah::setpreset(unsigned char npreset) for(int n = 0; n < PRESET_SIZE; n++) changepar(n, presets[npreset][n]); if(insertion == 0) - changepar(0, presets[npreset][0] / 2); //lower the volume if this is system effect + changepar(0, presets[npreset][0] / 2); //lower the volume if this is system effect Ppreset = npreset; } -void Alienwah::changepar(const int &npar, const unsigned char &value) +void Alienwah::changepar(int npar, unsigned char value) { switch(npar) { case 0: @@ -238,7 +238,7 @@ void Alienwah::changepar(const int &npar, const unsigned char &value) } } -unsigned char Alienwah::getpar(const int &npar) const +unsigned char Alienwah::getpar(int npar) const { switch(npar) { case 0: diff --git a/plugins/zynaddsubfx/src/Effects/Alienwah.h b/plugins/zynaddsubfx/src/Effects/Alienwah.h index 175c41f24..9ad695403 100644 --- a/plugins/zynaddsubfx/src/Effects/Alienwah.h +++ b/plugins/zynaddsubfx/src/Effects/Alienwah.h @@ -46,11 +46,11 @@ class Alienwah:public Effect REALTYPE *const efxoutl_, REALTYPE *const efxoutr_); ~Alienwah(); - void out(REALTYPE *const smpsl, REALTYPE *const smpsr); + void out(const Stereo &smp); void setpreset(unsigned char npreset); - void changepar(const int &npar, const unsigned char &value); - unsigned char getpar(const int &npar) const; + void changepar(int npar, unsigned char value); + unsigned char getpar(int npar) const; void cleanup(); private: @@ -66,13 +66,13 @@ class Alienwah:public Effect //Control Parameters - void setvolume(const unsigned char &Pvolume); - void setpanning(const unsigned char &Ppanning); - void setdepth(const unsigned char &Pdepth); - void setfb(const unsigned char &Pfb); - void setlrcross(const unsigned char &Plrcross); - void setdelay(const unsigned char &Pdelay); - void setphase(const unsigned char &Pphase); + void setvolume(unsigned char Pvolume); + void setpanning(unsigned char Ppanning); + void setdepth(unsigned char Pdepth); + void setfb(unsigned char Pfb); + void setlrcross(unsigned char Plrcross); + void setdelay(unsigned char Pdelay); + void setphase(unsigned char Pphase); //Internal Values REALTYPE panning, fb, depth, lrcross, phase; diff --git a/plugins/zynaddsubfx/src/Effects/Chorus.cpp b/plugins/zynaddsubfx/src/Effects/Chorus.cpp index 708c0cd75..b39c0032b 100644 --- a/plugins/zynaddsubfx/src/Effects/Chorus.cpp +++ b/plugins/zynaddsubfx/src/Effects/Chorus.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Chorus.C - Chorus and Flange effects + Chorus.cpp - Chorus and Flange effects Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -35,9 +35,6 @@ Chorus::Chorus(const int &insertion_, { dlk = 0; drk = 0; - //maxdelay=(int)(MAX_CHORUS_DELAY/1000.0*SAMPLE_RATE); - //delayl=new REALTYPE[maxdelay]; - //delayr=new REALTYPE[maxdelay]; setpreset(Ppreset); @@ -65,24 +62,13 @@ REALTYPE Chorus::getdelay(REALTYPE xlfo) if((result + 0.5) >= maxdelay) { cerr << - "WARNING: Chorus.C::getdelay(..) too big delay (see setdelay and setdepth funcs.)\n"; + "WARNING: Chorus.cpp::getdelay(..) too big delay (see setdelay and setdepth funcs.)\n"; result = maxdelay - 1.0; } return result; } -/* - * Apply the effect - */ -void Chorus::out(REALTYPE *smpsl, REALTYPE *smpsr) -{ - const Stereo input(AuSample(SOUND_BUFFER_SIZE, smpsl), AuSample( - SOUND_BUFFER_SIZE, - smpsr)); - out(input); -} - -void Chorus::out(const Stereo &input) +void Chorus::out(const Stereo &input) { const REALTYPE one = 1.0; dl1 = dl2; @@ -92,14 +78,14 @@ void Chorus::out(const Stereo &input) dl2 = getdelay(lfol); dr2 = getdelay(lfor); - for(int i = 0; i < input.l().size(); i++) { - REALTYPE inl = input.l()[i]; - REALTYPE inr = input.r()[i]; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE inl = input.l[i]; + REALTYPE inr = input.r[i]; //LRcross Stereo tmpc(inl, inr); //REALTYPE r=inr; - inl = tmpc.l() * (1.0 - lrcross) + tmpc.r() * lrcross; - inr = tmpc.r() * (1.0 - lrcross) + tmpc.l() * lrcross; + inl = tmpc.l * (1.0 - lrcross) + tmpc.r * lrcross; + inr = tmpc.r * (1.0 - lrcross) + tmpc.l * lrcross; //Left channel @@ -114,9 +100,9 @@ void Chorus::out(const Stereo &input) dlhi2 = (dlhi - 1 + maxdelay) % maxdelay; dllo = 1.0 - fmod(tmp, one); - efxoutl[i] = delaySample.l()[dlhi2] * dllo + delaySample.l()[dlhi] + efxoutl[i] = delaySample.l[dlhi2] * dllo + delaySample.l[dlhi] * (1.0 - dllo); - delaySample.l()[dlk] = inl + efxoutl[i] * fb; + delaySample.l[dlk] = inl + efxoutl[i] * fb; //Right channel @@ -131,20 +117,20 @@ void Chorus::out(const Stereo &input) dlhi2 = (dlhi - 1 + maxdelay) % maxdelay; dllo = 1.0 - fmod(tmp, one); - efxoutr[i] = delaySample.r()[dlhi2] * dllo + delaySample.r()[dlhi] + efxoutr[i] = delaySample.r[dlhi2] * dllo + delaySample.r[dlhi] * (1.0 - dllo); - delaySample.r()[dlk] = inr + efxoutr[i] * fb; + delaySample.r[dlk] = inr + efxoutr[i] * fb; } if(Poutsub != 0) - for(int i = 0; i < input.l().size(); i++) { + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { efxoutl[i] *= -1.0; efxoutr[i] *= -1.0; } ; - for(int i = 0; i < input.l().size(); i++) { + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { efxoutl[i] *= panning; efxoutr[i] *= (1.0 - panning); } @@ -155,31 +141,31 @@ void Chorus::out(const Stereo &input) */ void Chorus::cleanup() { - delaySample.l().clear(); - delaySample.r().clear(); + delaySample.l.clear(); + delaySample.r.clear(); } /* * Parameter control */ -void Chorus::setdepth(const unsigned char &Pdepth) +void Chorus::setdepth(unsigned char Pdepth) { this->Pdepth = Pdepth; depth = (pow(8.0, (Pdepth / 127.0) * 2.0) - 1.0) / 1000.0; //seconds } -void Chorus::setdelay(const unsigned char &Pdelay) +void Chorus::setdelay(unsigned char Pdelay) { this->Pdelay = Pdelay; delay = (pow(10.0, (Pdelay / 127.0) * 2.0) - 1.0) / 1000.0; //seconds } -void Chorus::setfb(const unsigned char &Pfb) +void Chorus::setfb(unsigned char Pfb) { this->Pfb = Pfb; fb = (Pfb - 64.0) / 64.1; } -void Chorus::setvolume(const unsigned char &Pvolume) +void Chorus::setvolume(unsigned char Pvolume) { this->Pvolume = Pvolume; outvolume = Pvolume / 127.0; @@ -189,13 +175,13 @@ void Chorus::setvolume(const unsigned char &Pvolume) volume = outvolume; } -void Chorus::setpanning(const unsigned char &Ppanning) +void Chorus::setpanning(unsigned char Ppanning) { this->Ppanning = Ppanning; panning = Ppanning / 127.0; } -void Chorus::setlrcross(const unsigned char &Plrcross) +void Chorus::setlrcross(unsigned char Plrcross) { this->Plrcross = Plrcross; lrcross = Plrcross / 127.0; @@ -236,7 +222,7 @@ void Chorus::setpreset(unsigned char npreset) } -void Chorus::changepar(const int &npar, const unsigned char &value) +void Chorus::changepar(int npar, unsigned char value) { switch(npar) { case 0: @@ -288,7 +274,7 @@ void Chorus::changepar(const int &npar, const unsigned char &value) } } -unsigned char Chorus::getpar(const int &npar) const +unsigned char Chorus::getpar(int npar) const { switch(npar) { case 0: diff --git a/plugins/zynaddsubfx/src/Effects/Chorus.h b/plugins/zynaddsubfx/src/Effects/Chorus.h index 748ce5eaf..2aeb1a191 100644 --- a/plugins/zynaddsubfx/src/Effects/Chorus.h +++ b/plugins/zynaddsubfx/src/Effects/Chorus.h @@ -25,7 +25,7 @@ #include "../globals.h" #include "Effect.h" #include "EffectLFO.h" -#include "../Samples/AuSample.h" +#include "../Samples/Sample.h" #include "../Misc/Stereo.h" #define MAX_CHORUS_DELAY 250.0 //ms @@ -37,8 +37,7 @@ class Chorus:public Effect Chorus(const int &insetion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); /**Destructor*/ ~Chorus(); - void out(REALTYPE *smpsl, REALTYPE *smpsr); - void out(const Stereo &input); + void out(const Stereo &input); void setpreset(unsigned char npreset); /** * Sets the value of the chosen variable @@ -58,7 +57,7 @@ class Chorus:public Effect * @param npar number of chosen parameter * @param value the new value */ - void changepar(const int &npar, const unsigned char &value); + void changepar(int npar, unsigned char value); /** * Gets the value of the chosen variable * @@ -77,7 +76,7 @@ class Chorus:public Effect * @param npar number of chosen parameter * @return the value of the parameter */ - unsigned char getpar(const int &npar) const; + unsigned char getpar(int npar) const; void cleanup(); private: @@ -94,19 +93,18 @@ class Chorus:public Effect //Parameter Controls - void setvolume(const unsigned char &Pvolume); - void setpanning(const unsigned char &Ppanning); - void setdepth(const unsigned char &Pdepth); - void setdelay(const unsigned char &Pdelay); - void setfb(const unsigned char &Pfb); - void setlrcross(const unsigned char &Plrcross); + void setvolume(unsigned char Pvolume); + void setpanning(unsigned char Ppanning); + void setdepth(unsigned char Pdepth); + void setdelay(unsigned char Pdelay); + void setfb(unsigned char Pfb); + void setlrcross(unsigned char Plrcross); //Internal Values REALTYPE depth, delay, fb, lrcross, panning; REALTYPE dl1, dl2, dr1, dr2, lfol, lfor; int maxdelay; - Stereo delaySample; - //REALTYPE *delayl,*delayr; + Stereo delaySample; int dlk, drk, dlhi, dlhi2; REALTYPE getdelay(REALTYPE xlfo); REALTYPE dllo, mdel; diff --git a/plugins/zynaddsubfx/src/Effects/Distorsion.cpp b/plugins/zynaddsubfx/src/Effects/Distorsion.cpp index 61fe9966b..a0b6a2e62 100644 --- a/plugins/zynaddsubfx/src/Effects/Distorsion.cpp +++ b/plugins/zynaddsubfx/src/Effects/Distorsion.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Distorsion.C - Distorsion effect + Distorsion.cpp - Distorsion effect Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -260,7 +260,7 @@ void Distorsion::applyfilters(REALTYPE *efxoutl, REALTYPE *efxoutr) /* * Effect output */ -void Distorsion::out(REALTYPE *smpsl, REALTYPE *smpsr) +void Distorsion::out(const Stereo &smp) { int i; REALTYPE l, r, lout, rout; @@ -271,14 +271,14 @@ void Distorsion::out(REALTYPE *smpsl, REALTYPE *smpsr) if(Pstereo != 0) { //Stereo for(i = 0; i < SOUND_BUFFER_SIZE; i++) { - efxoutl[i] = smpsl[i] * inputvol * panning; - efxoutr[i] = smpsr[i] * inputvol * (1.0 - panning); + efxoutl[i] = smp.l[i] * inputvol * panning; + efxoutr[i] = smp.r[i] * inputvol * (1.0 - panning); } } else { for(i = 0; i < SOUND_BUFFER_SIZE; i++) efxoutl[i] = - (smpsl[i] * panning + smpsr[i] * (1.0 - panning)) * inputvol; + (smp.l[i] * panning + smp.r[i] * (1.0 - panning)) * inputvol; ; } @@ -315,7 +315,7 @@ void Distorsion::out(REALTYPE *smpsl, REALTYPE *smpsr) /* * Parameter control */ -void Distorsion::setvolume(const unsigned char &Pvolume) +void Distorsion::setvolume(unsigned char Pvolume) { this->Pvolume = Pvolume; @@ -330,20 +330,20 @@ void Distorsion::setvolume(const unsigned char &Pvolume) cleanup(); } -void Distorsion::setpanning(const unsigned char &Ppanning) +void Distorsion::setpanning(unsigned char Ppanning) { this->Ppanning = Ppanning; panning = (Ppanning + 0.5) / 127.0; } -void Distorsion::setlrcross(const unsigned char &Plrcross) +void Distorsion::setlrcross(unsigned char Plrcross) { this->Plrcross = Plrcross; lrcross = Plrcross / 127.0 * 1.0; } -void Distorsion::setlpf(const unsigned char &Plpf) +void Distorsion::setlpf(unsigned char Plpf) { this->Plpf = Plpf; REALTYPE fr = exp(pow(Plpf / 127.0, 0.5) * log(25000.0)) + 40; @@ -351,7 +351,7 @@ void Distorsion::setlpf(const unsigned char &Plpf) lpfr->setfreq(fr); } -void Distorsion::sethpf(const unsigned char &Phpf) +void Distorsion::sethpf(unsigned char Phpf) { this->Phpf = Phpf; REALTYPE fr = exp(pow(Phpf / 127.0, 0.5) * log(25000.0)) + 20.0; @@ -391,7 +391,7 @@ void Distorsion::setpreset(unsigned char npreset) } -void Distorsion::changepar(const int &npar, const unsigned char &value) +void Distorsion::changepar(int npar, unsigned char value) { switch(npar) { case 0: @@ -439,7 +439,7 @@ void Distorsion::changepar(const int &npar, const unsigned char &value) } } -unsigned char Distorsion::getpar(const int &npar) const +unsigned char Distorsion::getpar(int npar) const { switch(npar) { case 0: diff --git a/plugins/zynaddsubfx/src/Effects/Distorsion.h b/plugins/zynaddsubfx/src/Effects/Distorsion.h index 8c082f13f..472af3ffd 100644 --- a/plugins/zynaddsubfx/src/Effects/Distorsion.h +++ b/plugins/zynaddsubfx/src/Effects/Distorsion.h @@ -38,32 +38,32 @@ class Distorsion:public Effect public: Distorsion(const int &insertion, REALTYPE *efxoutl_, REALTYPE *efxoutr_); ~Distorsion(); - void out(REALTYPE *smpsl, REALTYPE *smpr); + void out(const Stereo &smp); void setpreset(unsigned char npreset); - void changepar(const int &npar, const unsigned char &value); - unsigned char getpar(const int &npar) const; + void changepar(int npar, unsigned char value); + unsigned char getpar(int npar) const; void cleanup(); void applyfilters(REALTYPE *efxoutl, REALTYPE *efxoutr); private: //Parametrii - unsigned char Pvolume; //Volumul or E/R - unsigned char Ppanning; //Panning - unsigned char Plrcross; // L/R Mixing - unsigned char Pdrive; //the input amplification - unsigned char Plevel; //the output amplification - unsigned char Ptype; //Distorsion type - unsigned char Pnegate; //if the input is negated - unsigned char Plpf; //lowpass filter - unsigned char Phpf; //highpass filter - unsigned char Pstereo; //0=mono,1=stereo + unsigned char Pvolume; //Volume or E/R + unsigned char Ppanning; //Panning + unsigned char Plrcross; // L/R Mixing + unsigned char Pdrive; //the input amplification + unsigned char Plevel; //the output amplification + unsigned char Ptype; //Distorsion type + unsigned char Pnegate; //if the input is negated + unsigned char Plpf; //lowpass filter + unsigned char Phpf; //highpass filter + unsigned char Pstereo; //0=mono,1=stereo unsigned char Pprefiltering; //if you want to do the filtering before the distorsion - void setvolume(const unsigned char &Pvolume); - void setpanning(const unsigned char &Ppanning); - void setlrcross(const unsigned char &Plrcross); - void setlpf(const unsigned char &Plpf); - void sethpf(const unsigned char &Phpf); + void setvolume(unsigned char Pvolume); + void setpanning(unsigned char Ppanning); + void setlrcross(unsigned char Plrcross); + void setlpf(unsigned char Plpf); + void sethpf(unsigned char Phpf); //Real Parameters REALTYPE panning, lrcross; diff --git a/plugins/zynaddsubfx/src/Effects/DynamicFilter.cpp b/plugins/zynaddsubfx/src/Effects/DynamicFilter.cpp index 1b2bb1eb0..b60f40142 100644 --- a/plugins/zynaddsubfx/src/Effects/DynamicFilter.cpp +++ b/plugins/zynaddsubfx/src/Effects/DynamicFilter.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - DynamicFilter.C - "WahWah" effect and others + DynamicFilter.cpp - "WahWah" effect and others Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -46,7 +46,7 @@ DynamicFilter::~DynamicFilter() /* * Apply the effect */ -void DynamicFilter::out(REALTYPE *smpsl, REALTYPE *smpsr) +void DynamicFilter::out(const Stereo &smp) { int i; if(filterpars->changed) { @@ -62,10 +62,10 @@ void DynamicFilter::out(REALTYPE *smpsl, REALTYPE *smpsr) REALTYPE q = filterpars->getq(); for(i = 0; i < SOUND_BUFFER_SIZE; i++) { - efxoutl[i] = smpsl[i]; - efxoutr[i] = smpsr[i]; + efxoutl[i] = smp.l[i]; + efxoutr[i] = smp.r[i]; - REALTYPE x = (fabs(smpsl[i]) + fabs(smpsr[i])) * 0.5; + REALTYPE x = (fabs(smp.l[i]) + fabs(smp.l[i])) * 0.5; ms1 = ms1 * (1.0 - ampsmooth) + x * ampsmooth + 1e-10; } @@ -110,14 +110,14 @@ void DynamicFilter::cleanup() * Parameter control */ -void DynamicFilter::setdepth(const unsigned char &Pdepth) +void DynamicFilter::setdepth(unsigned char Pdepth) { this->Pdepth = Pdepth; depth = pow((Pdepth / 127.0), 2.0); } -void DynamicFilter::setvolume(const unsigned char &Pvolume) +void DynamicFilter::setvolume(unsigned char Pvolume) { this->Pvolume = Pvolume; outvolume = Pvolume / 127.0; @@ -127,14 +127,14 @@ void DynamicFilter::setvolume(const unsigned char &Pvolume) volume = outvolume; } -void DynamicFilter::setpanning(const unsigned char &Ppanning) +void DynamicFilter::setpanning(unsigned char Ppanning) { this->Ppanning = Ppanning; panning = Ppanning / 127.0; } -void DynamicFilter::setampsns(const unsigned char &Pampsns) +void DynamicFilter::setampsns(unsigned char Pampsns) { ampsns = pow(Pampsns / 127.0, 2.5) * 10.0; if(Pampsnsinv != 0) @@ -270,7 +270,7 @@ void DynamicFilter::setpreset(unsigned char npreset) } -void DynamicFilter::changepar(const int &npar, const unsigned char &value) +void DynamicFilter::changepar(int npar, unsigned char value) { switch(npar) { case 0: @@ -312,7 +312,7 @@ void DynamicFilter::changepar(const int &npar, const unsigned char &value) } } -unsigned char DynamicFilter::getpar(const int &npar) const +unsigned char DynamicFilter::getpar(int npar) const { switch(npar) { case 0: diff --git a/plugins/zynaddsubfx/src/Effects/DynamicFilter.h b/plugins/zynaddsubfx/src/Effects/DynamicFilter.h index 2bb5fcd9b..6ce10f5ee 100644 --- a/plugins/zynaddsubfx/src/Effects/DynamicFilter.h +++ b/plugins/zynaddsubfx/src/Effects/DynamicFilter.h @@ -33,11 +33,11 @@ class DynamicFilter:public Effect public: DynamicFilter(int insetion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); ~DynamicFilter(); - void out(REALTYPE *smpsl, REALTYPE *smpsr); + void out(const Stereo &smp); void setpreset(unsigned char npreset); - void changepar(const int &npar, const unsigned char &value); - unsigned char getpar(const int &npar) const; + void changepar(int npar, unsigned char value); + unsigned char getpar(int npar) const; void cleanup(); // void setdryonly(); @@ -53,10 +53,10 @@ class DynamicFilter:public Effect unsigned char Pampsmooth; //how smooth the input amplitude changes the filter //Parameter Control - void setvolume(const unsigned char &Pvolume); - void setpanning(const unsigned char &Ppanning); - void setdepth(const unsigned char &Pdepth); - void setampsns(const unsigned char &Pampsns); + void setvolume(unsigned char Pvolume); + void setpanning(unsigned char Ppanning); + void setdepth(unsigned char Pdepth); + void setampsns(unsigned char Pampsns); void reinitfilter(); diff --git a/plugins/zynaddsubfx/src/Effects/EQ.cpp b/plugins/zynaddsubfx/src/Effects/EQ.cpp index 8ff71918d..59aa9f155 100644 --- a/plugins/zynaddsubfx/src/Effects/EQ.cpp +++ b/plugins/zynaddsubfx/src/Effects/EQ.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - EQ.C - EQ effect + EQ.cpp - EQ effect Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -45,9 +45,6 @@ EQ::EQ(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_) EQ::~EQ() {} -/* - * Cleanup the effect - */ void EQ::cleanup() { for(int i = 0; i < MAX_EQ_BANDS; i++) { @@ -56,17 +53,12 @@ void EQ::cleanup() } } - - -/* - * Effect output - */ -void EQ::out(REALTYPE *smpsl, REALTYPE *smpsr) +void EQ::out(const Stereo &smp) { int i; for(i = 0; i < SOUND_BUFFER_SIZE; i++) { - efxoutl[i] = smpsl[i] * volume; - efxoutr[i] = smpsr[i] * volume; + efxoutl[i] = smp.l[i] * volume; + efxoutr[i] = smp.r[i] * volume; } for(i = 0; i < MAX_EQ_BANDS; i++) { @@ -81,7 +73,7 @@ void EQ::out(REALTYPE *smpsl, REALTYPE *smpsr) /* * Parameter control */ -void EQ::setvolume(const unsigned char &Pvolume) +void EQ::setvolume(unsigned char Pvolume) { this->Pvolume = Pvolume; @@ -113,7 +105,7 @@ void EQ::setpreset(unsigned char npreset) } -void EQ::changepar(const int &npar, const unsigned char &value) +void EQ::changepar(int npar, unsigned char value) { switch(npar) { case 0: @@ -167,7 +159,7 @@ void EQ::changepar(const int &npar, const unsigned char &value) } } -unsigned char EQ::getpar(const int &npar) const +unsigned char EQ::getpar(int npar) const { switch(npar) { case 0: diff --git a/plugins/zynaddsubfx/src/Effects/EQ.h b/plugins/zynaddsubfx/src/Effects/EQ.h index 6f4130cd1..7ac328404 100644 --- a/plugins/zynaddsubfx/src/Effects/EQ.h +++ b/plugins/zynaddsubfx/src/Effects/EQ.h @@ -33,17 +33,17 @@ class EQ:public Effect public: EQ(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); ~EQ(); - void out(REALTYPE *smpsl, REALTYPE *smpr); + void out(const Stereo &smp); void setpreset(unsigned char npreset); - void changepar(const int &npar, const unsigned char &value); - unsigned char getpar(const int &npar) const; + void changepar(int npar, unsigned char value); + unsigned char getpar(int npar) const; void cleanup(); REALTYPE getfreqresponse(REALTYPE freq); private: //Parameters unsigned char Pvolume; /** -#include #include "Echo.h" +#define MAX_DELAY 2 + Echo::Echo(const int &insertion_, REALTYPE *const efxoutl_, REALTYPE *const efxoutr_) :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), - Pvolume(50), Ppanning(64), //Pdelay(60), + Pvolume(50), Ppanning(64), Pdelay(60), Plrdelay(100), Plrcross(100), Pfb(40), Phidamp(60), - lrdelay(0), delaySample(1), old(0.0) + delayTime(1), lrdelay(0), avgDelay(0), + delay(new REALTYPE[(int)(MAX_DELAY * SAMPLE_RATE)], + new REALTYPE[(int)(MAX_DELAY * SAMPLE_RATE)]), + old(0.0), pos(0), delta(1), ndelta(1) { + initdelays(); setpreset(Ppreset); } -Echo::~Echo() {} +Echo::~Echo() +{ + delete[] delay.l; + delete[] delay.r; +} /* * Cleanup the effect */ void Echo::cleanup() { - delaySample.l().clear(); - delaySample.r().clear(); + memset(delay.l,0,MAX_DELAY*SAMPLE_RATE*sizeof(REALTYPE)); + memset(delay.r,0,MAX_DELAY*SAMPLE_RATE*sizeof(REALTYPE)); old = Stereo(0.0); } +inline int max(int a, int b) +{ + return a > b ? a : b; +} /* * Initialize the delays */ void Echo::initdelays() { - /**\todo make this adjust insted of destroy old delays*/ - kl = 0; - kr = 0; - dl = (int)(1 + delay.getiVal() * SAMPLE_RATE - lrdelay); - if(dl < 1) - dl = 1; - dr = (int)(1 + delay.getiVal() * SAMPLE_RATE + lrdelay); - if(dr < 1) - dr = 1; + cleanup(); + //number of seconds to delay left chan + float dl = avgDelay - lrdelay; - delaySample.l() = AuSample(dl); - delaySample.r() = AuSample(dr); + //number of seconds to delay right chan + float dr = avgDelay + lrdelay; - old = Stereo(0.0); + ndelta.l = max(1,(int) (dl * SAMPLE_RATE)); + ndelta.r = max(1,(int) (dr * SAMPLE_RATE)); } -/* - * Effect output - */ -void Echo::out(REALTYPE *const smpsl, REALTYPE *const smpsr) +void Echo::out(const Stereo &input) { - Stereo input(AuSample(SOUND_BUFFER_SIZE, smpsl), AuSample( - SOUND_BUFFER_SIZE, - smpsr)); - out(input); -} + REALTYPE ldl, rdl; -void Echo::out(const Stereo &input) -{ -//void Echo::out(const Stereo & input){ //ideal - REALTYPE l, r, ldl, rdl; /**\todo move l+r->? ldl+rdl->?*/ - - for(int i = 0; i < input.l().size(); i++) { - ldl = delaySample.l()[kl]; - rdl = delaySample.r()[kr]; - l = ldl * (1.0 - lrcross) + rdl * lrcross; - r = rdl * (1.0 - lrcross) + ldl * lrcross; - ldl = l; - rdl = r; + for(int i = 0; i < SOUND_BUFFER_SIZE; ++i) { + ldl = delay.l[pos.l]; + rdl = delay.r[pos.r]; + ldl = ldl * (1.0 - lrcross) + rdl * lrcross; + rdl = rdl * (1.0 - lrcross) + ldl * lrcross; efxoutl[i] = ldl * 2.0; efxoutr[i] = rdl * 2.0; - - ldl = input.l()[i] * panning - ldl * fb; - rdl = input.r()[i] * (1.0 - panning) - rdl * fb; + ldl = input.l[i] * panning - ldl * fb; + rdl = input.r[i] * (1.0 - panning) - rdl * fb; //LowPass Filter - delaySample.l()[kl] = ldl = ldl * hidamp + old.l() * (1.0 - hidamp); - delaySample.r()[kr] = rdl = rdl * hidamp + old.r() * (1.0 - hidamp); - old.l() = ldl; - old.r() = rdl; + old.l = delay.l[(pos.l+delta.l)%(MAX_DELAY * SAMPLE_RATE)] = ldl * hidamp + old.l * (1.0 - hidamp); + old.r = delay.r[(pos.r+delta.r)%(MAX_DELAY * SAMPLE_RATE)] = rdl * hidamp + old.r * (1.0 - hidamp); - if(++kl >= dl) - kl = 0; - if(++kr >= dr) - kr = 0; + //increment + ++pos.l;// += delta.l; + ++pos.r;// += delta.r; + + //ensure that pos is still in bounds + pos.l %= MAX_DELAY * SAMPLE_RATE; + pos.r %= MAX_DELAY * SAMPLE_RATE; + + //adjust delay if needed + delta.l = (15*delta.l + ndelta.l)/16; + delta.r = (15*delta.r + ndelta.r)/16; } } @@ -117,7 +117,7 @@ void Echo::out(const Stereo &input) /* * Parameter control */ -void Echo::setvolume(const unsigned char &Pvolume) +void Echo::setvolume(unsigned char Pvolume) { this->Pvolume = Pvolume; @@ -132,45 +132,44 @@ void Echo::setvolume(const unsigned char &Pvolume) cleanup(); } -void Echo::setpanning(const unsigned char &Ppanning) +void Echo::setpanning(unsigned char Ppanning) { this->Ppanning = Ppanning; panning = (Ppanning + 0.5) / 127.0; } -void Echo::setdelay(const unsigned char &Pdelay) +void Echo::setdelay(unsigned char Pdelay) { - delay.setmVal(Pdelay); - //this->Pdelay=Pdelay; - //delay=1+(int)(Pdelay/127.0*SAMPLE_RATE*1.5);//0 .. 1.5 sec + this->Pdelay=Pdelay; + avgDelay=(Pdelay/127.0*1.5);//0 .. 1.5 sec initdelays(); } -void Echo::setlrdelay(const unsigned char &Plrdelay) +void Echo::setlrdelay(unsigned char Plrdelay) { REALTYPE tmp; this->Plrdelay = Plrdelay; tmp = - (pow(2, fabs(Plrdelay - 64.0) / 64.0 * 9) - 1.0) / 1000.0 * SAMPLE_RATE; + (pow(2, fabs(Plrdelay - 64.0) / 64.0 * 9) - 1.0) / 1000.0; if(Plrdelay < 64.0) tmp = -tmp; - lrdelay = (int) tmp; + lrdelay = tmp; initdelays(); } -void Echo::setlrcross(const unsigned char &Plrcross) +void Echo::setlrcross(unsigned char Plrcross) { this->Plrcross = Plrcross; lrcross = Plrcross / 127.0 * 1.0; } -void Echo::setfb(const unsigned char &Pfb) +void Echo::setfb(unsigned char Pfb) { this->Pfb = Pfb; fb = Pfb / 128.0; } -void Echo::sethidamp(const unsigned char &Phidamp) +void Echo::sethidamp(unsigned char Phidamp) { this->Phidamp = Phidamp; hidamp = 1.0 - Phidamp / 127.0; @@ -213,7 +212,7 @@ void Echo::setpreset(unsigned char npreset) } -void Echo::changepar(const int &npar, const unsigned char &value) +void Echo::changepar(int npar, unsigned char value) { switch(npar) { case 0: @@ -240,7 +239,7 @@ void Echo::changepar(const int &npar, const unsigned char &value) } } -unsigned char Echo::getpar(const int &npar) const +unsigned char Echo::getpar(int npar) const { switch(npar) { case 0: @@ -250,7 +249,7 @@ unsigned char Echo::getpar(const int &npar) const return Ppanning; break; case 2: - return delay.getmVal(); + return Pdelay; break; case 3: return Plrdelay; diff --git a/plugins/zynaddsubfx/src/Effects/Echo.h b/plugins/zynaddsubfx/src/Effects/Echo.h index 4dbe40925..8842bd85d 100644 --- a/plugins/zynaddsubfx/src/Effects/Echo.h +++ b/plugins/zynaddsubfx/src/Effects/Echo.h @@ -25,9 +25,8 @@ #include "../globals.h" #include "Effect.h" -#include "../Samples/AuSample.h" #include "../Misc/Stereo.h" -#include "../Controls/DelayCtl.h" +#include "../Samples/Sample.h" /**Echo Effect*/ class Echo:public Effect @@ -51,15 +50,7 @@ class Echo:public Effect */ ~Echo(); - /** - * Outputs the echo to efxoutl and efxoutr - * @param smpsl Sample from Left channel - * @param smpsr Sample from Right channel - * \todo try to figure out if smpsl should be const *const - * or not (It should be) - */ - void out(REALTYPE *const smpsl, REALTYPE *const smpr); - void out(const Stereo &input); + void out(const Stereo &input); /** * Sets the state of Echo to the specified preset @@ -81,7 +72,7 @@ class Echo:public Effect * @param npar number of chosen parameter * @param value the new value */ - void changepar(const int &npar, const unsigned char &value); + void changepar(int npar, unsigned char value); /** * Gets the specified parameter @@ -97,7 +88,7 @@ class Echo:public Effect * @param npar number of chosen parameter * @return value of parameter */ - unsigned char getpar(const int &npar) const; + unsigned char getpar(int npar) const; int getnumparams(); @@ -108,31 +99,39 @@ class Echo:public Effect void setdryonly(); private: //Parameters - char Pvolume; /**<#1 Volume or Dry/Wetness*/ + char Pvolume; /**<#1 Volume or Dry/Wetness*/ char Ppanning; /**<#2 Panning*/ - DelayCtl delay; /**<#3 Delay of the Echo*/ + char Pdelay; /**<#3 Delay of the Echo*/ char Plrdelay; /**<#4 L/R delay difference*/ char Plrcross; /**<#5 L/R Mixing*/ - char Pfb; /**<#6Feedback*/ - char Phidamp; /**<#7Dampening of the Echo*/ + char Pfb; /**<#6Feedback*/ + char Phidamp; /**<#7Dampening of the Echo*/ - void setvolume(const unsigned char &Pvolume); - void setpanning(const unsigned char &Ppanning); - void setdelay(const unsigned char &Pdelay); - void setlrdelay(const unsigned char &Plrdelay); - void setlrcross(const unsigned char &Plrcross); - void setfb(const unsigned char &Pfb); - void sethidamp(const unsigned char &Phidamp); + void setvolume(unsigned char Pvolume); + void setpanning(unsigned char Ppanning); + void setdelay(unsigned char Pdelay); + void setlrdelay(unsigned char Plrdelay); + void setlrcross(unsigned char Plrcross); + void setfb(unsigned char Pfb); + void sethidamp(unsigned char Phidamp); //Real Parameters - REALTYPE panning, lrcross, fb, hidamp; //needs better names - int dl, dr, lrdelay; //needs better names + REALTYPE panning, lrcross, fb, hidamp; + //Left/Right delay lengths + Stereo delayTime; + REALTYPE lrdelay; + REALTYPE avgDelay; void initdelays(); - Stereo delaySample; + //2 channel ring buffer + Stereo delay; Stereo old; - int kl, kr; + //position of reading/writing from delaysample + Stereo pos; + //step size for delay buffer + Stereo delta; + Stereo ndelta; }; #endif diff --git a/plugins/zynaddsubfx/src/Effects/Effect.cpp b/plugins/zynaddsubfx/src/Effects/Effect.cpp index 0a17ebdc4..ab44312ed 100644 --- a/plugins/zynaddsubfx/src/Effects/Effect.cpp +++ b/plugins/zynaddsubfx/src/Effects/Effect.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Effect.C - this class is inherited by the all effects(Reverb, Echo, ..) + Effect.cpp - this class is inherited by the all effects(Reverb, Echo, ..) Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -22,10 +22,15 @@ #include "Effect.h" - Effect::Effect(bool insertion_, REALTYPE *const efxoutl_, REALTYPE *const efxoutr_, FilterParams *filterpars_, const unsigned char &Ppreset_) :Ppreset(Ppreset_), efxoutl(efxoutl_), efxoutr(efxoutr_), - filterpars(filterpars_), insertion(insertion_) {} + filterpars(filterpars_), insertion(insertion_) +{} + +void Effect::out(REALTYPE *const smpsl, REALTYPE *const smpsr) +{ + out(Stereo(smpsl,smpsr)); +}; diff --git a/plugins/zynaddsubfx/src/Effects/Effect.h b/plugins/zynaddsubfx/src/Effects/Effect.h index 7f769ead8..eddbbba5c 100644 --- a/plugins/zynaddsubfx/src/Effects/Effect.h +++ b/plugins/zynaddsubfx/src/Effects/Effect.h @@ -26,6 +26,7 @@ #include "../Misc/Util.h" #include "../globals.h" #include "../Params/FilterParams.h" +#include "../Misc/Stereo.h" /**this class is inherited by the all effects(Reverb, Echo, ..)*/ @@ -56,12 +57,12 @@ class Effect /**Change parameter npar to value * @param npar chosen parameter * @param value chosen new value*/ - virtual void changepar(const int &npar, const unsigned char &value) = 0; + virtual void changepar(int npar, unsigned char value) = 0; /**Get the value of parameter npar * @param npar chosen parameter * @return the value of the parameter in an unsigned char or 0 if it * does not exist*/ - virtual unsigned char getpar(const int &npar) const = 0; + virtual unsigned char getpar(int npar) const = 0; /**Output result of effect based on the given buffers * * This method should result in the effect generating its results @@ -71,18 +72,19 @@ class Effect * @param smpsl Input buffer for the Left channel * @param smpsr Input buffer for the Right channel */ - virtual void out(REALTYPE *const smpsl, REALTYPE *const smpsr) = 0; + void out(REALTYPE *const smpsl, REALTYPE *const smpsr); + virtual void out(const Stereo &smp) = 0; /**Reset the state of the effect*/ virtual void cleanup() {} /**This is only used for EQ (for user interface)*/ virtual REALTYPE getfreqresponse(REALTYPE freq) { - return 0; + return freq; } unsigned char Ppreset; /***/ REALTYPE outvolume;/** +using namespace std; EffectMgr::EffectMgr(int insertion_, pthread_mutex_t *mutex_) :insertion(insertion_), diff --git a/plugins/zynaddsubfx/src/Effects/EffectMgr.h b/plugins/zynaddsubfx/src/Effects/EffectMgr.h index 2a1257707..29d6a7a71 100644 --- a/plugins/zynaddsubfx/src/Effects/EffectMgr.h +++ b/plugins/zynaddsubfx/src/Effects/EffectMgr.h @@ -37,7 +37,6 @@ #include "../Params/FilterParams.h" #include "../Params/Presets.h" - /**Effect manager, an interface betwen the program and effects*/ class EffectMgr:public Presets { diff --git a/plugins/zynaddsubfx/src/Effects/Phaser.cpp b/plugins/zynaddsubfx/src/Effects/Phaser.cpp index b3402b9af..39c514f44 100644 --- a/plugins/zynaddsubfx/src/Effects/Phaser.cpp +++ b/plugins/zynaddsubfx/src/Effects/Phaser.cpp @@ -1,9 +1,18 @@ /* + + Phaser.cpp - Phasing and Approximate digital model of an analog JFET phaser. + Analog modeling implemented by Ryan Billing aka Transmogrifox. ZynAddSubFX - a software synthesizer - Phaser.C - Phaser effect + Phaser.cpp - Phaser effect Copyright (C) 2002-2005 Nasca Octavian Paul + Copyright (C) 2009-2010 Ryan Billing + Copyright (C) 2010-2010 Mark McCurry Author: Nasca Octavian Paul + Ryan Billing + Mark McCurry + + DSP analog modeling theory & practice largely influenced by various CCRMA publications, particularly works by Julius O. Smith. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License @@ -21,89 +30,212 @@ */ #include +#include #include "Phaser.h" + +using namespace std; + #define PHASER_LFO_SHAPE 2 +#define ONE_ 0.99999f // To prevent LFO ever reaching 1.0 for filter stability purposes +#define ZERO_ 0.00001f // Same idea as above. Phaser::Phaser(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_) - :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), old(1), oldgain(0.0) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), xn1(NULL), yn1(NULL), diff(0.0), old(NULL), oldgain(0.0), + fb(0.0) { + analog_setup(); setpreset(Ppreset); cleanup(); } -Phaser::~Phaser() -{} +void Phaser::analog_setup() +{ + //model mismatch between JFET devices + offset[0] = -0.2509303f; + offset[1] = 0.9408924f; + offset[2] = 0.998f; + offset[3] = -0.3486182f; + offset[4] = -0.2762545f; + offset[5] = -0.5215785f; + offset[6] = 0.2509303f; + offset[7] = -0.9408924f; + offset[8] = -0.998f; + offset[9] = 0.3486182f; + offset[10] = 0.2762545f; + offset[11] = 0.5215785f; + barber = 0; //Deactivate barber pole phasing by default + + mis = 1.0f; + Rmin = 625.0f;// 2N5457 typical on resistance at Vgs = 0 + Rmax = 22000.0f;// Resistor parallel to FET + Rmx = Rmin/Rmax; + Rconst = 1.0f + Rmx; // Handle parallel resistor relationship + C = 0.00000005f; // 50 nF + CFs = (float) 2.0f*(float)SAMPLE_RATE*C; + invperiod = 1.0f / ((float) SOUND_BUFFER_SIZE); +} + +Phaser::~Phaser() +{ + if(xn1.l) + delete[] xn1.l; + if(yn1.l) + delete[] yn1.l; + if(xn1.r) + delete[] xn1.r; + if(yn1.r) + delete[] yn1.r; +} /* * Effect output */ -void Phaser::out(REALTYPE *smpsl, REALTYPE *smpsr) +void Phaser::out(const Stereo &input) { - int i, j; - REALTYPE lfol, lfor, lgain, rgain, tmp; - - lfo.effectlfoout(&lfol, &lfor); - lgain = lfol; - rgain = lfor; - lgain = (exp(lgain * PHASER_LFO_SHAPE) - 1) / (exp(PHASER_LFO_SHAPE) - 1.0); - rgain = (exp(rgain * PHASER_LFO_SHAPE) - 1) / (exp(PHASER_LFO_SHAPE) - 1.0); - - - lgain = 1.0 - phase * (1.0 - depth) - (1.0 - phase) * lgain * depth; - rgain = 1.0 - phase * (1.0 - depth) - (1.0 - phase) * rgain * depth; - - if(lgain > 1.0) - lgain = 1.0; + if(Panalog) + AnalogPhase(input); else - if(lgain < 0.0) - lgain = 0.0; - if(rgain > 1.0) - rgain = 1.0; - else - if(rgain < 0.0) - rgain = 0.0; + normalPhase(input); +} - for(i = 0; i < SOUND_BUFFER_SIZE; i++) { - REALTYPE x = (REALTYPE) i / SOUND_BUFFER_SIZE; - REALTYPE x1 = 1.0 - x; - REALTYPE gl = lgain * x + oldgain.left() * x1; - REALTYPE gr = rgain * x + oldgain.right() * x1; - REALTYPE inl = smpsl[i] * panning + fbl; - REALTYPE inr = smpsr[i] * (1.0 - panning) + fbr; +void Phaser::AnalogPhase(const Stereo &input) +{ + Stereo gain(0.0), lfoVal(0.0), mod(0.0), g(0.0), b(0.0), hpf(0.0); - //Left channel - for(j = 0; j < Pstages * 2; j++) { //Phasing routine - tmp = old.left()[j]; - old.left()[j] = gl * tmp + inl; - inl = tmp - gl *old.left()[j]; - } - //Right channel - for(j = 0; j < Pstages * 2; j++) { //Phasing routine - tmp = old.right()[j]; - old.right()[j] = gr * tmp + inr; - inr = tmp - gr *old.right()[j]; - } - //Left/Right crossing - REALTYPE l = inl; - REALTYPE r = inr; - inl = l * (1.0 - lrcross) + r * lrcross; - inr = r * (1.0 - lrcross) + l * lrcross; + lfo.effectlfoout(&lfoVal.l, &lfoVal.r); + mod.l = lfoVal.l*width + (depth - 0.5f); + mod.r = lfoVal.r*width + (depth - 0.5f); - fbl = inl * fb; - fbr = inr * fb; - efxoutl[i] = inl; - efxoutr[i] = inr; + mod.l = limit(mod.l, ZERO_, ONE_); + mod.r = limit(mod.r, ZERO_, ONE_); + + if(Phyper) { + //Triangle wave squared is approximately sin on bottom, tri on top + //Result is exponential sweep more akin to filter in synth with + //exponential generator circuitry. + mod.l *= mod.l; + mod.r *= mod.r; } - oldgain = Stereo(lgain, rgain); + //g.l,g.r is Vp - Vgs. Typical FET drain-source resistance follows constant/[1-sqrt(Vp - Vgs)] + mod.l = sqrtf(1.0f - mod.l); + mod.r = sqrtf(1.0f - mod.r); - if(Poutsub != 0) - for(i = 0; i < SOUND_BUFFER_SIZE; i++) { - efxoutl[i] *= -1.0; - efxoutr[i] *= -1.0; + diff.r = (mod.r - oldgain.r) * invperiod; + diff.l = (mod.l - oldgain.l) * invperiod; + + g = oldgain; + oldgain = mod; + + for (int i = 0; i < SOUND_BUFFER_SIZE; i++) { + g.l += diff.l;// Linear interpolation between LFO samples + g.r += diff.r; + + Stereo xn(input.l[i] * panning, + input.r[i] * (1.0f - panning)); + + if (barber) { + g.l = fmodf((g.l + 0.25f), ONE_); + g.r = fmodf((g.r + 0.25f), ONE_); } - ; + + xn.l = applyPhase(xn.l, g.l, fb.l, hpf.l, yn1.l, xn1.l); + xn.r = applyPhase(xn.r, g.r, fb.r, hpf.r, yn1.r, xn1.r); + + + fb.l = xn.l * feedback; + fb.r = xn.r * feedback; + efxoutl[i] = xn.l; + efxoutr[i] = xn.r; + } + + if(Poutsub) { + invSignal(efxoutl, SOUND_BUFFER_SIZE); + invSignal(efxoutr, SOUND_BUFFER_SIZE); + } +} + +REALTYPE Phaser::applyPhase(REALTYPE x, REALTYPE g, REALTYPE fb, + REALTYPE &hpf, REALTYPE *yn1, REALTYPE *xn1) +{ + for(int j = 0; j < Pstages; j++) { //Phasing routine + mis = 1.0f + offsetpct*offset[j]; + + //This is symmetrical. + //FET is not, so this deviates slightly, however sym dist. is + //better sounding than a real FET. + float d = (1.0f + 2.0f*(0.25f + g)*hpf*hpf*distortion) * mis; + Rconst = 1.0f + mis*Rmx; + + // This is 1/R. R is being modulated to control filter fc. + float b = (Rconst - g)/ (d*Rmin); + float gain = (CFs - b)/(CFs + b); + yn1[j] = gain * (x + yn1[j]) - xn1[j]; + + //high pass filter: + //Distortion depends on the high-pass part of the AP stage. + hpf = yn1[j] + (1.0f-gain)*xn1[j]; + + xn1[j] = x; + x = yn1[j]; + if (j==1) + x += fb; //Insert feedback after first phase stage + } + return x; +} +void Phaser::normalPhase(const Stereo &input) +{ + Stereo gain(0.0), lfoVal(0.0); + + lfo.effectlfoout(&lfoVal.l, &lfoVal.r); + gain.l = (exp(lfoVal.l * PHASER_LFO_SHAPE) - 1) / (exp(PHASER_LFO_SHAPE) - 1.0); + gain.r = (exp(lfoVal.r * PHASER_LFO_SHAPE) - 1) / (exp(PHASER_LFO_SHAPE) - 1.0); + + gain.l = 1.0 - phase * (1.0 - depth) - (1.0 - phase) * gain.l * depth; + gain.r = 1.0 - phase * (1.0 - depth) - (1.0 - phase) * gain.r * depth; + + gain.l = limit(gain.l, ZERO_, ONE_); + gain.r = limit(gain.r, ZERO_, ONE_); + + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE x = (REALTYPE) i / SOUND_BUFFER_SIZE; + REALTYPE x1 = 1.0 - x; + //TODO think about making panning an external feature + Stereo xn(input.l[i] * panning + fb.l, + input.r[i] * (1.0 - panning) + fb.r); + + Stereo g(gain.l * x + oldgain.l * x1, + gain.r * x + oldgain.r * x1); + + xn.l = applyPhase(xn.l, g.l, old.l); + xn.r = applyPhase(xn.r, g.r, old.r); + + //Left/Right crossing + crossover(xn.l, xn.r, lrcross); + + fb.l = xn.l * feedback; + fb.r = xn.r * feedback; + efxoutl[i] = xn.l; + efxoutr[i] = xn.r; + } + + oldgain = gain; + + if(Poutsub) { + invSignal(efxoutl, SOUND_BUFFER_SIZE); + invSignal(efxoutr, SOUND_BUFFER_SIZE); + } +} + +REALTYPE Phaser::applyPhase(REALTYPE x, REALTYPE g, REALTYPE *old) +{ + for(int j = 0; j < Pstages * 2; j++) { //Phasing routine + REALTYPE tmp = old[j]; + old[j] = g * tmp + x; + x = tmp - g *old[j]; + } + return x; } /* @@ -111,30 +243,35 @@ void Phaser::out(REALTYPE *smpsl, REALTYPE *smpsr) */ void Phaser::cleanup() { - fbl = 0.0; - fbr = 0.0; - oldgain = Stereo(0.0); - old.l().clear(); - old.r().clear(); + fb = oldgain = Stereo(0.0); + for(int i = 0; i < Pstages * 2; i++) { + old.l[i] = 0.0; + old.r[i] = 0.0; + } + for(int i = 0; i < Pstages; i++) { + xn1.l[i] = 0.0; + yn1.l[i] = 0.0; + xn1.r[i] = 0.0; + yn1.r[i] = 0.0; + } } /* * Parameter control */ -void Phaser::setdepth(const unsigned char &Pdepth) +void Phaser::setwidth(unsigned char Pwidth) { - this->Pdepth = Pdepth; - depth = (Pdepth / 127.0); + this->Pwidth = Pwidth; + width = ((float)Pwidth / 127.0f); } - -void Phaser::setfb(const unsigned char &Pfb) +void Phaser::setfb(unsigned char Pfb) { this->Pfb = Pfb; - fb = (Pfb - 64.0) / 64.1; + feedback = (float) (Pfb - 64) / 64.2f; } -void Phaser::setvolume(const unsigned char &Pvolume) +void Phaser::setvolume(unsigned char Pvolume) { this->Pvolume = Pvolume; outvolume = Pvolume / 127.0; @@ -144,52 +281,90 @@ void Phaser::setvolume(const unsigned char &Pvolume) volume = outvolume; } -void Phaser::setpanning(const unsigned char &Ppanning) +void Phaser::setpanning(unsigned char Ppanning) { this->Ppanning = Ppanning; - panning = Ppanning / 127.0; + panning = (float)Ppanning / 127.0; } -void Phaser::setlrcross(const unsigned char &Plrcross) +void Phaser::setlrcross(unsigned char Plrcross) { this->Plrcross = Plrcross; lrcross = Plrcross / 127.0; } -void Phaser::setstages(const unsigned char &Pstages) +void Phaser::setdistortion(unsigned char Pdistortion) { - if(Pstages >= MAX_PHASER_STAGES) - this->Pstages = MAX_PHASER_STAGES - 1; - else - this->Pstages = Pstages; - old = Stereo(Pstages * 2); + this->Pdistortion = Pdistortion; + distortion = (float)Pdistortion / 127.0f; +} + +void Phaser::setoffset(unsigned char Poffset) +{ + this->Poffset = Poffset; + offsetpct = (float)Poffset / 127.0f; +} + +void Phaser::setstages(unsigned char Pstages) +{ + if(xn1.l) + delete[] xn1.l; + if(yn1.l) + delete[] yn1.l; + if(xn1.r) + delete[] xn1.r; + if(yn1.r) + delete[] yn1.r; + + + this->Pstages = min(MAX_PHASER_STAGES, (int)Pstages); + + old = Stereo(new REALTYPE[Pstages * 2], + new REALTYPE[Pstages * 2]); + + xn1 = Stereo(new REALTYPE[Pstages], + new REALTYPE[Pstages]); + + yn1 = Stereo(new REALTYPE[Pstages], + new REALTYPE[Pstages]); + cleanup(); } -void Phaser::setphase(const unsigned char &Pphase) +void Phaser::setphase(unsigned char Pphase) { this->Pphase = Pphase; phase = (Pphase / 127.0); } +void Phaser::setdepth(unsigned char Pdepth) +{ + this->Pdepth = Pdepth; + depth = (float)(Pdepth) / 127.0f; +} + void Phaser::setpreset(unsigned char npreset) { - const int PRESET_SIZE = 12; - const int NUM_PRESETS = 6; + const int PRESET_SIZE = 15; + const int NUM_PRESETS = 12; unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { - //Phaser1 - {64, 64, 36, 0, 0, 64, 110, 64, 1, 0, 0, 20}, - //Phaser2 - {64, 64, 35, 0, 0, 88, 40, 64, 3, 0, 0, 20}, - //Phaser3 - {64, 64, 31, 0, 0, 66, 68, 107, 2, 0, 0, 20}, - //Phaser4 - {39, 64, 22, 0, 0, 66, 67, 10, 5, 0, 1, 20}, - //Phaser5 - {64, 64, 20, 0, 1, 110, 67, 78, 10, 0, 0, 20}, - //Phaser6 - {64, 64, 53, 100, 0, 58, 37, 78, 3, 0, 0, 20} + //Phaser + //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + {64, 64, 36, 0, 0, 64, 110, 64, 1, 0, 0, 20, 0, 0, 0}, + {64, 64, 35, 0, 0, 88, 40, 64, 3, 0, 0, 20, 0, 0, 0}, + {64, 64, 31, 0, 0, 66, 68, 107, 2, 0, 0, 20, 0, 0, 0}, + {39, 64, 22, 0, 0, 66, 67, 10, 5, 0, 1, 20, 0, 0, 0}, + {64, 64, 20, 0, 1, 110, 67, 78, 10, 0, 0, 20, 0, 0, 0}, + {64, 64, 53, 100, 0, 58, 37, 78, 3, 0, 0, 20, 0, 0, 0}, + //APhaser + //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + {64, 64, 14, 0, 1, 64, 64, 40, 4, 10, 0, 110, 1, 20, 1}, + {64, 64, 14, 5, 1, 64, 70, 40, 6, 10, 0, 110, 1, 20, 1}, + {64, 64, 9, 0, 0, 64, 60, 40, 8, 10, 0, 40, 0, 20, 1}, + {64, 64, 14, 10, 0, 64, 45, 80, 7, 10, 1, 110, 1, 20, 1}, + {25, 64, 127, 10, 0, 64, 25, 16, 8, 100, 0, 25, 0, 20, 1}, + {64, 64, 1, 10, 1, 64, 70, 40, 12, 10, 0, 110, 1, 20, 1} }; if(npreset >= NUM_PRESETS) npreset = NUM_PRESETS - 1; @@ -199,96 +374,100 @@ void Phaser::setpreset(unsigned char npreset) } -void Phaser::changepar(const int &npar, const unsigned char &value) +void Phaser::changepar(int npar, unsigned char value) { switch(npar) { - case 0: - setvolume(value); - break; - case 1: - setpanning(value); - break; - case 2: - lfo.Pfreq = value; - lfo.updateparams(); - break; - case 3: - lfo.Prandomness = value; - lfo.updateparams(); - break; - case 4: - lfo.PLFOtype = value; - lfo.updateparams(); - break; - case 5: - lfo.Pstereo = value; - lfo.updateparams(); - break; - case 6: - setdepth(value); - break; - case 7: - setfb(value); - break; - case 8: - setstages(value); - break; - case 9: - setlrcross(value); - break; - case 10: - if(value > 1) - Poutsub = 1; - else - Poutsub = value; - break; - case 11: - setphase(value); - break; + case 0: + setvolume(value); + break; + case 1: + setpanning(value); + break; + case 2: + lfo.Pfreq = value; + lfo.updateparams(); + break; + case 3: + lfo.Prandomness = value; + lfo.updateparams(); + break; + case 4: + lfo.PLFOtype = value; + lfo.updateparams(); + barber = (2 == value); + break; + case 5: + lfo.Pstereo = value; + lfo.updateparams(); + break; + case 6: + setdepth(value); + break; + case 7: + setfb(value); + break; + case 8: + setstages(value); + break; + case 9: + setlrcross(value); + setoffset(value); + break; + case 10: + Poutsub = min((int)value,1); + break; + case 11: + setphase(value); + setwidth(value); + break; + case 12: + Phyper = min((int)value, 1); + break; + case 13: + setdistortion(value); + break; + case 14: + Panalog = value; + break; } } -unsigned char Phaser::getpar(const int &npar) const +unsigned char Phaser::getpar(int npar) const { switch(npar) { - case 0: - return Pvolume; - break; - case 1: - return Ppanning; - break; - case 2: - return lfo.Pfreq; - break; - case 3: - return lfo.Prandomness; - break; - case 4: - return lfo.PLFOtype; - break; - case 5: - return lfo.Pstereo; - break; - case 6: - return Pdepth; - break; - case 7: - return Pfb; - break; - case 8: - return Pstages; - break; - case 9: - return Plrcross; - break; - case 10: - return Poutsub; - break; - case 11: - return Pphase; - break; - default: - return 0; + case 0: + return Pvolume; + case 1: + return Ppanning; + case 2: + return lfo.Pfreq; + case 3: + return lfo.Prandomness; + case 4: + return lfo.PLFOtype; + case 5: + return lfo.Pstereo; + case 6: + return Pdepth; + case 7: + return Pfb; + case 8: + return Pstages; + case 9: + return Plrcross; + return Poffset; + case 10: + return Poutsub; + case 11: + return Pphase; + return Pwidth; + case 12: + return Phyper; + case 13: + return Pdistortion; + case 14: + return Panalog; + default: + return 0; } } - diff --git a/plugins/zynaddsubfx/src/Effects/Phaser.h b/plugins/zynaddsubfx/src/Effects/Phaser.h index 30370a8c6..f5ee1b03f 100644 --- a/plugins/zynaddsubfx/src/Effects/Phaser.h +++ b/plugins/zynaddsubfx/src/Effects/Phaser.h @@ -3,7 +3,11 @@ Phaser.h - Phaser effect Copyright (C) 2002-2005 Nasca Octavian Paul + Copyright (C) 2009-2010 Ryan Billing + Copyright (C) 2010-2010 Mark McCurry Author: Nasca Octavian Paul + Ryan Billing + Mark McCurry This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License @@ -23,53 +27,77 @@ #ifndef PHASER_H #define PHASER_H #include "../globals.h" -#include "../Misc/Stereo.h" -#include "../Samples/AuSample.h" #include "Effect.h" #include "EffectLFO.h" #define MAX_PHASER_STAGES 12 -/**Phaser Effect*/ + class Phaser:public Effect { public: - Phaser(const int &insetion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); + Phaser(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); ~Phaser(); - void out(REALTYPE *smpsl, REALTYPE *smpsr); + void out(const Stereo &input); void setpreset(unsigned char npreset); - void changepar(const int &npar, const unsigned char &value); - unsigned char getpar(const int &npar) const; + void changepar(int npar, unsigned char value); + unsigned char getpar(int npar) const; void cleanup(); - void setdryonly(); private: - //Parametrii Phaser - EffectLFO lfo; /** old; - //REALTYPE oldlgain,oldrgain; - Stereo oldgain; + //Internal Variables + bool barber; //Barber pole phasing flag + REALTYPE distortion, width, offsetpct; + REALTYPE panning, feedback, depth, lrcross, phase; + Stereo old, xn1, yn1; + Stereo diff, oldgain, fb; + REALTYPE invperiod; + REALTYPE offset[12]; + + float mis; + float Rmin; // 3N5457 typical on resistance at Vgs = 0 + float Rmax; // Resistor parallel to FET + float Rmx; // Rmin/Rmax to avoid division in loop + float Rconst; // Handle parallel resistor relationship + float C; // Capacitor + float CFs; // A constant derived from capacitor and resistor relationships + + void analog_setup(); + void AnalogPhase(const Stereo &input); + //analog case + REALTYPE applyPhase(REALTYPE x, REALTYPE g, REALTYPE fb, + REALTYPE &hpf, REALTYPE *yn1, REALTYPE *xn1); + + void normalPhase(const Stereo &input); + REALTYPE applyPhase(REALTYPE x, REALTYPE g, REALTYPE *old); }; #endif diff --git a/plugins/zynaddsubfx/src/Effects/Reverb.cpp b/plugins/zynaddsubfx/src/Effects/Reverb.cpp index 27b0a554b..419cee4a6 100644 --- a/plugins/zynaddsubfx/src/Effects/Reverb.cpp +++ b/plugins/zynaddsubfx/src/Effects/Reverb.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Reverb.C - Reverberation effect + Reverb.cpp - Reverberation effect Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -165,15 +165,14 @@ void Reverb::processmono(int ch, REALTYPE *output) /* * Effect output */ -void Reverb::out(REALTYPE *smps_l, REALTYPE *smps_r) +void Reverb::out(const Stereo &smp) { int i; if((Pvolume == 0) && (insertion != 0)) return; for(i = 0; i < SOUND_BUFFER_SIZE; i++) - inputbuf[i] = (smps_l[i] + smps_r[i]) / 2.0; - ; + inputbuf[i] = (smp.l[i] + smp.r[i]) / 2.0; if(idelay != NULL) { for(i = 0; i < SOUND_BUFFER_SIZE; i++) { @@ -184,7 +183,6 @@ void Reverb::out(REALTYPE *smps_l, REALTYPE *smps_r) idelayk++; if(idelayk >= idelaylen) idelayk = 0; - ; } } @@ -215,7 +213,7 @@ void Reverb::out(REALTYPE *smps_l, REALTYPE *smps_r) /* * Parameter control */ -void Reverb::setvolume(const unsigned char &Pvolume) +void Reverb::setvolume(unsigned char Pvolume) { this->Pvolume = Pvolume; if(insertion == 0) { @@ -229,13 +227,13 @@ void Reverb::setvolume(const unsigned char &Pvolume) } } -void Reverb::setpan(const unsigned char &Ppan) +void Reverb::setpan(unsigned char Ppan) { this->Ppan = Ppan; pan = (REALTYPE)Ppan / 127.0; } -void Reverb::settime(const unsigned char &Ptime) +void Reverb::settime(unsigned char Ptime) { int i; REALTYPE t; @@ -246,7 +244,6 @@ void Reverb::settime(const unsigned char &Ptime) combfb[i] = -exp((REALTYPE)comblen[i] / (REALTYPE)SAMPLE_RATE * log(0.001) / t); //the feedback is negative because it removes the DC - ; } void Reverb::setlohidamp(unsigned char Plohidamp) @@ -271,7 +268,7 @@ void Reverb::setlohidamp(unsigned char Plohidamp) } } -void Reverb::setidelay(const unsigned char &Pidelay) +void Reverb::setidelay(unsigned char Pidelay) { REALTYPE delay; this->Pidelay = Pidelay; @@ -290,13 +287,13 @@ void Reverb::setidelay(const unsigned char &Pidelay) } } -void Reverb::setidelayfb(const unsigned char &Pidelayfb) +void Reverb::setidelayfb(unsigned char Pidelayfb) { this->Pidelayfb = Pidelayfb; idelayfb = Pidelayfb / 128.0; } -void Reverb::sethpf(const unsigned char &Phpf) +void Reverb::sethpf(unsigned char Phpf) { this->Phpf = Phpf; if(Phpf == 0) { //No HighPass @@ -313,7 +310,7 @@ void Reverb::sethpf(const unsigned char &Phpf) } } -void Reverb::setlpf(const unsigned char &Plpf) +void Reverb::setlpf(unsigned char Plpf) { this->Plpf = Plpf; if(Plpf == 127) { //No LowPass @@ -405,7 +402,7 @@ void Reverb::settype(unsigned char Ptype) } } -void Reverb::setroomsize(const unsigned char &Proomsize) +void Reverb::setroomsize(unsigned char Proomsize) { this->Proomsize = Proomsize; if(Proomsize == 0) @@ -418,7 +415,7 @@ void Reverb::setroomsize(const unsigned char &Proomsize) settype(Ptype); } -void Reverb::setbandwidth(const unsigned char &Pbandwidth) { +void Reverb::setbandwidth(unsigned char Pbandwidth) { this->Pbandwidth = Pbandwidth; REALTYPE v = Pbandwidth / 127.0; if(bandwidth) @@ -468,7 +465,7 @@ void Reverb::setpreset(unsigned char npreset) } -void Reverb::changepar(const int &npar, const unsigned char &value) +void Reverb::changepar(int npar, unsigned char value) { switch(npar) { case 0: @@ -511,7 +508,7 @@ void Reverb::changepar(const int &npar, const unsigned char &value) } } -unsigned char Reverb::getpar(const int &npar) const +unsigned char Reverb::getpar(int npar) const { switch(npar) { case 0: diff --git a/plugins/zynaddsubfx/src/Effects/Reverb.h b/plugins/zynaddsubfx/src/Effects/Reverb.h index d94f0bcef..e84c56d88 100644 --- a/plugins/zynaddsubfx/src/Effects/Reverb.h +++ b/plugins/zynaddsubfx/src/Effects/Reverb.h @@ -40,12 +40,12 @@ class Reverb:public Effect public: Reverb(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); ~Reverb(); - void out(REALTYPE *smps_l, REALTYPE *smps_r); + void out(const Stereo &smp); void cleanup(); void setpreset(unsigned char npreset); - void changepar(const int &npar, const unsigned char &value); - unsigned char getpar(const int &npar) const; + void changepar(int npar, unsigned char value); + unsigned char getpar(int npar) const; private: //Parametrii @@ -90,17 +90,17 @@ class Reverb:public Effect unsigned char Pbandwidth; //parameter control - void setvolume(const unsigned char &Pvolume); - void setpan(const unsigned char &Ppan); - void settime(const unsigned char &Ptime); + void setvolume(unsigned char Pvolume); + void setpan(unsigned char Ppan); + void settime(unsigned char Ptime); void setlohidamp(unsigned char Plohidamp); - void setidelay(const unsigned char &Pidelay); - void setidelayfb(const unsigned char &Pidelayfb); - void sethpf(const unsigned char &Phpf); - void setlpf(const unsigned char &Plpf); + void setidelay(unsigned char Pidelay); + void setidelayfb(unsigned char Pidelayfb); + void sethpf(unsigned char Phpf); + void setlpf(unsigned char Plpf); void settype(unsigned char Ptype); - void setroomsize(const unsigned char &Proomsize); - void setbandwidth(const unsigned char &Pbandwidth); + void setroomsize(unsigned char Proomsize); + void setbandwidth(unsigned char Pbandwidth); REALTYPE pan, erbalance; //Parameters diff --git a/plugins/zynaddsubfx/src/Input/ALSAMidiIn.cpp b/plugins/zynaddsubfx/src/Input/ALSAMidiIn.cpp index 10f8e2811..d50795dad 100644 --- a/plugins/zynaddsubfx/src/Input/ALSAMidiIn.cpp +++ b/plugins/zynaddsubfx/src/Input/ALSAMidiIn.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - ALSAMidiIn.C - Midi input for ALSA (this creates an ALSA virtual port) + ALSAMidiIn.cpp - Midi input for ALSA (this creates an ALSA virtual port) Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Input/MidiIn.cpp b/plugins/zynaddsubfx/src/Input/MidiIn.cpp index 90df75d95..3d7c5b230 100644 --- a/plugins/zynaddsubfx/src/Input/MidiIn.cpp +++ b/plugins/zynaddsubfx/src/Input/MidiIn.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - MidiIn.C - This class is inherited by all the Midi input classes + MidiIn.cpp - This class is inherited by all the Midi input classes Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Input/NULLMidiIn.cpp b/plugins/zynaddsubfx/src/Input/NULLMidiIn.cpp index 22ee76d75..a9c13acb3 100644 --- a/plugins/zynaddsubfx/src/Input/NULLMidiIn.cpp +++ b/plugins/zynaddsubfx/src/Input/NULLMidiIn.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - NULLMidiIn.C - a dummy Midi port + NULLMidiIn.cpp - a dummy Midi port Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Input/OSSMidiIn.cpp b/plugins/zynaddsubfx/src/Input/OSSMidiIn.cpp index b278ae6bf..5a20fb930 100644 --- a/plugins/zynaddsubfx/src/Input/OSSMidiIn.cpp +++ b/plugins/zynaddsubfx/src/Input/OSSMidiIn.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - OSSMidiIn.C - Midi input for Open Sound System + OSSMidiIn.cpp - Midi input for Open Sound System Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Input/WINMidiIn.cpp b/plugins/zynaddsubfx/src/Input/WINMidiIn.cpp index e8462457d..65974eec1 100644 --- a/plugins/zynaddsubfx/src/Input/WINMidiIn.cpp +++ b/plugins/zynaddsubfx/src/Input/WINMidiIn.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - WINMidiIn.C - Midi input for Windows + WINMidiIn.cpp - Midi input for Windows Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Misc/Bank.h b/plugins/zynaddsubfx/src/Misc/Bank.h index 81acc3dec..aa3594648 100644 --- a/plugins/zynaddsubfx/src/Misc/Bank.h +++ b/plugins/zynaddsubfx/src/Misc/Bank.h @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Bank.C - Instrument Bank + Bank.h - Instrument Bank Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Misc/CMakeLists.txt b/plugins/zynaddsubfx/src/Misc/CMakeLists.txt index 877cd54a6..8b883f379 100644 --- a/plugins/zynaddsubfx/src/Misc/CMakeLists.txt +++ b/plugins/zynaddsubfx/src/Misc/CMakeLists.txt @@ -8,9 +8,13 @@ set(zynaddsubfx_misc_SRCS Microtonal.cpp Part.cpp Util.cpp - XMLwrapper.cpp + QtXmlWrapper.cpp ) +if (LASH_FOUND) + set(zynaddsubfx_misc_SRCS ${zynaddsubfx_misc_SRCS} LASHClient.cpp) +endif() + add_library(zynaddsubfx_misc STATIC ${zynaddsubfx_misc_SRCS} ) diff --git a/plugins/zynaddsubfx/src/Misc/Config.cpp b/plugins/zynaddsubfx/src/Misc/Config.cpp index aa996f38a..a58f64dc6 100644 --- a/plugins/zynaddsubfx/src/Misc/Config.cpp +++ b/plugins/zynaddsubfx/src/Misc/Config.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Config.C - Configuration file functions + Config.cpp - Configuration file functions Copyright (C) 2003-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Misc/Dump.cpp b/plugins/zynaddsubfx/src/Misc/Dump.cpp index 4c13c9464..492cf57ed 100644 --- a/plugins/zynaddsubfx/src/Misc/Dump.cpp +++ b/plugins/zynaddsubfx/src/Misc/Dump.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Dump.C - It dumps the notes to a text file + Dump.cpp - It dumps the notes to a text file Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Misc/LASHClient.cpp b/plugins/zynaddsubfx/src/Misc/LASHClient.cpp index a21461f29..292037791 100644 --- a/plugins/zynaddsubfx/src/Misc/LASHClient.cpp +++ b/plugins/zynaddsubfx/src/Misc/LASHClient.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - LASHClient.C - LASH support + LASHClient.cpp - LASH support Copyright (C) 2006-2009 Lars Luthman Author: Lars Luthman diff --git a/plugins/zynaddsubfx/src/Misc/Master.cpp b/plugins/zynaddsubfx/src/Misc/Master.cpp index d0c7648c6..fa5e1b003 100644 --- a/plugins/zynaddsubfx/src/Misc/Master.cpp +++ b/plugins/zynaddsubfx/src/Misc/Master.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Master.C - It sends Midi Messages to Parts, receives samples from parts, + Master.cpp - It sends Midi Messages to Parts, receives samples from parts, process them with system/insertion effects and mix them Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Misc/Microtonal.cpp b/plugins/zynaddsubfx/src/Misc/Microtonal.cpp index e84ee8e64..1d327d209 100644 --- a/plugins/zynaddsubfx/src/Misc/Microtonal.cpp +++ b/plugins/zynaddsubfx/src/Misc/Microtonal.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Microtonal.C - Tuning settings and microtonal capabilities + Microtonal.cpp - Tuning settings and microtonal capabilities Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Misc/Part.cpp b/plugins/zynaddsubfx/src/Misc/Part.cpp index 2f8dfe7ba..3830fc630 100644 --- a/plugins/zynaddsubfx/src/Misc/Part.cpp +++ b/plugins/zynaddsubfx/src/Misc/Part.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Part.C - Part implementation + Part.cpp - Part implementation Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -249,7 +249,7 @@ void Part::NoteOn(unsigned char note, if(Ppolymode != 0) { fprintf( stderr, - "ZynAddSubFX WARNING: Poly and Legato modes are both On, that should not happen ! ... Disabling Legato mode ! - (Part.C::NoteOn(..))\n"); + "ZynAddSubFX WARNING: Poly and Legato modes are both On, that should not happen ! ... Disabling Legato mode ! - (Part.cpp::NoteOn(..))\n"); Plegatomode = 0; } else { @@ -293,7 +293,7 @@ void Part::NoteOn(unsigned char note, //test fprintf(stderr, "%s", - "NOTES TOO MANY (> POLIPHONY) - (Part.C::NoteOn(..))\n"); + "NOTES TOO MANY (> POLIPHONY) - (Part.cpp::NoteOn(..))\n"); else { //start the note partnote[pos].status = KEY_PLAYING; diff --git a/plugins/zynaddsubfx/src/Misc/QtXmlWrapper.cpp b/plugins/zynaddsubfx/src/Misc/QtXmlWrapper.cpp new file mode 100644 index 000000000..4cac88171 --- /dev/null +++ b/plugins/zynaddsubfx/src/Misc/QtXmlWrapper.cpp @@ -0,0 +1,556 @@ +/* + * QtXmlWrapper.cpp - a QtXml based XML backend for ZynAddSubxFX + * + * Copyright (c) 2009 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +/* File derived from QtXmlWrapper.C: */ +/* + ZynAddSubFX - a software synthesizer + + QtXmlWrapper.C - XML wrapper + Copyright (C) 2003-2005 Nasca Octavian Paul + Copyright (C) 2009-2009 Mark McCurry + Author: Nasca Octavian Paul + Mark McCurry + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include +#include "QtXmlWrapper.h" +#include +#include +#include +#include +#include "lmmsconfig.h" +#include "../globals.h" +#include "Util.h" + + +struct XmlData +{ + XmlData() : + m_doc( "ZynAddSubFX-data" ) + { + } + QDomDocument m_doc; + QDomElement m_node; + QDomElement m_info; + + QDomElement addparams( const char *name, unsigned int params, ... ); +} ; + + + +QtXmlWrapper::QtXmlWrapper() : + d( new XmlData ) +{ + version.Major = 2; + version.Minor = 4; + version.Revision = 1; + + minimal = true; + + d->m_node = d->m_doc.createElement( "ZynAddSubFX-data" ); + d->m_node.setAttribute( "version-major", QString::number( version.Major ) ); + d->m_node.setAttribute( "version-minor", QString::number( version.Minor ) ); + d->m_node.setAttribute( "version-revision", QString::number( version.Revision ) ); + d->m_node.setAttribute( "ZynAddSubFX-author", "Nasca Octavian Paul" ); + d->m_doc.appendChild( d->m_node ); + + //make the empty branch that will contain the information parameters + d->m_info = d->addparams("INFORMATION", 0); + + //save zynaddsubfx specifications + beginbranch("BASE_PARAMETERS"); + addpar("max_midi_parts", NUM_MIDI_PARTS); + addpar("max_kit_items_per_instrument", NUM_KIT_ITEMS); + + addpar("max_system_effects", NUM_SYS_EFX); + addpar("max_insertion_effects", NUM_INS_EFX); + addpar("max_instrument_effects", NUM_PART_EFX); + + addpar("max_addsynth_voices", NUM_VOICES); + endbranch(); +} + + + + +QtXmlWrapper::~QtXmlWrapper() +{ + delete d; +} + + + + +void QtXmlWrapper::setPadSynth(bool enabled) +{ + /**@bug this might create multiple nodes when only one is needed*/ + QDomElement oldNode = d->m_node; + d->m_node = d->m_info; + //Info storing + addparbool("PADsynth_used", enabled); + d->m_node = oldNode; +} + +QDomElement findElement( QDomElement root, const QString & tagname, const QString & attrname, + const QString & attrval ) +{ + QDomNodeList list = root.elementsByTagName( tagname ); + for( int i = 0; i < list.size(); ++i ) + { + QDomNode n = list.at( i ); + if( n.isElement() ) + { + QDomElement e = n.toElement(); + if( e.hasAttribute( attrname ) && e.attribute( attrname ) == attrval ) + { + return e; + } + } + } + + return QDomElement(); +} + + + + +bool QtXmlWrapper::hasPadSynth() const +{ + /**Right now this has a copied implementation of setparbool, so this should + * be reworked as XMLwrapper evolves*/ + QDomElement tmp = d->m_doc.elementsByTagName( "INFORMATION" ).at( 0 ).toElement(); + QDomElement parameter = findElement( tmp, "par_bool", "name", "PADsynth_used" ); + if( !parameter.isNull() ) + { + const QString val = parameter.attribute( "value" ).toLower(); + return val[0] == 'y'; + } + return false; +} + + +/* SAVE XML members */ + +int QtXmlWrapper::saveXMLfile(const std::string &filename) const +{ + char *xmldata = getXMLdata(); + if(xmldata == NULL) + return -2; + + int compression = config.cfg.GzipCompression; + int result = dosavefile(filename.c_str(), compression, xmldata); + + delete[] xmldata; + return result; +} + + +char *QtXmlWrapper::getXMLdata() const +{ + QString xml = d->m_doc.toString( 1 ); + return qstrdup( xml.toUtf8().constData() ); +} + + +int QtXmlWrapper::dosavefile(const char *filename, + int compression, + const char *xmldata) const +{ + if(compression == 0) { + FILE *file; + file = fopen(filename, "w"); + if(file == NULL) + return -1; + fputs(xmldata, file); + fclose(file); + } + else { + if(compression > 9) + compression = 9; + if(compression < 1) + compression = 1; + char options[10]; + snprintf(options, 10, "wb%d", compression); + + gzFile gzfile; + gzfile = gzopen(filename, options); + if(gzfile == NULL) + return -1; + gzputs(gzfile, xmldata); + gzclose(gzfile); + } + + return 0; +} + + + +void QtXmlWrapper::addpar(const std::string &name, int val) +{ + d->addparams("par", 2, "name", name.c_str(), "value", stringFrom( + val).c_str()); +} + +void QtXmlWrapper::addparreal(const std::string &name, REALTYPE val) +{ + d->addparams("par_real", 2, "name", name.c_str(), "value", + stringFrom(val).c_str()); +} + +void QtXmlWrapper::addparbool(const std::string &name, int val) +{ + if(val != 0) + d->addparams("par_bool", 2, "name", name.c_str(), "value", "yes"); + else + d->addparams("par_bool", 2, "name", name.c_str(), "value", "no"); +} + +void QtXmlWrapper::addparstr(const std::string &name, const std::string &val) +{ + QDomElement e = d->m_doc.createElement( "string" ); + e.setAttribute( "name", name.c_str() ); + e.appendChild( d->m_doc.createTextNode( val.c_str() ) ); + d->m_node.appendChild( e ); +} + + +void QtXmlWrapper::beginbranch(const std::string &name) +{ + d->m_node = d->addparams(name.c_str(), 0); +} + +void QtXmlWrapper::beginbranch(const std::string &name, int id) +{ + d->m_node = d->addparams(name.c_str(), 1, "id", stringFrom(id).c_str()); +} + +void QtXmlWrapper::endbranch() +{ + d->m_node = d->m_node.parentNode().toElement(); +} + + + +/* LOAD XML members */ + +int QtXmlWrapper::loadXMLfile(const std::string &filename) +{ + const char *xmldata = doloadfile(filename.c_str()); + if(xmldata == NULL) + { + qDebug() << "QtXmlWrapper::loadXMLfile(): empty data"; + return -1; //the file could not be loaded or uncompressed + } + + QByteArray b( xmldata ); + if( b[0] != '<' ) + { + // remove first blank line + b.remove( 0, +#ifdef LMMS_BUILD_WIN32 + 2 +#else + 1 +#endif + ); + } + + if( !d->m_doc.setContent( b ) ) + { + qDebug() << "QtXmlWrapper::loadXMLfile(): could not set document content"; + delete[] xmldata; + return -2; + } + delete[] xmldata; + + d->m_node = d->m_doc.elementsByTagName( "ZynAddSubFX-data" ).at( 0 ).toElement(); + if( d->m_node.isNull() || !d->m_node.isElement() ) + { + qDebug() << "QtXmlWrapper::loadXMLfile(): missing root node"; + return -3; //the XML doesnt embbed zynaddsubfx data + } + QDomElement root = d->m_node.toElement(); + //fetch version information + version.Major = root.attribute( "version-major").toInt(); + version.Minor = root.attribute( "version-minor").toInt(); + version.Revision = root.attribute( "version-revision").toInt(); + + return 0; +} + + +char *QtXmlWrapper::doloadfile(const std::string &filename) const +{ + char *xmldata = NULL; + gzFile gzfile = gzopen(filename.c_str(), "rb"); + + if(gzfile != NULL) { //The possibly compressed file opened + std::stringstream strBuf; //reading stream + const int bufSize = 500; //fetch size + char fetchBuf[bufSize + 1]; //fetch buffer + int read = 0; //chars read in last fetch + + fetchBuf[bufSize] = 0; //force null termination + + while(bufSize == (read = gzread(gzfile, fetchBuf, bufSize))) + strBuf << fetchBuf; + + fetchBuf[read] = 0; //Truncate last partial read + strBuf << fetchBuf; + + gzclose(gzfile); + + //Place data in output format + std::string tmp = strBuf.str(); + xmldata = new char[tmp.size() + 1]; + strncpy(xmldata, tmp.c_str(), tmp.size() + 1); + } + + return xmldata; +} + +bool QtXmlWrapper::putXMLdata(const char *xmldata) +{ + d->m_doc.setContent( QString::fromUtf8( xmldata ) ); + + d->m_node = d->m_doc.elementsByTagName( "ZynAddSubFX-data" ).at( 0 ).toElement(); + if( d->m_node.isNull() ) + { + return false; + } + + return true; +} + + + +int QtXmlWrapper::enterbranch(const std::string &name) +{ + QDomElement tmp = d->m_node.firstChildElement( name.c_str() ); + if( tmp.isNull() ) + { + return 0; + } + + d->m_node = tmp; + + return 1; +} + +int QtXmlWrapper::enterbranch(const std::string &name, int id) +{ + QDomElement tmp = findElement( d->m_node, name.c_str(), + "id", QString::number( id ) ); + if( tmp.isNull() ) + { + return 0; + } + + d->m_node = tmp; + + return 1; +} + + +void QtXmlWrapper::exitbranch() +{ + d->m_node = d->m_node.parentNode().toElement(); +} + + +int QtXmlWrapper::getbranchid(int min, int max) const +{ + if( !d->m_node.isElement() ) + { + return min; + } + QDomElement tmp = d->m_node.toElement(); + if( !tmp.hasAttribute( "id" ) ) + { + return min; + } + int id = tmp.attribute( "id" ).toInt(); + if((min == 0) && (max == 0)) + return id; + + if(id < min) + id = min; + else + if(id > max) + id = max; + + return id; +} + +int QtXmlWrapper::getpar(const std::string &name, int defaultpar, int min, + int max) const +{ + QDomElement tmp = findElement( d->m_node, "par", "name", name.c_str() ); + if( tmp.isNull() || !tmp.hasAttribute( "value" ) ) + { + return defaultpar; + } + + int val = tmp.attribute( "value" ).toInt(); + if(val < min) + val = min; + else + if(val > max) + val = max; + + return val; +} + +int QtXmlWrapper::getpar127(const std::string &name, int defaultpar) const +{ + return getpar(name, defaultpar, 0, 127); +} + +int QtXmlWrapper::getparbool(const std::string &name, int defaultpar) const +{ + QDomElement tmp = findElement( d->m_node, "par_bool", "name", name.c_str() ); + if( tmp.isNull() || !tmp.hasAttribute( "value" ) ) + { + return defaultpar; + } + + const QString val = tmp.attribute( "value" ).toLower(); + if( val[0] == 'y' ) + { + return 1; + } + return 0; +} + +void QtXmlWrapper::getparstr(const std::string &name, char *par, int maxstrlen) const +{ + ZERO(par, maxstrlen); + QDomNode tmp = findElement( d->m_node, "string", "name", name.c_str() ); + if( tmp.isNull() || !tmp.hasChildNodes() ) + { + return; + } + + tmp = tmp.firstChild(); + if( tmp.nodeType() == QDomNode::ElementNode ) + { + snprintf(par, maxstrlen, "%s", tmp.toElement().tagName().toUtf8().constData() ); + return; + } + if( tmp.nodeType() == QDomNode::TextNode ) + { + snprintf(par, maxstrlen, "%s", tmp.toText().data().toUtf8().constData() ); + return; + } +} + +std::string QtXmlWrapper::getparstr(const std::string &name, + const std::string &defaultpar) const +{ + QDomNode tmp = findElement( d->m_node, "string", "name", name.c_str() ); + if( tmp.isNull() || !tmp.hasChildNodes() ) + { + return defaultpar; + } + + tmp = tmp.firstChild(); + if( tmp.nodeType() == QDomNode::ElementNode && !tmp.toElement().tagName().isEmpty() ) + { + return tmp.toElement().tagName().toUtf8().constData(); + } + if( tmp.nodeType() == QDomNode::TextNode && !tmp.toText().data().isEmpty() ) + { + return tmp.toText().data().toUtf8().constData(); + } + + return defaultpar; +} + +REALTYPE QtXmlWrapper::getparreal(const char *name, REALTYPE defaultpar) const +{ + QDomElement tmp = findElement( d->m_node, "par_real", "name", name ); + if( tmp.isNull() || !tmp.hasAttribute( "value" ) ) + { + return defaultpar; + } + + return tmp.attribute( "value" ).toFloat(); +} + +REALTYPE QtXmlWrapper::getparreal(const char *name, + REALTYPE defaultpar, + REALTYPE min, + REALTYPE max) const +{ + REALTYPE result = getparreal(name, defaultpar); + + if(result < min) + result = min; + else + if(result > max) + result = max; + return result; +} + + +/** Private members **/ + +QDomElement XmlData::addparams(const char *name, unsigned int params, + ...) +{ + /**@todo make this function send out a good error message if something goes + * wrong**/ + QDomElement element = m_doc.createElement( name ); + m_node.appendChild( element ); + + if(params) { + va_list variableList; + va_start(variableList, params); + + const char *ParamName; + const char *ParamValue; + while(params--) { + ParamName = va_arg(variableList, const char *); + ParamValue = va_arg(variableList, const char *); + element.setAttribute( ParamName, ParamValue); + } + } + return element; +} + diff --git a/plugins/zynaddsubfx/src/Misc/QtXmlWrapper.h b/plugins/zynaddsubfx/src/Misc/QtXmlWrapper.h new file mode 100644 index 000000000..0f478dd97 --- /dev/null +++ b/plugins/zynaddsubfx/src/Misc/QtXmlWrapper.h @@ -0,0 +1,125 @@ +/* + * QtXmlWrapper.h - a QtXml based XML backend for ZynAddSubxFX + * + * Copyright (c) 2009 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +/* File derived from XMLwrapper.h: */ +/* + ZynAddSubFX - a software synthesizer + + XMLwrapper.h - XML wrapper + Copyright (C) 2003-2005 Nasca Octavian Paul + Copyright (C) 2009-2009 Mark McCurry + Author: Nasca Octavian Paul + Mark McCurry + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef QT_XML_WRAPPER_H +#define QT_XML_WRAPPER_H + +#include "../globals.h" + +#include +#include +#include +#include + +#define QtXmlWrapper XMLwrapper + +struct XmlData; + +class QtXmlWrapper +{ +public: + QtXmlWrapper(); + ~QtXmlWrapper(); + + int saveXMLfile( const std::string & filename ) const; + int loadXMLfile( const std::string & filename ); + + char *getXMLdata() const; + bool putXMLdata( const char *xmldata ); + + void addpar( const std::string & name, int val ); + void addparreal( const std::string & name, REALTYPE val); + void addparbool( const std::string & name, int val ); + void addparstr( const std::string & name, const std::string & val ); + + void beginbranch( const std::string & name ); + void beginbranch( const std::string & name, int id ); + void endbranch(); + + + int enterbranch( const std::string & name ); + int enterbranch( const std::string & name, int id ); + void exitbranch(); + int getbranchid( int min, int max ) const; + + int getpar( const std::string & name, int defaultpar, int min, int max ) const; + int getpar127( const std::string & name, int defaultpar ) const; + int getparbool( const std::string & name, int defaultpar ) const; + + void getparstr( const std::string & name, char * par, int maxstrlen ) const; + std::string getparstr( const std::string & name, const std::string & defaultpar ) const; + REALTYPE getparreal( const char * name, REALTYPE defaultpar ) const; + + REALTYPE getparreal(const char *name, REALTYPE defaultpar, REALTYPE min, REALTYPE max) const; + + bool minimal; /** Stereo::Stereo(const T &left, const T &right) - :leftChannel(left), rightChannel(right) + :l(left), r(right) {} template Stereo::Stereo(const T &val) - :leftChannel(val), rightChannel(val) + :l(val), r(val) {} template -void Stereo::operator=(const Stereo &nstr) +Stereo &Stereo::operator=(const Stereo &nstr) { - leftChannel = nstr.leftChannel; - rightChannel = nstr.rightChannel; + l = nstr.l; + r = nstr.r; + return *this; } diff --git a/plugins/zynaddsubfx/src/Misc/Stereo.h b/plugins/zynaddsubfx/src/Misc/Stereo.h index 8bdf43017..06ee63c80 100644 --- a/plugins/zynaddsubfx/src/Misc/Stereo.h +++ b/plugins/zynaddsubfx/src/Misc/Stereo.h @@ -22,7 +22,7 @@ #define STEREO_H template -class Stereo +struct Stereo { public: Stereo(const T &left, const T &right); @@ -32,34 +32,10 @@ class Stereo Stereo(const T &val); ~Stereo() {} - void operator=(const Stereo &smp); - T &left() { - return leftChannel; - } - T &right() { - return rightChannel; - } - T &l() { - return leftChannel; - } - T &r() { - return rightChannel; - } - const T &left() const { - return leftChannel; - } - const T &right() const { - return rightChannel; - } - const T &l() const { - return leftChannel; - } - const T &r() const { - return rightChannel; - } - private: - T leftChannel; - T rightChannel; + Stereo &operator=(const Stereo &smp); + + //data + T l, r; }; #include "Stereo.cpp" #endif diff --git a/plugins/zynaddsubfx/src/Misc/Util.cpp b/plugins/zynaddsubfx/src/Misc/Util.cpp index 0f862c602..ae3d2af34 100644 --- a/plugins/zynaddsubfx/src/Misc/Util.cpp +++ b/plugins/zynaddsubfx/src/Misc/Util.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Util.C - Miscellaneous functions + Util.cpp - Miscellaneous functions Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -113,3 +113,18 @@ bool fileexists(const char *filename) return false; } +void invSignal(REALTYPE *sig, size_t len) +{ + for(int i = 0; i < len; i++) + sig[i] *= -1.0f; +} + +void crossover(REALTYPE &a, REALTYPE &b, REALTYPE crossover) +{ + REALTYPE tmpa = a; + REALTYPE tmpb = b; + a = tmpa * (1.0 - crossover) + tmpb * crossover; + b = tmpb * (1.0 - crossover) + tmpa * crossover; +} + + diff --git a/plugins/zynaddsubfx/src/Misc/Util.h b/plugins/zynaddsubfx/src/Misc/Util.h index ccdac4dea..c0dc73ee2 100644 --- a/plugins/zynaddsubfx/src/Misc/Util.h +++ b/plugins/zynaddsubfx/src/Misc/Util.h @@ -42,6 +42,10 @@ extern REALTYPE *denormalkillbuf; /** std::string stringFrom(T x) { @@ -60,5 +64,11 @@ T stringTo(const char *x) return ans; } +template +T limit(T val, T min, T max) +{ + return (val < min ? min : (val > max ? max : val)); +} + #endif diff --git a/plugins/zynaddsubfx/src/Misc/XMLwrapper.cpp b/plugins/zynaddsubfx/src/Misc/XMLwrapper.cpp index b9ee3d6e6..d3750c47e 100644 --- a/plugins/zynaddsubfx/src/Misc/XMLwrapper.cpp +++ b/plugins/zynaddsubfx/src/Misc/XMLwrapper.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - XMLwrapper.C - XML wrapper + XMLwrapper.cpp - XML wrapper Copyright (C) 2003-2005 Nasca Octavian Paul Copyright (C) 2009-2009 Mark McCurry Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Misc/XMLwrapper.h b/plugins/zynaddsubfx/src/Misc/XMLwrapper.h index 5860f0764..997ac933b 100644 --- a/plugins/zynaddsubfx/src/Misc/XMLwrapper.h +++ b/plugins/zynaddsubfx/src/Misc/XMLwrapper.h @@ -22,6 +22,9 @@ */ +#if 1 +#include "QtXmlWrapper.h" +#else #include #include #ifndef REALTYPE @@ -269,4 +272,4 @@ class XMLwrapper }; #endif - +#endif diff --git a/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.cpp b/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.cpp index 41e5ddc13..a7fdd0803 100644 --- a/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.cpp +++ b/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - DSSIaudiooutput.C - Audio functions for DSSI + DSSIaudiooutput.cpp - Audio functions for DSSI Copyright (C) 2002 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -20,268 +20,666 @@ */ +/* + * Inital working DSSI output code contributed by Stephen G. Parry + */ + //this file contains code used from trivial_synth.c from -//the DSSI (published by Steve Harris under public domain) as a template -//the code is incomplete +//the DSSI (published by Steve Harris under public domain) as a template. + #include #include "DSSIaudiooutput.h" +#include "../Misc/Config.h" +#include "../Misc/Bank.h" +#include -static LADSPA_Descriptor *tsLDescriptor = NULL; -static DSSI_Descriptor *tsDDescriptor = NULL; - -typedef struct { - LADSPA_Data *outl; - LADSPA_Data *outr; -// note_data data[MIDI_NOTES]; -// float omega[MIDI_NOTES]; -} TS; - - -static void cleanupTS(LADSPA_Handle instance) +// +// Static stubs for LADSPA member functions +// +// LADSPA is essentially a C handle based API; This plug-in implementation is +// a C++ OO one so we need stub functions to map from C API calls to C++ object +// method calls. +void DSSIaudiooutput::stub_connectPort(LADSPA_Handle instance, unsigned long port, LADSPA_Data * data) { - free(instance); + getInstance(instance)->connectPort(port, data); } -static void connectPortTS(LADSPA_Handle instance, unsigned long port, - LADSPA_Data *data) + +void DSSIaudiooutput::stub_activate(LADSPA_Handle instance) { - TS *plugin; - plugin = (TS *) instance; - switch(port) { - case 0: - plugin->outl = data; - break; - case 1: - plugin->outr = data; - break; - } + getInstance(instance)->activate(); } +void DSSIaudiooutput::stub_run(LADSPA_Handle instance, unsigned long sample_count) +{ + getInstance(instance)->run(sample_count); +} + +void DSSIaudiooutput::stub_deactivate(LADSPA_Handle instance) +{ + getInstance(instance)->deactivate(); +} + + +void DSSIaudiooutput::stub_cleanup(LADSPA_Handle instance) +{ + DSSIaudiooutput* plugin_instance = getInstance(instance); + plugin_instance->cleanup(); + delete plugin_instance; +} + + const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) { - switch(index) { - case 0: - return tsLDescriptor; - default: - return NULL; - } + return DSSIaudiooutput::getLadspaDescriptor(index); +} + +// +// Static stubs for DSSI member functions +// +// DSSI is essentially a C handle based API; This plug-in implementation is +// a C++ OO one so we need stub functions to map from C API calls to C++ object +// method calls. +const DSSI_Program_Descriptor* DSSIaudiooutput::stub_getProgram (LADSPA_Handle instance, unsigned long index) +{ + return getInstance(instance)->getProgram(index); +} + +void DSSIaudiooutput::stub_selectProgram(LADSPA_Handle instance, unsigned long bank, unsigned long program) +{ + getInstance(instance)->selectProgram(bank, program); +} + +int DSSIaudiooutput::stub_getMidiControllerForPort(LADSPA_Handle instance, unsigned long port) +{ + return getInstance(instance)->getMidiControllerForPort(port); +} + +void DSSIaudiooutput::stub_runSynth(LADSPA_Handle instance, unsigned long sample_count, + snd_seq_event_t *events, unsigned long event_count) +{ + getInstance(instance)->runSynth(sample_count, events, event_count); } const DSSI_Descriptor *dssi_descriptor(unsigned long index) { -// FILE *a=fopen("/tmp/zzzzz11z","w"); -// fprintf(a,"aaaaaaaaaaa TEST\n"); -// fclose(a); - switch(index) { - case 0: - return tsDDescriptor; - default: + return DSSIaudiooutput::getDssiDescriptor(index); +} + +// +// LADSPA member functions +// + +/** + * Instantiates a plug-in. + * + * This LADSPA member function instantiates a plug-in. + * Note that instance initialisation should generally occur in + * activate() rather than here. + * + * Zyn Implementation + * ------------------ + * This implementation creates a C++ class object and hides its pointer + * in the handle by type casting. + * + * @param descriptor [in] the descriptor for this plug-in + * @param s_rate [in] the sample rate + * @return the plug-in instance handle if successful else NULL + */ +LADSPA_Handle DSSIaudiooutput::instantiate(const LADSPA_Descriptor * descriptor, unsigned long s_rate) +{ + if(descriptor->UniqueID == dssiDescriptor->LADSPA_Plugin->UniqueID) + { + return (LADSPA_Handle)(new DSSIaudiooutput(s_rate)); + } + else + { return NULL; } } -static LADSPA_Handle instantiateTS(const LADSPA_Descriptor *descriptor, - unsigned long s_rate) +/** + * Connects a port on an instantiated plug-in. + * + * This LADSPA member function connects a port on an instantiated plug-in to a + * memory location at which a block of data for the port will be read/written. + * The data location is expected to be an array of LADSPA_Data for audio ports + * or a single LADSPA_Data value for control ports. Memory issues will be + * managed by the host. The plug-in must read/write the data at these locations + * every time run() or run_adding() is called and the data present at the time + * of this connection call should not be considered meaningful. + * + * Zyn Implementation + * ------------------ + * The buffer pointers are stored as member variables + * + * @param port [in] the port to be connected + * @param data [in] the data buffer to write to / read from + */ +void DSSIaudiooutput::connectPort(unsigned long port, LADSPA_Data * data) { - TS *plugin_data = (TS *) malloc(sizeof(TS)); - /* for (i=0; iomega[i] = M_PI * 2.0 / (double)s_rate * - pow(2.0, (i-69.0) / 12.0); - } - */ - return (LADSPA_Handle) plugin_data; -} - -static void activateTS(LADSPA_Handle instance) -{ - TS *plugin_data = (TS *) instance; - -// for (i=0; idata[i].active = 0; -// } -} - - -static void runTS(LADSPA_Handle instance, unsigned long sample_count, - snd_seq_event_t *events, unsigned long event_count) -{ - TS *plugin_data = (TS *) instance; -// LADSPA_Data *const output = plugin_data->output; -// LADSPA_Data freq = *(plugin_data->freq); -// LADSPA_Data vol = *(plugin_data->vol); -// note_data *data = plugin_data->data; - unsigned long pos; - unsigned long event_pos; - unsigned long note; - - /* if (freq < 1.0) { - freq = 440.0f; - } - if (vol < 0.000001) { - vol = 1.0f; - } - - if (event_count > 0) { - printf("trivial_synth: have %ld events\n", event_count); - } - - for (pos = 0, event_pos = 0; pos < sample_count; pos++) { - - while (event_pos < event_count - && pos == events[event_pos].time.tick) { - - printf("trivial_synth: event type %d\n", events[event_pos].type); - - if (events[event_pos].type == SND_SEQ_EVENT_NOTEON) { - data[events[event_pos].data.note.note].amp = - events[event_pos].data.note.velocity / 512.0f; - data[events[event_pos].data.note.note]. - active = events[event_pos].data.note.velocity > 0; - data[events[event_pos].data.note.note]. - phase = 0.0; - } else if (events[event_pos].type == SND_SEQ_EVENT_NOTEOFF) { - data[events[event_pos].data.note.note]. - active = 0; - } - event_pos++; - } - - output[pos] = 0.0f; - for (note = 0; note < MIDI_NOTES; note++) { - if (data[note].active) { - output[pos] += sin(data[note].phase) * data[note].amp * vol; - data[note].phase += plugin_data->omega[note] * freq; - if (data[note].phase > M_PI * 2.0) { - data[note].phase -= M_PI * 2.0; - } - } - } - } - */ -} - - -static void runTSWrapper(LADSPA_Handle instance, - unsigned long sample_count) -{ - runTS(instance, sample_count, NULL, 0); -} - -int getControllerTS(LADSPA_Handle instance, unsigned long port) -{ - return -1; -} - -void _init() -{ - char **port_names; - LADSPA_PortDescriptor *port_descriptors; - LADSPA_PortRangeHint *port_range_hints; - - FILE *a = fopen("/tmp/zzzzzz", "w"); - fprintf(a, "aaaaaaaaaaa TEST\n"); - fclose(a); - - - tsLDescriptor = (LADSPA_Descriptor *) malloc(sizeof(LADSPA_Descriptor)); - if(tsLDescriptor) { - tsLDescriptor->UniqueID = 100; - tsLDescriptor->Label = "ZASF"; - tsLDescriptor->Properties = 0; - tsLDescriptor->Name = "ZynAddSubFX"; - tsLDescriptor->Maker = - "Nasca Octavian Paul "; - tsLDescriptor->Copyright = "GNU General Public License v.2"; - tsLDescriptor->PortCount = 2; - - port_descriptors = (LADSPA_PortDescriptor *) - calloc(tsLDescriptor->PortCount, sizeof - (LADSPA_PortDescriptor)); - tsLDescriptor->PortDescriptors = - (const LADSPA_PortDescriptor *) port_descriptors; - - port_range_hints = (LADSPA_PortRangeHint *) - calloc(tsLDescriptor->PortCount, sizeof - (LADSPA_PortRangeHint)); - tsLDescriptor->PortRangeHints = - (const LADSPA_PortRangeHint *) port_range_hints; - - port_names = (char **) calloc(tsLDescriptor->PortCount, sizeof(char *)); - tsLDescriptor->PortNames = (const char **) port_names; - - port_descriptors[0] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; - port_names[0] = "Output L"; - port_range_hints[0].HintDescriptor = 0; - port_descriptors[1] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; - port_names[1] = "Output R"; - port_range_hints[1].HintDescriptor = 0; - - tsLDescriptor->activate = activateTS; - tsLDescriptor->cleanup = cleanupTS; - tsLDescriptor->connect_port = connectPortTS; - tsLDescriptor->deactivate = NULL; - tsLDescriptor->instantiate = instantiateTS; - tsLDescriptor->run = runTSWrapper; - tsLDescriptor->run_adding = NULL; - tsLDescriptor->set_run_adding_gain = NULL; - } - - tsDDescriptor = (DSSI_Descriptor *) malloc(sizeof(DSSI_Descriptor)); - if(tsDDescriptor) { - tsDDescriptor->DSSI_API_Version = 1; - tsDDescriptor->LADSPA_Plugin = tsLDescriptor; - tsDDescriptor->configure = NULL; - tsDDescriptor->get_program = NULL; - tsDDescriptor->get_midi_controller_for_port = getControllerTS; - tsDDescriptor->select_program = NULL; - tsDDescriptor->run_synth = runTS; - tsDDescriptor->run_synth_adding = NULL; - tsDDescriptor->run_multiple_synths = NULL; - tsDDescriptor->run_multiple_synths_adding = NULL; + switch (port) { + case 0: + outl = data; + break; + case 1: + outr = data; + break; } } -void _fini() -{} - - - - - - - -//the constructor and the destructor are defined in main.C -/* -void VSTSynth::process (float **inputs, float **outputs, long sampleframes){ - float *outl=outputs[0]; - float *outr=outputs[1]; - pthread_mutex_lock(&vmaster->mutex); - vmaster->GetAudioOutSamples(sampleframes,(int) getSampleRate(),outl,outr); - pthread_mutex_unlock(&vmaster->mutex); -}; - -void VSTSynth::processReplacing (float **inputs, float **outputs, long sampleframes){ - process(inputs,outputs,sampleframes); -}; - -long int VSTSynth::canDo(char *txt){ - if (strcmp(txt,"receiveVstEvents")==0) return (1); - if (strcmp(txt,"receiveVstMidiEvent")==0) return (1); - return(-1); -}; - -bool VSTSynth::getVendorString(char *txt){ - strcpy(txt,"Nasca O. Paul"); - return(true); -}; - -bool VSTSynth::getProductString(char *txt){ - strcpy(txt,"ZynAddSubFX"); - return(true); -}; - -void VSTSynth::resume(){ - wantEvents(); -}; - +/** + * Initialises a plug-in instance and activates it for use. + * + * This LADSPA member function initialises a plug-in instance and activates it + * for use. This is separated from instantiate() to aid real-time support and + * so that hosts can reinitialise a plug-in instance by calling deactivate() and + * then activate(). In this case the plug-in instance must reset all state + * information dependent on the history of the plug-in instance except for any + * data locations provided by connect_port() and any gain set by + * set_run_adding_gain(). + * + * Zyn Implementation + * ------------------ + * Currently this does nothing; Care must be taken as to code placed here as + * too much code here seems to cause time-out problems in jack-dssi-host. */ +void DSSIaudiooutput::activate() +{ +} +/** + * Runs an instance of a plug-in for a block. + * + * This LADSPA member function runs an instance of a plug-in for a block. + * Note that if an activate() function exists then it must be called before + * run() or run_adding(). If deactivate() is called for a plug-in instance then + * the plug-in instance may not be reused until activate() has been called again. + * + * Zyn Implementation + * ------------------ + * This is a LADSPA function that does not process any MIDI events; it is hence + * implemented by simply calling runSynth() with an empty event list. + * + * @param sample_count [in] the block size (in samples) for which the plug-in instance may run + */ +void DSSIaudiooutput::run(unsigned long sample_count) +{ + runSynth(sample_count,NULL,(unsigned long)0); +} + +/** + * Counterpart to activate(). + * + * This LADSPA member function is the counterpart to activate() (see above). + * Deactivation is not similar to pausing as the plug-in instance will be + * reinitialised when activate() is called to reuse it. + * + * Zyn Implementation + * ------------------ + * Currently this function does nothing. + */ +void DSSIaudiooutput::deactivate() +{ + +} + +/** + * Deletes a plug-in instance that is no longer required. + * + * LADSPA member function; once an instance of a plug-in has been finished with + * it can be deleted using this function. The instance handle ceases to be + * valid after this call. + * + * If activate() was called for a plug-in instance then a corresponding call to + * deactivate() must be made before cleanup() is called. + * + * Zyn Implementation + * ------------------ + * Currently cleanup is deferred to the destructor that is invoked after cleanup() + */ +void DSSIaudiooutput::cleanup() +{ +} + +/** + * Initial entry point for the LADSPA plug-in library. + * + * This LADSPA function is the initial entry point for the plug-in library. + * The LADSPA host looks for this entry point in each shared library object it + * finds and then calls the function to enumerate the plug-ins within the + * library. + * + * Zyn Implementation + * ------------------ + * As the Zyn plug-in is a DSSI plug-in, the LADSPA descriptor is embedded inside + * the DSSI descriptor, which is created by DSSIaudiooutput::initDssiDescriptor() + * statically when the library is loaded. This function then merely returns a pointer + * to that embedded descriptor. + * + * @param index [in] the index number of the plug-in within the library. + * @return if index is in range, a pointer to the plug-in descriptor is returned, else NULL + */ +const LADSPA_Descriptor* DSSIaudiooutput::getLadspaDescriptor(unsigned long index) +{ + if(index > 0 || dssiDescriptor == NULL) + return NULL; + else + return dssiDescriptor->LADSPA_Plugin; +} + +// +// DSSI member functions +// + +/** + * Provides a description of a program available on this synth. + * + * This DSSI member function pointer provides a description of a program (named + * preset sound) available on this synth. + * + * Zyn Implementation + * ------------------ + * The instruments in all Zyn's bank directories, as shown by the `instrument + * -> show instrument bank` command, are enumerated to the host by this + * function, allowing access to all those instruments. + * The first time an instrument is requested, the bank it is in and any + * unmapped ones preceding that are mapped; all the instruments names and + * filenames from those banks are stored in the programMap member variable for + * later use. This is done on demand in this way, rather than up front in one + * go because loading all the instrument names in one go can lead to timeouts + * and zombies. + * + * @param index [in] index into the plug-in's list of + * programs, not a program number as represented by the Program + * field of the DSSI_Program_Descriptor. (This distinction is + * needed to support synths that use non-contiguous program or + * bank numbers.) + * @return a DSSI_Program_Descriptor pointer that is + * guaranteed to be valid only until the next call to get_program, + * deactivate, or configure, on the same plug-in instance, or NULL if index is out of range. + */ +const DSSI_Program_Descriptor* DSSIaudiooutput::getProgram (unsigned long index) +{ + static DSSI_Program_Descriptor retVal; + + /* Make sure we have the list of banks loaded */ + initBanks(); + + /* Make sure that the bank containing the instrument has been mapped */ + while (index >= programMap.size() && mapNextBank()) + /* DO NOTHING MORE */; + + if(index >= programMap.size()) + { + /* No more instruments */ + return NULL; + } + else + { + /* OK, return the instrument */ + retVal.Name = programMap[index].name.c_str(); + retVal.Program = programMap[index].program; + retVal.Bank = programMap[index].bank; + return &retVal; + } +} + +/** + * Selects a new program for this synth. + * + * This DSSI member function selects a new program for this synth. The program + * change will take effect immediately at the start of the next run_synth() + * call. An invalid bank / instrument combination is ignored. + * + * Zyn Implementation + * ------------------ + * the banks and instruments are as shown in the `instrument -> show instrument + * bank` command in Zyn. The bank no is a 1-based index into the list of banks + * Zyn loads and shows in the drop down and the program number is the + * instrument within that bank. + * + * @param bank [in] the bank number to select + * @param program [in] the program number within the bank to select + */ +void DSSIaudiooutput::selectProgram(unsigned long bank, unsigned long program) +{ + initBanks(); +// cerr << "selectProgram(" << (bank & 0x7F) << ':' << ((bank >> 7) & 0x7F) << "," << program << ")" << '\n'; + if(bank < MAX_NUM_BANKS && program < BANK_SIZE) + { + char* bankdir = master->bank.banks[ bank ].dir; + if(bankdir != NULL) + { + pthread_mutex_lock(&master->mutex); + + /* We have to turn off the CheckPADsynth functionality, else + * the program change takes way too long and we get timeouts + * and hence zombies (!) */ + int save = config.cfg.CheckPADsynth; + config.cfg.CheckPADsynth = 0; + + /* Load the bank... */ + master->bank.loadbank(bankdir); + + /* restore the CheckPADsynth flag */ + config.cfg.CheckPADsynth = save; + + /* Now load the instrument... */ + master->bank.loadfromslot((unsigned int)program, master->part[0]); + + pthread_mutex_unlock(&master->mutex); + } + } +} + +/** + * Returns the MIDI controller number or NRPN for a input control port + * + * This DSSI member function returns the MIDI controller number or NRPN that + * should be mapped to the given input control port. If the given port should + * not have any MIDI controller mapped to it, the function will return DSSI_NONE. + * The behaviour of this function is undefined if the given port + * number does not correspond to an input control port. + * + * Zyn Implementation + * ------------------ + * Currently Zyn does not define any controller ports, but may do in the future. + * + * @param port [in] the input controller port + * @return the CC and NRPN values shifted and ORed together. + */ +int DSSIaudiooutput::getMidiControllerForPort(unsigned long port) +{ + return DSSI_NONE; +} + +/** + * Runs the synth for a block. + * + * This DSSI member function runs the synth for a block. This is identical in + * function to the LADSPA run() function, except that it also supplies events + * to the synth. + * + * Zyn Implementation + * ------------------ + * Zyn implements synthesis in Master::GetAudioOutSamples; runSynth calls this + * function in chunks delimited by the sample_count and the frame indexes in + * the events block, calling the appropriate NoteOn, NoteOff and SetController + * members of Master to process the events supplied between each chunk. + * + * @param sample_count [in] the block size (in samples) for which the synth + * instance may run. + * @param events [in] The Events pointer points to a block of ALSA + * sequencer events, used to communicate MIDI and related events to the synth. + * Each event must be timestamped relative to the start of the block, + * (mis)using the ALSA "tick time" field as a frame count. The host is + * responsible for ensuring that events with differing timestamps are already + * ordered by time. Must not include NOTE (only NOTE_ON / NOTE_OFF), LSB or MSB + * events. + * @param event_count [in] the number of entries in the `events` block + */ +void DSSIaudiooutput::runSynth(unsigned long sample_count, snd_seq_event_t *events, unsigned long event_count) +{ + unsigned long from_frame = 0; + unsigned long event_index = 0; + unsigned long next_event_frame = 0; + unsigned long to_frame = 0; + pthread_mutex_lock(&master->mutex); + + do { + /* Find the time of the next event, if any */ + if(events == NULL || event_index >= event_count) + next_event_frame = ULONG_MAX; + else + next_event_frame = events[event_index].time.tick; + + /* find the end of the sub-sample to be processed this time round... */ + /* if the next event falls within the desired sample interval... */ + if(next_event_frame < sample_count && next_event_frame >= to_frame) + /* set the end to be at that event */ + to_frame = next_event_frame; + else + /* ...else go for the whole remaining sample */ + to_frame = sample_count; + if(from_frameGetAudioOutSamples(to_frame - from_frame, (int)sampleRate, &(outl[from_frame]), &(outr[from_frame])); + // next sub-sample please... + from_frame = to_frame; + } + + // Now process any event(s) at the current timing point + while(events != NULL && event_index < event_count && events[event_index].time.tick == to_frame) + { + if(events[event_index].type == SND_SEQ_EVENT_NOTEON) + { + master->NoteOn(events[event_index].data.note.channel, events[event_index].data.note.note, events[event_index].data.note.velocity); + } + else if(events[event_index].type == SND_SEQ_EVENT_NOTEOFF) + { + master->NoteOff(events[event_index].data.note.channel, events[event_index].data.note.note); + } + else if(events[event_index].type == SND_SEQ_EVENT_CONTROLLER) + { + master->SetController(events[event_index].data.control.channel, events[event_index].data.control.param, events[event_index].data.control.value); + } + else + { + } + event_index++; + } + + // Keep going until we have the desired total length of sample... + } while(to_frame < sample_count); + + pthread_mutex_unlock(&master->mutex); +} + +/** + * Initial entry point for the DSSI plug-in library. + * + * This DSSI function is the initial entry point for the plug-in library. + * The DSSI host looks for this entry point in each shared library object it + * finds and then calls the function to enumerate the plug-ins within the + * library. + * + * Zyn Implementation + * ------------------ + * The descriptor is created statically by DSSIaudiooutput::initDssiDescriptor() + * when the plug-in library is loaded. This function merely returns a pointer to + * that descriptor. + * + * @param index [in] the index number of the plug-in within the library. + * @return if index is in range, a pointer to the plug-in descriptor is returned, else NULL + */ +const DSSI_Descriptor* DSSIaudiooutput::getDssiDescriptor(unsigned long index) +{ + if(index > 0 || dssiDescriptor == NULL) + return NULL; + else + return dssiDescriptor; +} + +// +// Internal member functions +// + +// Initialise the DSSI descriptor, statically: +DSSI_Descriptor* DSSIaudiooutput::dssiDescriptor = DSSIaudiooutput::initDssiDescriptor(); + +/** + * Initializes the DSSI (and LADSPA) descriptor, returning it is an object. + */ +DSSI_Descriptor* DSSIaudiooutput::initDssiDescriptor() +{ + DSSI_Descriptor* newDssiDescriptor = new DSSI_Descriptor; + + LADSPA_PortDescriptor* newPortDescriptors; + char** newPortNames; + LADSPA_PortRangeHint* newPortRangeHints; + + if (newDssiDescriptor) + { + LADSPA_Descriptor* newLadspaDescriptor = new LADSPA_Descriptor; + if (newLadspaDescriptor) + { + newLadspaDescriptor->UniqueID = 100; + newLadspaDescriptor->Label = "ZASF"; + newLadspaDescriptor->Properties = 0; + newLadspaDescriptor->Name = "ZynAddSubFX"; + newLadspaDescriptor->Maker = "Nasca Octavian Paul "; + newLadspaDescriptor->Copyright = "GNU General Public License v.2"; + newLadspaDescriptor->PortCount = 2; + + newPortNames = new char *[newLadspaDescriptor->PortCount]; + newPortNames[0] = "Output L"; + newPortNames[1] = "Output R"; + newLadspaDescriptor->PortNames = newPortNames; + + newPortDescriptors = new LADSPA_PortDescriptor[newLadspaDescriptor->PortCount]; + newPortDescriptors[0] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + newPortDescriptors[1] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + newLadspaDescriptor->PortDescriptors = newPortDescriptors; + + newPortRangeHints = new LADSPA_PortRangeHint[newLadspaDescriptor->PortCount]; + newPortRangeHints[0].HintDescriptor = 0; + newPortRangeHints[1].HintDescriptor = 0; + newLadspaDescriptor->PortRangeHints = newPortRangeHints; + + newLadspaDescriptor->activate = stub_activate; + newLadspaDescriptor->cleanup = stub_cleanup; + newLadspaDescriptor->connect_port = stub_connectPort; + newLadspaDescriptor->deactivate = stub_deactivate; + newLadspaDescriptor->instantiate = instantiate; + newLadspaDescriptor->run = stub_run; + newLadspaDescriptor->run_adding = NULL; + newLadspaDescriptor->set_run_adding_gain = NULL; + } + newDssiDescriptor->LADSPA_Plugin = newLadspaDescriptor; + newDssiDescriptor->DSSI_API_Version = 1; + newDssiDescriptor->configure = NULL; + newDssiDescriptor->get_program = stub_getProgram; + newDssiDescriptor->get_midi_controller_for_port = stub_getMidiControllerForPort; + newDssiDescriptor->select_program = stub_selectProgram; + newDssiDescriptor->run_synth = stub_runSynth; + newDssiDescriptor->run_synth_adding = NULL; + newDssiDescriptor->run_multiple_synths = NULL; + newDssiDescriptor->run_multiple_synths_adding = NULL; + } + + dssiDescriptor = newDssiDescriptor; + + return dssiDescriptor; +} + +/** + * Converts a LADSPA / DSSI handle into a DSSIaudiooutput instance. + * + * @param instance [in] + * @return the instance + */ +DSSIaudiooutput* DSSIaudiooutput::getInstance(LADSPA_Handle instance) +{ + return (DSSIaudiooutput*)(instance); +} + +/** + * The private sole constructor for the DSSIaudiooutput class. + * + * Only ever called via instantiate(). + * @param sampleRate [in] the sample rate to be used by the synth. + * @return + */ +DSSIaudiooutput::DSSIaudiooutput(unsigned long sampleRate) +{ + this->sampleRate = sampleRate; + this->banksInited = false; + + config.init(); + + srand(time(NULL)); + denormalkillbuf=new REALTYPE [SOUND_BUFFER_SIZE]; + for (int i=0;imaster = new Master(); +} + +/** + * The destructor for the DSSIaudiooutput class + * @return + */ +DSSIaudiooutput::~DSSIaudiooutput() +{ +} + +/** + * Ensures the list of bank (directories) has been initialised. + */ +void DSSIaudiooutput::initBanks(void) +{ + if(!banksInited) + { + pthread_mutex_lock(&master->mutex); + master->bank.rescanforbanks(); + banksInited = true; + pthread_mutex_unlock(&master->mutex); + } +} + +/** + * constructor for the internally used ProgramDescriptor class + * + * @param _bank [in] bank number + * @param _program [in] program number + * @param _name [in] instrument / sample name + * @return + */ +DSSIaudiooutput::ProgramDescriptor::ProgramDescriptor(unsigned long _bank, unsigned long _program, char* _name) : + bank(_bank), program(_program), name(_name) +{ +} + +/** + * The map of programs available; held as a single shared statically allocated object. + */ +vector DSSIaudiooutput::programMap = vector(); + +/** + * Index controlling the map of banks + */ +long DSSIaudiooutput::bankNoToMap = 1; + +/** + * Queries and maps the next available bank of instruments. + * + * If the program index requested to getProgram() lies beyond the banks mapped to date, + * this member function is called to map the next one. + * @return true if a new bank has been found and mapped, else false. + */ +bool DSSIaudiooutput::mapNextBank() +{ + pthread_mutex_lock(&master->mutex); + Bank& bank = master->bank; + bool retval; + if(bankNoToMap >= MAX_NUM_BANKS || bank.banks[bankNoToMap].dir == NULL) + { + retval = false; + } + else + { + bank.loadbank(bank.banks[bankNoToMap].dir); + for(unsigned long instrument = 0; instrument < BANK_SIZE; instrument++) + { + char* insName = bank.getname(instrument); + if(insName != NULL && insName[0] != '\0' && insName[0] != ' ') + { + programMap.push_back(ProgramDescriptor(bankNoToMap,instrument,insName)); + } + } + bankNoToMap ++; + retval = true; + } + pthread_mutex_unlock(&master->mutex); + return retval; +} diff --git a/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.h b/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.h index a2ecf3c55..076367a72 100644 --- a/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.h +++ b/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.h @@ -26,34 +26,86 @@ #include "../globals.h" #include "../Misc/Master.h" -#include "../UI/MasterUI.h" #include #include +#include -/* -class VSTSynth:public AudioEffectX{ - public: - VSTSynth (audioMasterCallback audioMaster); - ~VSTSynth(); +class DSSIaudiooutput +{ +public: + // + // Static stubs for LADSPA member functions + // + static void stub_connectPort(LADSPA_Handle instance, unsigned long port, LADSPA_Data * data); + static void stub_activate(LADSPA_Handle instance); + static void stub_run(LADSPA_Handle instance, unsigned long sample_count); + static void stub_deactivate(LADSPA_Handle Instance); + static void stub_cleanup(LADSPA_Handle instance); - virtual void process (float **inputs, float **outputs, long sampleframes); - virtual void processReplacing (float **inputs, float **outputs, long sampleframes); - virtual long processEvents(VstEvents *events);//this is used for Midi input - virtual long int canDo(char *txt); - virtual bool getVendorString(char *txt); - virtual bool getProductString(char *txt); - virtual void resume(); + // + // Static stubs for DSSI member functions + // + static const DSSI_Program_Descriptor* stub_getProgram (LADSPA_Handle instance, unsigned long Index); + static void stub_selectProgram(LADSPA_Handle instance, unsigned long bank, unsigned long program); + static int stub_getMidiControllerForPort(LADSPA_Handle instance, unsigned long port); + static void stub_runSynth(LADSPA_Handle instance, unsigned long sample_count, + snd_seq_event_t *events, unsigned long event_count); - virtual long getChunk(void** data,bool isPreset=false); - virtual void setChunk(void *data,long size,bool isPreset=false); + /* + * LADSPA member functions + */ + static LADSPA_Handle instantiate(const LADSPA_Descriptor * descriptor, unsigned long s_rate); + void connectPort(unsigned long port, LADSPA_Data * data); + void activate(); + void run(unsigned long sample_count); + void deactivate(); + void cleanup(); + static const LADSPA_Descriptor* getLadspaDescriptor(unsigned long index); - MasterUI *ui; - int Pexitprogram; + /* + * DSSI member functions + */ + const DSSI_Program_Descriptor* getProgram (unsigned long Index); + void selectProgram(unsigned long bank, unsigned long program); + int getMidiControllerForPort(unsigned long port); + void runSynth(unsigned long sample_count, snd_seq_event_t *events, unsigned long event_count); + static const DSSI_Descriptor* getDssiDescriptor(unsigned long index); - Master *vmaster; - pthread_t thr; + struct ProgramDescriptor + { + unsigned long bank; + unsigned long program; + string name; + ProgramDescriptor(unsigned long _bank, unsigned long _program, char* _name); + }; + +private: + + DSSIaudiooutput(unsigned long sampleRate); + ~DSSIaudiooutput(); + static DSSI_Descriptor* initDssiDescriptor(); + static DSSIaudiooutput* getInstance(LADSPA_Handle instance); + void initBanks(); + bool mapNextBank(); + + LADSPA_Data *outl; + LADSPA_Data *outr; + long sampleRate; + Master* master; + static DSSI_Descriptor* dssiDescriptor; + static string bankDirNames[]; + static + vector programMap; + + /** + * Flag controlling the list of bank directories + */ + bool banksInited; + + static + long bankNoToMap; }; -*/ + #endif diff --git a/plugins/zynaddsubfx/src/Output/JACK_RTaudiooutput.cpp b/plugins/zynaddsubfx/src/Output/JACK_RTaudiooutput.cpp index 2ee019d1c..2e63e659b 100644 --- a/plugins/zynaddsubfx/src/Output/JACK_RTaudiooutput.cpp +++ b/plugins/zynaddsubfx/src/Output/JACK_RTaudiooutput.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - JACKaudiooutput.C - Audio output for JACK + JACKaudiooutput.cpp - Audio output for JACK Copyright (C) 2002 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Output/JACKaudiooutput.cpp b/plugins/zynaddsubfx/src/Output/JACKaudiooutput.cpp index 15f249246..d3c25fdd9 100644 --- a/plugins/zynaddsubfx/src/Output/JACKaudiooutput.cpp +++ b/plugins/zynaddsubfx/src/Output/JACKaudiooutput.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - JACKaudiooutput.C - Audio output for JACK + JACKaudiooutput.cpp - Audio output for JACK Copyright (C) 2002 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Output/OSSaudiooutput.cpp b/plugins/zynaddsubfx/src/Output/OSSaudiooutput.cpp index ad77573af..f6c6b3f0f 100644 --- a/plugins/zynaddsubfx/src/Output/OSSaudiooutput.cpp +++ b/plugins/zynaddsubfx/src/Output/OSSaudiooutput.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - OSSaudiooutput.C - Audio output for Open Sound System + OSSaudiooutput.cpp - Audio output for Open Sound System Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Output/PAaudiooutput.cpp b/plugins/zynaddsubfx/src/Output/PAaudiooutput.cpp index 73b346827..bfd84cca9 100644 --- a/plugins/zynaddsubfx/src/Output/PAaudiooutput.cpp +++ b/plugins/zynaddsubfx/src/Output/PAaudiooutput.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - PAaudiooutput.C - Audio output for PortAudio + PAaudiooutput.cpp - Audio output for PortAudio Copyright (C) 2002 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Output/Recorder.cpp b/plugins/zynaddsubfx/src/Output/Recorder.cpp index 43a44630e..244047ce8 100644 --- a/plugins/zynaddsubfx/src/Output/Recorder.cpp +++ b/plugins/zynaddsubfx/src/Output/Recorder.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Recorder.C - Records sound to a file + Recorder.cpp - Records sound to a file Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Output/VSTaudiooutput.cpp b/plugins/zynaddsubfx/src/Output/VSTaudiooutput.cpp index 183a3bb55..494a127c0 100644 --- a/plugins/zynaddsubfx/src/Output/VSTaudiooutput.cpp +++ b/plugins/zynaddsubfx/src/Output/VSTaudiooutput.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - VSTaudiooutput.C - Audio output for VST + VSTaudiooutput.cpp - Audio output for VST Copyright (C) 2002 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -22,7 +22,7 @@ #include #include "VSTaudiooutput.h" -//the constructor and the destructor are defined in main.C +//the constructor and the destructor are defined in main.cpp void VSTSynth::process(float **inputs, float **outputs, long sampleframes) { diff --git a/plugins/zynaddsubfx/src/Params/ADnoteParameters.cpp b/plugins/zynaddsubfx/src/Params/ADnoteParameters.cpp index 80c23391d..91f3449f1 100644 --- a/plugins/zynaddsubfx/src/Params/ADnoteParameters.cpp +++ b/plugins/zynaddsubfx/src/Params/ADnoteParameters.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - ADnoteParameters.C - Parameters for ADnote (ADsynth) + ADnoteParameters.cpp - Parameters for ADnote (ADsynth) Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -28,7 +28,8 @@ int ADnote_unison_sizes[] = {1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 25, 30, 40, 50, 0}; -ADnoteParameters::ADnoteParameters(FFTwrapper *fft_):Presets() +ADnoteParameters::ADnoteParameters(FFTwrapper *fft_) + :PresetsArray() { setpresettype("Padsyth"); fft = fft_; diff --git a/plugins/zynaddsubfx/src/Params/ADnoteParameters.h b/plugins/zynaddsubfx/src/Params/ADnoteParameters.h index ee5a632bd..e63efcff3 100644 --- a/plugins/zynaddsubfx/src/Params/ADnoteParameters.h +++ b/plugins/zynaddsubfx/src/Params/ADnoteParameters.h @@ -33,7 +33,7 @@ #include "../Misc/Util.h" #include "../Misc/XMLwrapper.h" #include "../DSP/FFTwrapper.h" -#include "Presets.h" +#include "PresetsArray.h" enum FMTYPE { NONE, MORPH, RING_MOD, PHASE_MOD, FREQ_MOD, PITCH_MOD @@ -275,7 +275,7 @@ struct ADnoteVoiceParam { EnvelopeParams *FMAmpEnvelope; }; -class ADnoteParameters:public Presets +class ADnoteParameters : public PresetsArray { public: ADnoteParameters(FFTwrapper *fft_); diff --git a/plugins/zynaddsubfx/src/Params/CMakeLists.txt b/plugins/zynaddsubfx/src/Params/CMakeLists.txt index 5ad77a4f2..670fcf26d 100644 --- a/plugins/zynaddsubfx/src/Params/CMakeLists.txt +++ b/plugins/zynaddsubfx/src/Params/CMakeLists.txt @@ -6,6 +6,7 @@ set(zynaddsubfx_params_SRCS LFOParams.cpp PADnoteParameters.cpp Presets.cpp + PresetsArray.cpp PresetsStore.cpp SUBnoteParameters.cpp diff --git a/plugins/zynaddsubfx/src/Params/Controller.cpp b/plugins/zynaddsubfx/src/Params/Controller.cpp index 61a0793e0..9bfa6b47d 100644 --- a/plugins/zynaddsubfx/src/Params/Controller.cpp +++ b/plugins/zynaddsubfx/src/Params/Controller.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Controller.C - (Midi) Controllers implementation + Controller.cpp - (Midi) Controllers implementation Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Params/EnvelopeParams.cpp b/plugins/zynaddsubfx/src/Params/EnvelopeParams.cpp index bb8207ba6..c13039f0f 100644 --- a/plugins/zynaddsubfx/src/Params/EnvelopeParams.cpp +++ b/plugins/zynaddsubfx/src/Params/EnvelopeParams.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - EnvelopeParams.C - Parameters for Envelope + EnvelopeParams.cpp - Parameters for Envelope Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Params/FilterParams.cpp b/plugins/zynaddsubfx/src/Params/FilterParams.cpp index a74bf5a99..6f87bc1a3 100644 --- a/plugins/zynaddsubfx/src/Params/FilterParams.cpp +++ b/plugins/zynaddsubfx/src/Params/FilterParams.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - FilterParams.C - Parameters for filter + FilterParams.cpp - Parameters for filter Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -27,7 +27,8 @@ FilterParams::FilterParams(unsigned char Ptype_, unsigned char Pfreq_, - unsigned char Pq_):Presets() + unsigned char Pq_) + : PresetsArray() { setpresettype("Pfilter"); Dtype = Ptype_; diff --git a/plugins/zynaddsubfx/src/Params/FilterParams.h b/plugins/zynaddsubfx/src/Params/FilterParams.h index 2a1df6b28..8facbe58c 100644 --- a/plugins/zynaddsubfx/src/Params/FilterParams.h +++ b/plugins/zynaddsubfx/src/Params/FilterParams.h @@ -25,9 +25,9 @@ #include "../globals.h" #include "../Misc/XMLwrapper.h" -#include "Presets.h" +#include "PresetsArray.h" -class FilterParams:public Presets +class FilterParams : public PresetsArray { public: FilterParams(unsigned char Ptype_, diff --git a/plugins/zynaddsubfx/src/Params/LFOParams.cpp b/plugins/zynaddsubfx/src/Params/LFOParams.cpp index fe993ed93..33028defc 100644 --- a/plugins/zynaddsubfx/src/Params/LFOParams.cpp +++ b/plugins/zynaddsubfx/src/Params/LFOParams.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - LFOParams.C - Parameters for LFO + LFOParams.cpp - Parameters for LFO Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -33,7 +33,7 @@ LFOParams::LFOParams(char Pfreq_, char PLFOtype_, char Prandomness_, char Pdelay_, - char Pcontinuous_, + char Pcontinous_, char fel_):Presets() { switch(fel_) { @@ -53,7 +53,7 @@ LFOParams::LFOParams(char Pfreq_, DLFOtype = PLFOtype_; Drandomness = Prandomness_; Ddelay = Pdelay_; - Dcontinuous = Pcontinuous_; + Dcontinous = Pcontinous_; fel = fel_; time = 0; @@ -71,7 +71,7 @@ void LFOParams::defaults() PLFOtype = DLFOtype; Prandomness = Drandomness; Pdelay = Ddelay; - Pcontinuous = Dcontinuous; + Pcontinous = Dcontinous; Pfreqrand = 0; Pstretch = 64; } @@ -87,7 +87,7 @@ void LFOParams::add2XML(XMLwrapper *xml) xml->addpar("randomness_frequency", Pfreqrand); xml->addpar("delay", Pdelay); xml->addpar("stretch", Pstretch); - xml->addparbool("continuous", Pcontinuous); + xml->addparbool("continous", Pcontinous); } void LFOParams::getfromXML(XMLwrapper *xml) @@ -100,6 +100,6 @@ void LFOParams::getfromXML(XMLwrapper *xml) Pfreqrand = xml->getpar127("randomness_frequency", Pfreqrand); Pdelay = xml->getpar127("delay", Pdelay); Pstretch = xml->getpar127("stretch", Pstretch); - Pcontinuous = xml->getparbool("continuous", Pcontinuous); + Pcontinous = xml->getparbool("continous", Pcontinous); } diff --git a/plugins/zynaddsubfx/src/Params/LFOParams.h b/plugins/zynaddsubfx/src/Params/LFOParams.h index b1b99eecd..6a7dcd915 100644 --- a/plugins/zynaddsubfx/src/Params/LFOParams.h +++ b/plugins/zynaddsubfx/src/Params/LFOParams.h @@ -35,7 +35,7 @@ class LFOParams:public Presets char PLFOtype_, char Prandomness_, char Pdelay_, - char Pcontinuous, + char Pcontinous, char fel_); ~LFOParams(); @@ -52,11 +52,11 @@ class LFOParams:public Presets unsigned char Prandomness; /**type); - if(nelement != -1) - strcat(type, "n"); + //strcat(type, "n"); if(name == NULL) if(strstr(type, "Plfo") != NULL) strcpy(type, "Plfo"); - ; xml->beginbranch(type); - if(nelement == -1) - add2XML(xml); - else - add2XMLsection(xml, nelement); + add2XML(xml); xml->endbranch(); if(name == NULL) @@ -68,74 +62,53 @@ void Presets::copy(const char *name) presetsstore.copypreset(xml, type, name); delete (xml); - nelement = -1; } void Presets::paste(int npreset) { char type[MAX_PRESETTYPE_SIZE]; strcpy(type, this->type); - if(nelement != -1) - strcat(type, "n"); + //strcat(type, "n"); + if(npreset == 0) if(strstr(type, "Plfo") != NULL) strcpy(type, "Plfo"); - ; XMLwrapper *xml = new XMLwrapper(); if(npreset == 0) { if(!checkclipboardtype()) { - nelement = -1; delete (xml); return; } if(!presetsstore.pasteclipboard(xml)) { delete (xml); - nelement = -1; return; } } else { if(!presetsstore.pastepreset(xml, npreset)) { delete (xml); - nelement = -1; return; } } if(xml->enterbranch(type) == 0) { - nelement = -1; return; } - if(nelement == -1) { - defaults(); - getfromXML(xml); - } - else { - defaults(nelement); - getfromXMLsection(xml, nelement); - } + + defaults(); + getfromXML(xml); + xml->exitbranch(); delete (xml); - nelement = -1; } bool Presets::checkclipboardtype() { - char type[MAX_PRESETTYPE_SIZE]; - strcpy(type, this->type); - if(nelement != -1) - strcat(type, "n"); - return presetsstore.checkclipboardtype(type); } -void Presets::setelement(int n) -{ - nelement = n; -} - void Presets::rescanforpresets() { presetsstore.rescanforpresets(type); diff --git a/plugins/zynaddsubfx/src/Params/Presets.h b/plugins/zynaddsubfx/src/Params/Presets.h index 8e143aed6..d8000fe3b 100644 --- a/plugins/zynaddsubfx/src/Params/Presets.h +++ b/plugins/zynaddsubfx/src/Params/Presets.h @@ -30,17 +30,18 @@ /**Presets and Clipboard management*/ class Presets { + friend class PresetsArray; public: Presets(); virtual ~Presets(); - void copy(const char *name); /** + + +PresetsArray::PresetsArray() +{ + type[0] = 0; + nelement = -1; +} + +PresetsArray::~PresetsArray() +{} + +void PresetsArray::setpresettype(const char *type) +{ + strcpy(this->type, type); +} + +void PresetsArray::copy(const char *name) +{ + XMLwrapper *xml = new XMLwrapper(); + + //used only for the clipboard + if(name == NULL) + xml->minimal = false; + + char type[MAX_PRESETTYPE_SIZE]; + strcpy(type, this->type); + if(nelement != -1) + strcat(type, "n"); + if(name == NULL) + if(strstr(type, "Plfo") != NULL) + strcpy(type, "Plfo"); + ; + + xml->beginbranch(type); + if(nelement == -1) + add2XML(xml); + else + add2XMLsection(xml, nelement); + xml->endbranch(); + + if(name == NULL) + presetsstore.copyclipboard(xml, type); + else + presetsstore.copypreset(xml, type, name); + + delete (xml); + nelement = -1; +} + +void PresetsArray::paste(int npreset) +{ + char type[MAX_PRESETTYPE_SIZE]; + strcpy(type, this->type); + if(nelement != -1) + strcat(type, "n"); + if(npreset == 0) + if(strstr(type, "Plfo") != NULL) + strcpy(type, "Plfo"); + ; + + XMLwrapper *xml = new XMLwrapper(); + if(npreset == 0) { + if(!checkclipboardtype()) { + nelement = -1; + delete (xml); + return; + } + if(!presetsstore.pasteclipboard(xml)) { + delete (xml); + nelement = -1; + return; + } + } + else { + if(!presetsstore.pastepreset(xml, npreset)) { + delete (xml); + nelement = -1; + return; + } + } + + if(xml->enterbranch(type) == 0) { + nelement = -1; + return; + } + if(nelement == -1) { + defaults(); + getfromXML(xml); + } + else { + defaults(nelement); + getfromXMLsection(xml, nelement); + } + xml->exitbranch(); + + delete (xml); + nelement = -1; +} + +bool PresetsArray::checkclipboardtype() +{ + char type[MAX_PRESETTYPE_SIZE]; + strcpy(type, this->type); + if(nelement != -1) + strcat(type, "n"); + + return presetsstore.checkclipboardtype(type); +} + +void PresetsArray::setelement(int n) +{ + nelement = n; +} + diff --git a/plugins/zynaddsubfx/src/Params/PresetsArray.h b/plugins/zynaddsubfx/src/Params/PresetsArray.h new file mode 100644 index 000000000..aea7ed362 --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/PresetsArray.h @@ -0,0 +1,60 @@ +/* + ZynAddSubFX - a software synthesizer + + PresetsArray.h - PresetsArray and Clipboard management + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef PRESETSARRAY_H +#define PRESETSARRAY_H + +#include "../Misc/XMLwrapper.h" + +#include "Presets.h" + +/**PresetsArray and Clipboard management*/ +class PresetsArray : public Presets +{ + public: + PresetsArray(); + virtual ~PresetsArray(); + + void copy(const char *name); /** +#include +#include #include #include #include @@ -27,17 +30,14 @@ #include "PresetsStore.h" #include "../Misc/Util.h" +using namespace std; + PresetsStore presetsstore; PresetsStore::PresetsStore() { clipboard.data = NULL; clipboard.type[0] = 0; - - for(int i = 0; i < MAX_PRESETS; i++) { - presets[i].file = NULL; - presets[i].name = NULL; - } } PresetsStore::~PresetsStore() @@ -66,7 +66,7 @@ bool PresetsStore::pasteclipboard(XMLwrapper *xml) return true; } -bool PresetsStore::checkclipboardtype(char *type) +bool PresetsStore::checkclipboardtype(const char *type) { //makes LFO's compatible if((strstr(type, @@ -78,128 +78,88 @@ bool PresetsStore::checkclipboardtype(char *type) //Presets management void PresetsStore::clearpresets() { - for(int i = 0; i < MAX_PRESETS; i++) { - if(presets[i].file != NULL) { - delete (presets[i].file); - presets[i].file = NULL; - } - if(presets[i].name != NULL) { - delete (presets[i].name); - presets[i].name = NULL; - } - } + presets.clear(); } //a helper function that compares 2 presets[] -int Presets_compar(const void *a, const void *b) +bool PresetsStore::presetstruct::operator<(const presetstruct &b) const { - struct PresetsStore::presetstruct *p1 = (PresetsStore::presetstruct *)a; - struct PresetsStore::presetstruct *p2 = (PresetsStore::presetstruct *)b; - if(((p1->name) == NULL) || ((p2->name) == NULL)) - return 0; - - return strcasecmp(p1->name, p2->name) < 0; + return name < b.name; } -void PresetsStore::rescanforpresets(char *type) +void PresetsStore::rescanforpresets(string type) { + //std::cout << "Scanning For Presets" << std::endl; + //std::cout << "Of Type: " << type << std::endl; + clearpresets(); - int presetk = 0; - char ftype[MAX_STRING_SIZE]; - snprintf(ftype, MAX_STRING_SIZE, ".%s.xpz", type); + string ftype = "." + type + ".xpz"; for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) { if(config.cfg.presetsDirList[i] == NULL) continue; - char *dirname = config.cfg.presetsDirList[i]; - DIR *dir = opendir(dirname); + + //open directory + string dirname = config.cfg.presetsDirList[i]; + DIR *dir = opendir(dirname.c_str()); if(dir == NULL) continue; struct dirent *fn; + + //check all files in directory while((fn = readdir(dir))) { - const char *filename = fn->d_name; - if(strstr(filename, ftype) == NULL) + string filename = fn->d_name; + if(filename.find(ftype) == string::npos) continue; - - presets[presetk].file = new char [MAX_STRING_SIZE]; - presets[presetk].name = new char [MAX_STRING_SIZE]; - char tmpc = dirname[strlen(dirname) - 1]; + //ensure proper path is formed + char tmpc = dirname[dirname.size() - 1]; const char *tmps; if((tmpc == '/') || (tmpc == '\\')) tmps = ""; else tmps = "/"; - snprintf(presets[presetk].file, - MAX_STRING_SIZE, - "%s%s%s", - dirname, - tmps, - filename); - snprintf(presets[presetk].name, MAX_STRING_SIZE, "%s", filename); - char *tmp = strstr(presets[presetk].name, ftype); - if(tmp != NULL) - tmp[0] = '\0'; - presetk++; - if(presetk >= MAX_PRESETS) - return; + string location = "" + dirname + tmps + filename; + + //trim file type off of name + string name = filename.substr(0, filename.find(ftype)); + + //put on list + presets.push_back(presetstruct(location, name)); } closedir(dir); } //sort the presets - for(int j = 0; j < MAX_PRESETS - 1; j++) { - for(int i = j + 1; i < MAX_PRESETS; i++) { - if(Presets_compar(&presets[i], &presets[j])) { - presetstruct tmp = presets[i]; - presets[i] = presets[j]; - presets[j] = tmp; - } - } - } + sort(presets.begin(), presets.end()); } -void PresetsStore::copypreset(XMLwrapper *xml, char *type, const char *name) -{ - char filename[MAX_STRING_SIZE], tmpfilename[MAX_STRING_SIZE]; +void PresetsStore::copypreset(XMLwrapper *xml, char *type, string name) +{ if(config.cfg.presetsDirList[0] == NULL) return; - snprintf(tmpfilename, MAX_STRING_SIZE, "%s", name); - //make the filenames legal - for(int i = 0; i < (int) strlen(tmpfilename); i++) { - char c = tmpfilename[i]; - if((c >= '0') && (c <= '9')) - continue; - if((c >= 'A') && (c <= 'Z')) - continue; - if((c >= 'a') && (c <= 'z')) - continue; - if((c == '-') || (c == ' ')) - continue; - tmpfilename[i] = '_'; + for(int i = 0; i < (int) name.size(); i++) { + char c = name[i]; + if(!(isdigit(c) || isalpha(c) || (c == '-') || (c == ' '))) + name[i] = '_'; } - const char *dirname = config.cfg.presetsDirList[0]; - char tmpc = dirname[strlen(dirname) - 1]; + //make path legal + const string dirname = config.cfg.presetsDirList[0]; + char tmpc = dirname[dirname.size() - 1]; const char *tmps; if((tmpc == '/') || (tmpc == '\\')) tmps = ""; else tmps = "/"; - snprintf(filename, - MAX_STRING_SIZE, - "%s%s%s.%s.xpz", - dirname, - tmps, - name, - type); + string filename("" + dirname + tmps + name + type); xml->saveXMLfile(filename); } @@ -207,10 +167,10 @@ void PresetsStore::copypreset(XMLwrapper *xml, char *type, const char *name) bool PresetsStore::pastepreset(XMLwrapper *xml, int npreset) { npreset--; - if(npreset >= MAX_PRESETS) + if(npreset >= presets.size()) return false; - char *filename = presets[npreset].file; - if(filename == NULL) + string filename = presets[npreset].file; + if(filename.empty()) return false; bool result = (xml->loadXMLfile(filename) >= 0); return result; @@ -219,11 +179,11 @@ bool PresetsStore::pastepreset(XMLwrapper *xml, int npreset) void PresetsStore::deletepreset(int npreset) { npreset--; - if(npreset >= MAX_PRESETS) + if(npreset >= presets.size()) return; - char *filename = presets[npreset].file; - if(filename == NULL) + string filename = presets[npreset].file; + if(filename.empty()) return; - remove(filename); + remove(filename.c_str()); } diff --git a/plugins/zynaddsubfx/src/Params/PresetsStore.h b/plugins/zynaddsubfx/src/Params/PresetsStore.h index c81498231..f498e7829 100644 --- a/plugins/zynaddsubfx/src/Params/PresetsStore.h +++ b/plugins/zynaddsubfx/src/Params/PresetsStore.h @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - PresetsStore.C - Presets and Clipboard store + PresetsStore.cpp - Presets and Clipboard store Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -20,11 +20,12 @@ */ +#include +#include #include "../Misc/XMLwrapper.h" #include "../Misc/Config.h" #define MAX_PRESETTYPE_SIZE 30 -#define MAX_PRESETS 1000 class PresetsStore { @@ -35,20 +36,23 @@ class PresetsStore //Clipboard stuff void copyclipboard(XMLwrapper *xml, char *type); bool pasteclipboard(XMLwrapper *xml); - bool checkclipboardtype(char *type); + bool checkclipboardtype(const char *type); //presets stuff - void copypreset(XMLwrapper *xml, char *type, const char *name); + void copypreset(XMLwrapper *xml, char *type, std::string name); bool pastepreset(XMLwrapper *xml, int npreset); void deletepreset(int npreset); struct presetstruct { - char *file; - char *name; + presetstruct(std::string _file, std::string _name) + :file(_file),name(_name){}; + bool operator<(const presetstruct &b) const; + std::string file; + std::string name; }; - presetstruct presets[MAX_PRESETS]; + std::vector presets; - void rescanforpresets(char *type); + void rescanforpresets(const std::string type); private: struct { diff --git a/plugins/zynaddsubfx/src/Params/SUBnoteParameters.cpp b/plugins/zynaddsubfx/src/Params/SUBnoteParameters.cpp index 27fdb46d0..425ddad75 100644 --- a/plugins/zynaddsubfx/src/Params/SUBnoteParameters.cpp +++ b/plugins/zynaddsubfx/src/Params/SUBnoteParameters.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - SUBnoteParameters.C - Parameters for SUBnote (SUBsynth) + SUBnoteParameters.cpp - Parameters for SUBnote (SUBsynth) Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Samples/AuSample.cpp b/plugins/zynaddsubfx/src/Samples/AuSample.cpp deleted file mode 100644 index 49f3a2887..000000000 --- a/plugins/zynaddsubfx/src/Samples/AuSample.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - ZynAddSubFX - a software synthesizer - - AuSample.h - Object for storing information on audio samples (for one channel) - Copyright (C) 2009-2009 Mark McCurry - Author: Mark McCurry - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License - as published by the Free Software Foundation. - - 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 (version 2 or later) for more details. - - You should have received a copy of the GNU General Public License (version 2) - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "AuSample.h" - -AuSample::AuSample(int length, REALTYPE fill) - :Sample(length, fill) {} - -AuSample::AuSample(int length, const REALTYPE *input) - :Sample(length, input) {} - diff --git a/plugins/zynaddsubfx/src/Samples/AuSample.h b/plugins/zynaddsubfx/src/Samples/AuSample.h deleted file mode 100644 index cad4a786c..000000000 --- a/plugins/zynaddsubfx/src/Samples/AuSample.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - ZynAddSubFX - a software synthesizer - - AuSample.h - Object for storing information on audio samples (for one channel) - Copyright (C) 2009-2009 Mark McCurry - Author: Mark McCurry - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License - as published by the Free Software Foundation. - - 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 (version 2 or later) for more details. - - You should have received a copy of the GNU General Public License (version 2) - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef AUSAMPLE_H -#define AUSAMPLE_H - -#include "Sample.h" -#include "FqSample.h" - -class AuSample:public Sample -{ - public: - AuSample(int length, REALTYPE fill = 0); - AuSample(int length, const REALTYPE *input); - FqSample getFqSample(); /**\todo implement this*/ -}; -#endif - diff --git a/plugins/zynaddsubfx/src/Samples/CMakeLists.txt b/plugins/zynaddsubfx/src/Samples/CMakeLists.txt index 2efd9e924..a6ef7b2a0 100644 --- a/plugins/zynaddsubfx/src/Samples/CMakeLists.txt +++ b/plugins/zynaddsubfx/src/Samples/CMakeLists.txt @@ -1,6 +1,4 @@ set(zynaddsubfx_samples_SRCS - AuSample.cpp - FqSample.cpp Sample.cpp ) diff --git a/plugins/zynaddsubfx/src/Samples/FqSample.cpp b/plugins/zynaddsubfx/src/Samples/FqSample.cpp deleted file mode 100644 index 94774047a..000000000 --- a/plugins/zynaddsubfx/src/Samples/FqSample.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - ZynAddSubFX - a software synthesizer - - FqSample.C - Object for storing information on samples - Copyright (C) 2009-2009 Mark McCurry - Author: Mark McCurry - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License - as published by the Free Software Foundation. - - 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 (version 2 or later) for more details. - - You should have received a copy of the GNU General Public License (version 2) - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "FqSample.h" - -FqSample::FqSample(int length, REALTYPE fill) - :Sample(length, fill) -{} - -FqSample::FqSample(int length, const REALTYPE *input) - :Sample(length, input) -{} - -FqSample::~FqSample() -{} - diff --git a/plugins/zynaddsubfx/src/Samples/FqSample.h b/plugins/zynaddsubfx/src/Samples/FqSample.h deleted file mode 100644 index fd31535cb..000000000 --- a/plugins/zynaddsubfx/src/Samples/FqSample.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - ZynAddSubFX - a software synthesizer - - FqSample.h - Object for storing information on samples - Copyright (C) 2009-2009 Mark McCurry - Author: Mark McCurry - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License - as published by the Free Software Foundation. - - 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 (version 2 or later) for more details. - - You should have received a copy of the GNU General Public License (version 2) - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef MONOSAMPLE_H -#define MONOSAMPLE_H - -#include "FqSample.h" -#include "Sample.h" - -class FqSample:public Sample -{ - public: - FqSample(int length, REALTYPE fill = 0); - FqSample(int length, const REALTYPE *input); - ~FqSample(); - //FqSample &operator=(const FqSample &smp); - //float *dontuse(){return buffer;}; -}; -#endif - diff --git a/plugins/zynaddsubfx/src/Samples/Sample.cpp b/plugins/zynaddsubfx/src/Samples/Sample.cpp index ca5bdc128..8fe022b65 100644 --- a/plugins/zynaddsubfx/src/Samples/Sample.cpp +++ b/plugins/zynaddsubfx/src/Samples/Sample.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Sample.C - Object for storing information on samples + Sample.cpp - Object for storing information on samples Copyright (C) 2009-2009 Mark McCurry Author: Mark McCurry @@ -19,8 +19,13 @@ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include //for memcpy/memset +#include #include "Sample.h" +using namespace std; + +#warning TODO Think about renaming Sample to Frame /**\TODO start using pointer math here as these will be Frequency called * functions throughout the code*/ Sample::Sample(const Sample &smp) @@ -92,6 +97,74 @@ bool Sample::operator==(const Sample &smp) const return true; } +/** + * Linear point estimation + * @param ya Y of point a + * @param yb Y of point b + * @param xt X of test point + * @param xa X of point a + * @param xb X of point b + * @return estimated Y of test point + */ +inline float linearEstimate(float ya, float yb, float xt, int xa = 0, int xb = 1) +{ + if(xa == xb) + return ya; + + return (yb-ya) * (xt-xa)/(xb-xa) + ya; +} + +void Sample::resize(unsigned int nsize) +{ + if(bufferSize == nsize) + return; + else {//resampling occurs here + float ratio = (nsize * 1.0) / (bufferSize * 1.0); + + int nBufferSize = nsize; + float *nBuffer = new float[nBufferSize]; + + //take care of edge cases + *nBuffer = *buffer; + *(nBuffer+nBufferSize-1) = *(buffer+bufferSize-1); + + //addition is done to avoid 0 edge case + for(int i = 1; i < nBufferSize - 1; ++i) + { + float left = floor(i/ratio); + float right = ceil((i+1)/ratio); + float test = i/ratio; + if(left > bufferSize - 1) + left = bufferSize - 1; + if(right > bufferSize - 1) + right = bufferSize - 1; + if(left > test) + test = left; + nBuffer[i] = linearEstimate(buffer[(int)left], + buffer[(int)right], + test, (int)left, (int)right); + } + + //put the new data in + delete[] buffer; + buffer = nBuffer; + bufferSize = nBufferSize; + } +} + +void Sample::append(const Sample &smp) +{ + int nbufferSize = bufferSize + smp.bufferSize; + float *nbuffer = new float[nbufferSize]; + + memcpy(nbuffer, buffer, bufferSize * sizeof(float)); + memcpy(nbuffer + bufferSize, smp.buffer, smp.bufferSize * sizeof(float)); + delete buffer; + + buffer = nbuffer; + bufferSize = nbufferSize; +} + REALTYPE Sample::max() const { REALTYPE max = -1500; //a good low considering that samples should store values -1.0 to 1.0 diff --git a/plugins/zynaddsubfx/src/Samples/Sample.h b/plugins/zynaddsubfx/src/Samples/Sample.h index ebdae66e5..5aa7c6860 100644 --- a/plugins/zynaddsubfx/src/Samples/Sample.h +++ b/plugins/zynaddsubfx/src/Samples/Sample.h @@ -50,13 +50,19 @@ class Sample void operator=(const Sample &smp); /**Provides the == operator*/ bool operator==(const Sample &smp) const; + /**Provides direct access to the buffer to allow for transition * * This method is like c_str() from the string class and should be used * sparingly*/ - const REALTYPE *c_buf() { - return buffer; - } + const REALTYPE *c_buf() const {return buffer;} + + /**Change the size of the sample*/ + void resize(unsigned int nsize); + + /**Appends another Sample to this Sample*/ + void append(const Sample &smp); + REALTYPE max() const; REALTYPE min() const; REALTYPE absMax() const; diff --git a/plugins/zynaddsubfx/src/Seq/MIDIEvents.cpp b/plugins/zynaddsubfx/src/Seq/MIDIEvents.cpp index 3bbab6c48..22d9a0565 100644 --- a/plugins/zynaddsubfx/src/Seq/MIDIEvents.cpp +++ b/plugins/zynaddsubfx/src/Seq/MIDIEvents.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - MIDIEvents.C - It stores the midi events from midi file or sequencer + MIDIEvents.cpp - It stores the midi events from midi file or sequencer Copyright (C) 2003-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Seq/MIDIFile.cpp b/plugins/zynaddsubfx/src/Seq/MIDIFile.cpp index f9dc64444..b732f49f7 100644 --- a/plugins/zynaddsubfx/src/Seq/MIDIFile.cpp +++ b/plugins/zynaddsubfx/src/Seq/MIDIFile.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - MIDIFile.C - MIDI file loader + MIDIFile.cpp - MIDI file loader Copyright (C) 2003-2005 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -101,7 +101,7 @@ int MIDIFile::parsemidifile(MIDIEvents *me_) } else //SMPTE (frames/second and ticks/frame) printf( - "ERROR:in MIDIFile.C::parsemidifile() - SMPTE not implemented yet."); + "ERROR:in MIDIFile.cpp::parsemidifile() - SMPTE not implemented yet."); ; if(ntracks >= NUM_MIDI_TRACKS) @@ -115,7 +115,7 @@ int MIDIFile::parsemidifile(MIDIEvents *me_) } printf("\n\nCURRENT File position is = 0x%x\n", midifilek); - printf("\nMIDI file successfully parsed.\n"); + printf("\nMIDI file succesfully parsed.\n"); // printf("\n0x%x\n",getbyte()); this->me = NULL; diff --git a/plugins/zynaddsubfx/src/Seq/Sequencer.cpp b/plugins/zynaddsubfx/src/Seq/Sequencer.cpp index cedc9249e..6dfde4679 100644 --- a/plugins/zynaddsubfx/src/Seq/Sequencer.cpp +++ b/plugins/zynaddsubfx/src/Seq/Sequencer.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Sequencer.C - The Sequencer + Sequencer.cpp - The Sequencer Copyright (C) 2003-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Synth/ADnote.cpp b/plugins/zynaddsubfx/src/Synth/ADnote.cpp index a70f3feef..c259fb4f4 100644 --- a/plugins/zynaddsubfx/src/Synth/ADnote.cpp +++ b/plugins/zynaddsubfx/src/Synth/ADnote.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - ADnote.C - The "additive" synthesizer + ADnote.cpp - The "additive" synthesizer Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -408,8 +408,7 @@ ADnote::ADnote(ADnoteParameters *pars, tmpwave_unison = new REALTYPE *[max_unison]; for(int k = 0; k < max_unison; k++) { tmpwave_unison[k] = new REALTYPE[SOUND_BUFFER_SIZE]; - for(int i = 0; i < SOUND_BUFFER_SIZE; i++) - tmpwave_unison[k][i] = 0.0; + memset(tmpwave_unison[k], 0, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); } initparameters(); @@ -775,7 +774,7 @@ void ADnote::KillVoice(int nvoice) if(NoteVoicePar[nvoice].VoiceOut != NULL) memset(NoteVoicePar[nvoice].VoiceOut, 0, SOUND_BUFFER_SIZE - * sizeof(REALTYPE)); //do not delete, yet: perhaps is used by another voice + * sizeof(REALTYPE));//do not delete, yet: perhaps is used by another voice NoteVoicePar[nvoice].Enabled = OFF; } @@ -1010,8 +1009,7 @@ void ADnote::initparameters() } ; if(NoteVoicePar[nvoice].VoiceOut != NULL) - for(i = 0; i < SOUND_BUFFER_SIZE; i++) - NoteVoicePar[nvoice].VoiceOut[i] = 0.0; + memset(NoteVoicePar[nvoice].VoiceOut, 0, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); } } @@ -1469,8 +1467,8 @@ inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice, //if I use VoiceOut[] as modulator for(int k = 0; k < unison_size[nvoice]; k++) { REALTYPE *tw = tmpwave_unison[k]; - for(i = 0; i < SOUND_BUFFER_SIZE; i++) - tw[i] = NoteVoicePar[NoteVoicePar[nvoice].FMVoice].VoiceOut[i]; + memcpy(tw, NoteVoicePar[NoteVoicePar[nvoice].FMVoice].VoiceOut, + SOUND_BUFFER_SIZE * sizeof(REALTYPE)); } } else { @@ -1654,11 +1652,9 @@ int ADnote::noteout(REALTYPE *outl, REALTYPE *outr) //mix subvoices into voice - for(i = 0; i < SOUND_BUFFER_SIZE; i++) - tmpwavel[i] = 0.0; + memset(tmpwavel, 0, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); if(stereo) - for(i = 0; i < SOUND_BUFFER_SIZE; i++) - tmpwaver[i] = 0.0; + memset(tmpwaver, 0, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); for(int k = 0; k < unison_size[nvoice]; k++) { REALTYPE *tw = tmpwave_unison[k]; if(stereo) { @@ -1825,11 +1821,10 @@ int ADnote::noteout(REALTYPE *outl, REALTYPE *outr) //Processing Global parameters NoteGlobalPar.GlobalFilterL->filterout(&outl[0]); - if(stereo == 0) - for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //set the right channel=left channel - outr[i] = outl[i]; - bypassr[i] = bypassl[i]; - } + if(stereo == 0) { //set the right channel=left channel + memcpy(outr, outl, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); + memcpy(bypassr, bypassl, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); + } else NoteGlobalPar.GlobalFilterR->filterout(&outr[0]); @@ -1876,7 +1871,7 @@ int ADnote::noteout(REALTYPE *outl, REALTYPE *outr) if(Legato.silent) // Silencer if(Legato.msg != LM_FadeIn) { memset(outl, 0, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); - memset(outl, 0, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); + memset(outr, 0, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); } switch(Legato.msg) { case LM_CatchUp: // Continue the catch-up... diff --git a/plugins/zynaddsubfx/src/Synth/ADnote.cxx b/plugins/zynaddsubfx/src/Synth/ADnote.cxx deleted file mode 100644 index 66c7f4d66..000000000 --- a/plugins/zynaddsubfx/src/Synth/ADnote.cxx +++ /dev/null @@ -1,136 +0,0 @@ -#include -#include -#include -#include "../Misc/Master.h" -#include "../Misc/Util.h" -#include "../Synth/ADnote.h" -#include "../Params/Presets.h" -#include "../globals.h" - -class AdNoteTest : public CxxTest::TestSuite -{ -public: - - ADnote *note; - Master *master; - Controller *controller; - unsigned char testnote; - - - float *outR,*outL; - - void setUp() { - - //First the sensible settings and variables that have to be set: - SOUND_BUFFER_SIZE = 256; - - outL=new float[SOUND_BUFFER_SIZE]; - for (int i=0;iloadXMLfile("src/Tests/guitar-adnote.xmz"); - TS_ASSERT(wrap->enterbranch("MASTER")); - TS_ASSERT(wrap->enterbranch("PART", 0)); - TS_ASSERT(wrap->enterbranch("INSTRUMENT")); - TS_ASSERT(wrap->enterbranch("INSTRUMENT_KIT")); - TS_ASSERT(wrap->enterbranch("INSTRUMENT_KIT_ITEM", 0)); - TS_ASSERT(wrap->enterbranch("ADD_SYNTH_PARAMETERS")); - defaultPreset->getfromXML(wrap); - //defaultPreset->defaults(); - - - - controller = new Controller(); - - //lets go with.... 50! as a nice note - testnote = 50; - REALTYPE freq = 440.0*pow(2.0,(testnote-69.0)/12.0); - - note = new ADnote(defaultPreset, controller, freq, 120, 0, testnote, false); - - } - - void willNoteBeRunButIsHereForLinkingReasonsHowsThisForCamelCaseEh() - { - master = new Master(); - } - - void tearDown() { - delete note; - deleteFFTFREQS(&OscilGen::outoscilFFTfreqs); - } - - void testDefaults() { - - TS_ASSERT(note->ready); - int sampleCount = 0; - -//#define WRITE_OUTPUT - -#ifdef WRITE_OUTPUT - ofstream file("adnoteout", ios::out); -#endif - note->noteout(outL, outR); -#ifdef WRITE_OUTPUT - for (int i = 0; i < SOUND_BUFFER_SIZE; ++i) { - file << outL[i] << std::endl; - } -#endif - sampleCount += SOUND_BUFFER_SIZE; - - TS_ASSERT_DELTA(outL[255], 0.1724, 0.0001); - - note->relasekey(); - - - note->noteout(outL, outR); - sampleCount += SOUND_BUFFER_SIZE; - TS_ASSERT_DELTA(outL[255], -0.1284, 0.0001); - - note->noteout(outL, outR); - sampleCount += SOUND_BUFFER_SIZE; - TS_ASSERT_DELTA(outL[255], -0.0206, 0.0001); - - note->noteout(outL, outR); - sampleCount += SOUND_BUFFER_SIZE; - TS_ASSERT_DELTA(outL[255], -0.1122, 0.0001); - - note->noteout(outL, outR); - sampleCount += SOUND_BUFFER_SIZE; - TS_ASSERT_DELTA(outL[255], 0.1707, 0.0001); - - while (!note->finished()) { - note->noteout(outL, outR); -#ifdef WRITE_OUTPUT - for (int i = 0; i < SOUND_BUFFER_SIZE; ++i) { - file << outL[i] << std::endl; - } -#endif - sampleCount += SOUND_BUFFER_SIZE; - } -#ifdef WRITE_OUTPUT - file.close(); -#endif - - TS_ASSERT_EQUALS(sampleCount, 9472); - - } -}; - diff --git a/plugins/zynaddsubfx/src/Synth/CMakeLists.txt b/plugins/zynaddsubfx/src/Synth/CMakeLists.txt index 19fa17aad..486554b9f 100644 --- a/plugins/zynaddsubfx/src/Synth/CMakeLists.txt +++ b/plugins/zynaddsubfx/src/Synth/CMakeLists.txt @@ -14,5 +14,3 @@ add_library(zynaddsubfx_synth STATIC target_link_libraries(zynaddsubfx_synth) -unit_test(adnote_test ADnote.cxx "") - diff --git a/plugins/zynaddsubfx/src/Synth/Envelope.cpp b/plugins/zynaddsubfx/src/Synth/Envelope.cpp index ce8456481..a8f2ac662 100644 --- a/plugins/zynaddsubfx/src/Synth/Envelope.cpp +++ b/plugins/zynaddsubfx/src/Synth/Envelope.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Envelope.C - Envelope implementation + Envelope.cpp - Envelope implementation Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Synth/LFO.cpp b/plugins/zynaddsubfx/src/Synth/LFO.cpp index 7b665852f..6dcf47f9f 100644 --- a/plugins/zynaddsubfx/src/Synth/LFO.cpp +++ b/plugins/zynaddsubfx/src/Synth/LFO.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - LFO.C - LFO implementation + LFO.cpp - LFO implementation Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul @@ -38,7 +38,7 @@ LFO::LFO(LFOParams *lfopars, REALTYPE basefreq) (pow(2, lfopars->Pfreq * 10.0) - 1.0) / 12.0 * lfostretch; incx = fabs(lfofreq) * (REALTYPE)SOUND_BUFFER_SIZE / (REALTYPE)SAMPLE_RATE; - if(lfopars->Pcontinuous == 0) { + if(lfopars->Pcontinous == 0) { if(lfopars->Pstartphase == 0) x = RND; else diff --git a/plugins/zynaddsubfx/src/Synth/OscilGen.cpp b/plugins/zynaddsubfx/src/Synth/OscilGen.cpp index bbd62f3bb..97eb74659 100644 --- a/plugins/zynaddsubfx/src/Synth/OscilGen.cpp +++ b/plugins/zynaddsubfx/src/Synth/OscilGen.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - OscilGen.C - Waveform generator for ADnote + OscilGen.cpp - Waveform generator for ADnote Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Synth/PADnote.cpp b/plugins/zynaddsubfx/src/Synth/PADnote.cpp index 4c25ad904..699085f8c 100644 --- a/plugins/zynaddsubfx/src/Synth/PADnote.cpp +++ b/plugins/zynaddsubfx/src/Synth/PADnote.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - PADnote.C - The "pad" synthesizer + PADnote.cpp - The "pad" synthesizer Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Synth/Resonance.cpp b/plugins/zynaddsubfx/src/Synth/Resonance.cpp index 4e12572a3..2bf8c633c 100644 --- a/plugins/zynaddsubfx/src/Synth/Resonance.cpp +++ b/plugins/zynaddsubfx/src/Synth/Resonance.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - Resonance.C - Resonance + Resonance.cpp - Resonance Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/Synth/SUBnote.cpp b/plugins/zynaddsubfx/src/Synth/SUBnote.cpp index 0a3affba5..0ef075701 100644 --- a/plugins/zynaddsubfx/src/Synth/SUBnote.cpp +++ b/plugins/zynaddsubfx/src/Synth/SUBnote.cpp @@ -1,7 +1,7 @@ /* ZynAddSubFX - a software synthesizer - SUBnote.C - The "subtractive" synthesizer + SUBnote.cpp - The "subtractive" synthesizer Copyright (C) 2002-2005 Nasca Octavian Paul Author: Nasca Octavian Paul diff --git a/plugins/zynaddsubfx/src/UI/ADnoteUI.cc b/plugins/zynaddsubfx/src/UI/ADnoteUI.cc index 854a88f1b..9d3ca6caf 100644 --- a/plugins/zynaddsubfx/src/UI/ADnoteUI.cc +++ b/plugins/zynaddsubfx/src/UI/ADnoteUI.cc @@ -1050,7 +1050,7 @@ Fl_Group* ADvoiceUI::make_window() { o->value(pars->VoicePar[nvoice].Pfixedfreq); } // Fl_Check_Button* o { WidgetPDial* o = fixedfreqetdial = new WidgetPDial(405, 255, 15, 15, "Eq.T."); - fixedfreqetdial->tooltip("How the frequency varies according to the keyboard (leftmost for fixed frequen\ + fixedfreqetdial->tooltip("How the frequency varies acording to the keyboard (leftmost for fixed frequen\ cy)"); fixedfreqetdial->box(FL_ROUND_UP_BOX); fixedfreqetdial->color(FL_BACKGROUND_COLOR); diff --git a/plugins/zynaddsubfx/src/UI/ADnoteUI.fl b/plugins/zynaddsubfx/src/UI/ADnoteUI.fl index dc5e6adc6..748156c74 100644 --- a/plugins/zynaddsubfx/src/UI/ADnoteUI.fl +++ b/plugins/zynaddsubfx/src/UI/ADnoteUI.fl @@ -481,7 +481,7 @@ if (x==0) fixedfreqetdial->deactivate(); Fl_Dial fixedfreqetdial { label {Eq.T.} callback {pars->VoicePar[nvoice].PfixedfreqET=(int) o->value();} - tooltip {How the frequency varies according to the keyboard (leftmost for fixed frequency)} xywh {405 255 15 15} box ROUND_UP_BOX labelsize 10 align 8 maximum 127 step 1 + tooltip {How the frequency varies acording to the keyboard (leftmost for fixed frequency)} xywh {405 255 15 15} box ROUND_UP_BOX labelsize 10 align 8 maximum 127 step 1 code0 {o->value(pars->VoicePar[nvoice].PfixedfreqET);} code1 {if (pars->VoicePar[nvoice].Pfixedfreq==0) o->deactivate();} class WidgetPDial diff --git a/plugins/zynaddsubfx/src/UI/CMakeLists.txt b/plugins/zynaddsubfx/src/UI/CMakeLists.txt new file mode 100644 index 000000000..49336b2dc --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/CMakeLists.txt @@ -0,0 +1,32 @@ +set(UI_fl_files + ADnoteUI.fl + BankUI.fl + ConfigUI.fl + EffUI.fl + EnvelopeUI.fl + FilterUI.fl + LFOUI.fl + MasterUI.fl + MicrotonalUI.fl + OscilGenUI.fl + PADnoteUI.fl + PartUI.fl + PresetsUI.fl + ResonanceUI.fl + SeqUI.fl + SUBnoteUI.fl + VirKeyboard.fl + WidgetPDial.fl +) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +set_source_files_properties(UI/MasterUI.h PROPERTIES GENERATED 1) +fltk_wrap_ui(zynaddsubfx_gui ${UI_fl_files}) + +add_library(zynaddsubfx_gui STATIC + ${UI_objs} + ${zynaddsubfx_gui_FLTK_UI_SRCS} + ) + +target_link_libraries(zynaddsubfx_gui ${FLTK_LIBRARIES} ${MYFLTK_LIBRARIES}) diff --git a/plugins/zynaddsubfx/src/UI/EffUI.cc b/plugins/zynaddsubfx/src/UI/EffUI.cc index 9c1b141c7..cf7a3be53 100644 --- a/plugins/zynaddsubfx/src/UI/EffUI.cc +++ b/plugins/zynaddsubfx/src/UI/EffUI.cc @@ -146,6 +146,8 @@ Fl_Menu_Item EffUI::menu_revp[] = { void EffUI::cb_revp10_i(Fl_Choice* o, void*) { eff->seteffectpar(10,(int) o->value()); +if (eff->geteffectpar(10)==2) revp12->activate(); + else revp12->deactivate(); } void EffUI::cb_revp10(Fl_Choice* o, void* v) { ((EffUI*)(o->parent()->user_data()))->cb_revp10_i(o,v); @@ -435,6 +437,12 @@ Fl_Menu_Item EffUI::menu_phaserp[] = { {"Phaser 4", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, {"Phaser 5", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, {"Phaser 6", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"APhaser 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"APhaser 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"APhaser 3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"APhaser 4", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"APhaser 5", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"APhaser 6", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, {0,0,0,0,0,0,0,0,0} }; @@ -466,6 +474,19 @@ void EffUI::cb_phaserp3(WidgetPDial* o, void* v) { ((EffUI*)(o->parent()->user_data()))->cb_phaserp3_i(o,v); } +void EffUI::cb_phaserp4_i(Fl_Choice* o, void*) { + eff->seteffectpar(4,(int) o->value()); +} +void EffUI::cb_phaserp4(Fl_Choice* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_phaserp4_i(o,v); +} + +Fl_Menu_Item EffUI::menu_phaserp4[] = { + {"SIN", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"TRI", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + void EffUI::cb_phaserp5_i(WidgetPDial* o, void*) { eff->seteffectpar(5,(int) o->value()); } @@ -487,6 +508,13 @@ void EffUI::cb_phaserp7(WidgetPDial* o, void* v) { ((EffUI*)(o->parent()->user_data()))->cb_phaserp7_i(o,v); } +void EffUI::cb_phaserp8_i(Fl_Counter* o, void*) { + eff->seteffectpar(8,(int) o->value()); +} +void EffUI::cb_phaserp8(Fl_Counter* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_phaserp8_i(o,v); +} + void EffUI::cb_phaserp9_i(WidgetPDial* o, void*) { eff->seteffectpar(9,(int) o->value()); } @@ -501,26 +529,6 @@ void EffUI::cb_phaserp10(Fl_Check_Button* o, void* v) { ((EffUI*)(o->parent()->user_data()))->cb_phaserp10_i(o,v); } -void EffUI::cb_phaserp4_i(Fl_Choice* o, void*) { - eff->seteffectpar(4,(int) o->value()); -} -void EffUI::cb_phaserp4(Fl_Choice* o, void* v) { - ((EffUI*)(o->parent()->user_data()))->cb_phaserp4_i(o,v); -} - -Fl_Menu_Item EffUI::menu_phaserp4[] = { - {"SINE", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, - {"TRI", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, - {0,0,0,0,0,0,0,0,0} -}; - -void EffUI::cb_phaserp8_i(Fl_Counter* o, void*) { - eff->seteffectpar(8,(int) o->value()); -} -void EffUI::cb_phaserp8(Fl_Counter* o, void* v) { - ((EffUI*)(o->parent()->user_data()))->cb_phaserp8_i(o,v); -} - void EffUI::cb_phaserp11_i(WidgetPDial* o, void*) { eff->seteffectpar(11,(int) o->value()); } @@ -528,6 +536,27 @@ void EffUI::cb_phaserp11(WidgetPDial* o, void* v) { ((EffUI*)(o->parent()->user_data()))->cb_phaserp11_i(o,v); } +void EffUI::cb_phaserp12_i(Fl_Check_Button* o, void*) { + eff->seteffectpar(12,(int) o->value()); +} +void EffUI::cb_phaserp12(Fl_Check_Button* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_phaserp12_i(o,v); +} + +void EffUI::cb_phaserp13_i(WidgetPDial* o, void*) { + eff->seteffectpar(13,(int) o->value()); +} +void EffUI::cb_phaserp13(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_phaserp13_i(o,v); +} + +void EffUI::cb_phaserp14_i(Fl_Check_Button* o, void*) { + eff->seteffectpar(14,(int) o->value()); +} +void EffUI::cb_phaserp14(Fl_Check_Button* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_phaserp14_i(o,v); +} + void EffUI::cb_awp_i(Fl_Choice* o, void*) { eff->changepreset((int)o->value()); refresh(eff); @@ -1104,7 +1133,7 @@ Fl_Group* EffUI::make_reverb_window() { revp4->align(Fl_Align(FL_ALIGN_BOTTOM)); revp4->when(FL_WHEN_CHANGED); } // WidgetPDial* revp4 - { revp12 = new WidgetPDial(200, 40, 30, 30, "bw"); + { WidgetPDial* o = revp12 = new WidgetPDial(200, 40, 30, 30, "bw"); revp12->box(FL_ROUND_UP_BOX); revp12->color(FL_BACKGROUND_COLOR); revp12->selection_color(FL_INACTIVE_COLOR); @@ -1116,6 +1145,8 @@ Fl_Group* EffUI::make_reverb_window() { revp12->callback((Fl_Callback*)cb_revp12); revp12->align(Fl_Align(FL_ALIGN_BOTTOM)); revp12->when(FL_WHEN_RELEASE); + revp12->deactivate(); + if (eff->geteffectpar(10)==2) o->activate(); } // WidgetPDial* revp12 { revp6 = new WidgetPDial(235, 40, 30, 30, "E/R"); revp6->box(FL_ROUND_UP_BOX); @@ -1531,7 +1562,7 @@ Fl_Group* EffUI::make_phaser_window() { effphaserwindow->user_data((void*)(this)); effphaserwindow->align(Fl_Align(FL_ALIGN_TOP)); effphaserwindow->when(FL_WHEN_RELEASE); - { phaserp = new Fl_Choice(10, 15, 90, 15, "Preset"); + { phaserp = new Fl_Choice(10, 15, 100, 15, "Preset"); phaserp->down_box(FL_BORDER_BOX); phaserp->color((Fl_Color)14); phaserp->selection_color(FL_FOREGROUND_COLOR); @@ -1578,7 +1609,7 @@ Fl_Group* EffUI::make_phaser_window() { phaserp1->align(Fl_Align(FL_ALIGN_BOTTOM)); phaserp1->when(FL_WHEN_CHANGED); } // WidgetPDial* phaserp1 - { phaserp2 = new WidgetPDial(85, 40, 30, 30, "Freq"); + { phaserp2 = new WidgetPDial(85, 45, 25, 25, "Freq"); phaserp2->tooltip("LFO frequency"); phaserp2->box(FL_ROUND_UP_BOX); phaserp2->color(FL_BACKGROUND_COLOR); @@ -1592,7 +1623,7 @@ Fl_Group* EffUI::make_phaser_window() { phaserp2->align(Fl_Align(FL_ALIGN_BOTTOM)); phaserp2->when(FL_WHEN_CHANGED); } // WidgetPDial* phaserp2 - { phaserp3 = new WidgetPDial(120, 40, 30, 30, "Rnd"); + { phaserp3 = new WidgetPDial(120, 45, 25, 25, "Rnd"); phaserp3->tooltip("LFO randomness"); phaserp3->box(FL_ROUND_UP_BOX); phaserp3->color(FL_BACKGROUND_COLOR); @@ -1606,7 +1637,17 @@ Fl_Group* EffUI::make_phaser_window() { phaserp3->align(Fl_Align(FL_ALIGN_BOTTOM)); phaserp3->when(FL_WHEN_RELEASE); } // WidgetPDial* phaserp3 - { phaserp5 = new WidgetPDial(200, 40, 30, 30, "St.df"); + { phaserp4 = new Fl_Choice(245, 55, 40, 15, "LFO"); + phaserp4->tooltip("LFO function"); + phaserp4->down_box(FL_BORDER_BOX); + phaserp4->labelfont(1); + phaserp4->labelsize(10); + phaserp4->textsize(8); + phaserp4->callback((Fl_Callback*)cb_phaserp4); + phaserp4->align(Fl_Align(130)); + phaserp4->menu(menu_phaserp4); + } // Fl_Choice* phaserp4 + { phaserp5 = new WidgetPDial(155, 45, 25, 25, "St.df"); phaserp5->tooltip("Left/Right Channel Phase Shift"); phaserp5->box(FL_ROUND_UP_BOX); phaserp5->color(FL_BACKGROUND_COLOR); @@ -1620,21 +1661,21 @@ Fl_Group* EffUI::make_phaser_window() { phaserp5->align(Fl_Align(FL_ALIGN_BOTTOM)); phaserp5->when(FL_WHEN_CHANGED); } // WidgetPDial* phaserp5 - { phaserp6 = new WidgetPDial(235, 40, 30, 30, "Dpth"); + { phaserp6 = new WidgetPDial(120, 5, 25, 25, "Dpth"); phaserp6->tooltip("LFO Depth"); phaserp6->box(FL_ROUND_UP_BOX); phaserp6->color(FL_BACKGROUND_COLOR); phaserp6->selection_color(FL_INACTIVE_COLOR); phaserp6->labeltype(FL_NORMAL_LABEL); phaserp6->labelfont(1); - phaserp6->labelsize(11); + phaserp6->labelsize(10); phaserp6->labelcolor(FL_FOREGROUND_COLOR); phaserp6->maximum(127); phaserp6->callback((Fl_Callback*)cb_phaserp6); phaserp6->align(Fl_Align(FL_ALIGN_BOTTOM)); phaserp6->when(FL_WHEN_CHANGED); } // WidgetPDial* phaserp6 - { phaserp7 = new WidgetPDial(270, 40, 30, 30, "Fb"); + { phaserp7 = new WidgetPDial(185, 45, 25, 25, "Fb"); phaserp7->tooltip("Feedback"); phaserp7->box(FL_ROUND_UP_BOX); phaserp7->color(FL_BACKGROUND_COLOR); @@ -1648,7 +1689,17 @@ Fl_Group* EffUI::make_phaser_window() { phaserp7->align(Fl_Align(FL_ALIGN_BOTTOM)); phaserp7->when(FL_WHEN_CHANGED); } // WidgetPDial* phaserp7 - { phaserp9 = new WidgetPDial(345, 40, 30, 30, "L/R"); + { Fl_Counter* o = phaserp8 = new Fl_Counter(290, 55, 35, 15, "Stages"); + phaserp8->type(1); + phaserp8->labelfont(1); + phaserp8->labelsize(11); + phaserp8->minimum(0); + phaserp8->maximum(127); + phaserp8->step(1); + phaserp8->callback((Fl_Callback*)cb_phaserp8); + o->range(1,MAX_PHASER_STAGES); + } // Fl_Counter* phaserp8 + { phaserp9 = new WidgetPDial(215, 45, 25, 25, "L/R"); phaserp9->tooltip("Channel Routing"); phaserp9->box(FL_ROUND_UP_BOX); phaserp9->color(FL_BACKGROUND_COLOR); @@ -1662,7 +1713,7 @@ Fl_Group* EffUI::make_phaser_window() { phaserp9->align(Fl_Align(FL_ALIGN_BOTTOM)); phaserp9->when(FL_WHEN_CHANGED); } // WidgetPDial* phaserp9 - { phaserp10 = new Fl_Check_Button(185, 10, 74, 20, "Substract"); + { phaserp10 = new Fl_Check_Button(200, 10, 74, 20, "Substract"); phaserp10->tooltip("inverts output"); phaserp10->box(FL_THIN_UP_BOX); phaserp10->down_box(FL_DOWN_BOX); @@ -1671,27 +1722,7 @@ Fl_Group* EffUI::make_phaser_window() { phaserp10->labelsize(10); phaserp10->callback((Fl_Callback*)cb_phaserp10); } // Fl_Check_Button* phaserp10 - { phaserp4 = new Fl_Choice(155, 50, 40, 15, "LFO type"); - phaserp4->tooltip("LFO function"); - phaserp4->down_box(FL_BORDER_BOX); - phaserp4->labelfont(1); - phaserp4->labelsize(10); - phaserp4->textsize(8); - phaserp4->callback((Fl_Callback*)cb_phaserp4); - phaserp4->align(Fl_Align(130)); - phaserp4->menu(menu_phaserp4); - } // Fl_Choice* phaserp4 - { Fl_Counter* o = phaserp8 = new Fl_Counter(305, 55, 35, 15, "Stages"); - phaserp8->type(1); - phaserp8->labelfont(1); - phaserp8->labelsize(11); - phaserp8->minimum(0); - phaserp8->maximum(127); - phaserp8->step(1); - phaserp8->callback((Fl_Callback*)cb_phaserp8); - o->range(1,MAX_PHASER_STAGES); - } // Fl_Counter* phaserp8 - { phaserp11 = new WidgetPDial(155, 10, 25, 25, "Phase"); + { phaserp11 = new WidgetPDial(155, 5, 25, 25, "Phase"); phaserp11->box(FL_ROUND_UP_BOX); phaserp11->color(FL_BACKGROUND_COLOR); phaserp11->selection_color(FL_INACTIVE_COLOR); @@ -1704,6 +1735,29 @@ Fl_Group* EffUI::make_phaser_window() { phaserp11->align(Fl_Align(FL_ALIGN_BOTTOM)); phaserp11->when(FL_WHEN_CHANGED); } // WidgetPDial* phaserp11 + { phaserp12 = new Fl_Check_Button(245, 35, 55, 15, "hyp."); + phaserp12->tooltip("hyper"); + phaserp12->down_box(FL_DOWN_BOX); + phaserp12->callback((Fl_Callback*)cb_phaserp12); + } // Fl_Check_Button* phaserp12 + { phaserp13 = new WidgetPDial(340, 50, 25, 25, "dist"); + phaserp13->tooltip("Distortion"); + phaserp13->box(FL_ROUND_UP_BOX); + phaserp13->color(FL_BACKGROUND_COLOR); + phaserp13->selection_color(FL_INACTIVE_COLOR); + phaserp13->labeltype(FL_NORMAL_LABEL); + phaserp13->labelfont(1); + phaserp13->labelsize(11); + phaserp13->labelcolor(FL_FOREGROUND_COLOR); + phaserp13->maximum(127); + phaserp13->callback((Fl_Callback*)cb_phaserp13); + phaserp13->align(Fl_Align(FL_ALIGN_BOTTOM)); + phaserp13->when(FL_WHEN_CHANGED); + } // WidgetPDial* phaserp13 + { phaserp14 = new Fl_Check_Button(305, 35, 70, 15, "Analog"); + phaserp14->down_box(FL_DOWN_BOX); + phaserp14->callback((Fl_Callback*)cb_phaserp14); + } // Fl_Check_Button* phaserp14 effphaserwindow->end(); } // Fl_Group* effphaserwindow return effphaserwindow; @@ -2500,6 +2554,9 @@ switch(eff->geteffect()){ phaserp9->value(eff->geteffectpar(9)); phaserp10->value(eff->geteffectpar(10)); phaserp11->value(eff->geteffectpar(11)); + phaserp12->value(eff->geteffectpar(12)); + phaserp13->value(eff->geteffectpar(13)); + phaserp14->value(eff->geteffectpar(14)); effphaserwindow->show(); break; case 5: diff --git a/plugins/zynaddsubfx/src/UI/EffUI.fl b/plugins/zynaddsubfx/src/UI/EffUI.fl index 178f3ad04..69ebac180 100644 --- a/plugins/zynaddsubfx/src/UI/EffUI.fl +++ b/plugins/zynaddsubfx/src/UI/EffUI.fl @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0109 +version 1.0107 header_name {.h} code_name {.cc} decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} @@ -155,7 +155,7 @@ return(log(freq/20.0)/log(1000.0));} {} decl {int maxdB;} {} } -class EffUI {open : {public Fl_Group,public PresetsUI_} +class EffUI {: {public Fl_Group,public PresetsUI_} } { Function {EffUI(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { code {eff=NULL; @@ -179,7 +179,7 @@ if (filterwindow!=NULL){ } Function {make_null_window()} {} { Fl_Window effnullwindow { - xywh {287 379 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + xywh {216 539 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide class Fl_Group } { Fl_Text_Display {} { @@ -188,11 +188,10 @@ if (filterwindow!=NULL){ } } } - Function {make_reverb_window()} {open - } { - Fl_Window effreverbwindow {open - xywh {343 337 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 - class Fl_Group visible + Function {make_reverb_window()} {} { + Fl_Window effreverbwindow { + xywh {343 337 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group } { Fl_Text_Display {} { label {Reverb } @@ -260,7 +259,9 @@ refresh(eff);} } Fl_Choice revp10 { label Type - callback {eff->seteffectpar(10,(int) o->value());} open + callback {eff->seteffectpar(10,(int) o->value()); +if (eff->geteffectpar(10)==2) revp12->activate(); + else revp12->deactivate();} xywh {110 15 85 15} down_box BORDER_BOX color 14 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 } { MenuItem {} { @@ -309,7 +310,8 @@ refresh(eff);} Fl_Dial revp12 { label bw callback {eff->seteffectpar(12,(int) o->value());} - xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 + xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 deactivate + code0 {if (eff->geteffectpar(10)==2) o->activate();} class WidgetPDial } Fl_Dial revp6 { @@ -582,14 +584,14 @@ refresh(eff);} } Function {make_phaser_window()} {} { Fl_Window effphaserwindow { - xywh {389 213 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + xywh {75 25 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide class Fl_Group } { Fl_Choice phaserp { label Preset callback {eff->changepreset((int)o->value()); refresh(eff);} - xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 + xywh {10 15 100 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 } { MenuItem {} { label {Phaser 1} @@ -615,6 +617,30 @@ refresh(eff);} label {Phaser 6} xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 } + MenuItem {} { + label {APhaser 1} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {APhaser 2} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {APhaser 3} + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {APhaser 4} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {APhaser 5} + xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {APhaser 6} selected + xywh {90 90 100 20} labelfont 1 labelsize 10 labelcolor 7 + } } Fl_Text_Display {} { label Phaser @@ -635,51 +661,22 @@ refresh(eff);} Fl_Dial phaserp2 { label Freq callback {eff->seteffectpar(2,(int) o->value());} - tooltip {LFO frequency} xywh {85 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + tooltip {LFO frequency} xywh {85 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 class WidgetPDial } Fl_Dial phaserp3 { label Rnd callback {eff->seteffectpar(3,(int) o->value());} - tooltip {LFO randomness} xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 + tooltip {LFO randomness} xywh {120 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 class WidgetPDial } - Fl_Dial phaserp5 { - label {St.df} - callback {eff->seteffectpar(5,(int) o->value());} - tooltip {Left/Right Channel Phase Shift} xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 - class WidgetPDial - } - Fl_Dial phaserp6 { - label Dpth - callback {eff->seteffectpar(6,(int) o->value());} - tooltip {LFO Depth} xywh {235 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 - class WidgetPDial - } - Fl_Dial phaserp7 { - label Fb - callback {eff->seteffectpar(7,(int) o->value());} - tooltip Feedback xywh {270 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 - class WidgetPDial - } - Fl_Dial phaserp9 { - label {L/R} - callback {eff->seteffectpar(9,(int) o->value());} - tooltip {Channel Routing} xywh {345 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 - class WidgetPDial - } - Fl_Check_Button phaserp10 { - label Substract - callback {eff->seteffectpar(10,(int) o->value());} - tooltip {inverts output} xywh {185 10 74 20} box THIN_UP_BOX down_box DOWN_BOX color 230 labelfont 1 labelsize 10 - } Fl_Choice phaserp4 { - label {LFO type} + label LFO callback {eff->seteffectpar(4,(int) o->value());} - tooltip {LFO function} xywh {155 50 40 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 130 textsize 8 + tooltip {LFO function} xywh {245 55 40 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 130 textsize 8 } { MenuItem {} { - label SINE + label SIN xywh {15 15 100 20} labelfont 1 labelsize 10 } MenuItem {} { @@ -687,18 +684,63 @@ refresh(eff);} xywh {25 25 100 20} labelfont 1 labelsize 10 } } + Fl_Dial phaserp5 { + label {St.df} + callback {eff->seteffectpar(5,(int) o->value());} + tooltip {Left/Right Channel Phase Shift} xywh {155 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp6 { + label Dpth + callback {eff->seteffectpar(6,(int) o->value());} + tooltip {LFO Depth} xywh {120 5 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp7 { + label Fb + callback {eff->seteffectpar(7,(int) o->value());} + tooltip Feedback xywh {185 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } Fl_Counter phaserp8 { label Stages callback {eff->seteffectpar(8,(int) o->value());} - xywh {305 55 35 15} type Simple labelfont 1 labelsize 11 minimum 0 maximum 127 step 1 + xywh {290 55 35 15} type Simple labelfont 1 labelsize 11 minimum 0 maximum 127 step 1 code0 {o->range(1,MAX_PHASER_STAGES);} } + Fl_Dial phaserp9 { + label {L/R} + callback {eff->seteffectpar(9,(int) o->value());} + tooltip {Channel Routing} xywh {215 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Check_Button phaserp10 { + label Substract + callback {eff->seteffectpar(10,(int) o->value());} + tooltip {inverts output} xywh {200 10 74 20} box THIN_UP_BOX down_box DOWN_BOX color 230 labelfont 1 labelsize 10 + } Fl_Dial phaserp11 { label Phase callback {eff->seteffectpar(11,(int) o->value());} - xywh {155 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 maximum 127 + xywh {155 5 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 maximum 127 class WidgetPDial } + Fl_Check_Button phaserp12 { + label {hyp.} + callback {eff->seteffectpar(12,(int) o->value());} + tooltip hyper xywh {245 35 55 15} down_box DOWN_BOX + } + Fl_Dial phaserp13 { + label dist + callback {eff->seteffectpar(13,(int) o->value());} + tooltip Distortion xywh {340 50 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Check_Button phaserp14 { + label Analog + callback {eff->seteffectpar(14,(int) o->value());} + xywh {305 35 70 15} down_box DOWN_BOX + } } } Function {make_alienwah_window()} {} { @@ -1350,6 +1392,9 @@ switch(eff->geteffect()){ phaserp9->value(eff->geteffectpar(9)); phaserp10->value(eff->geteffectpar(10)); phaserp11->value(eff->geteffectpar(11)); + phaserp12->value(eff->geteffectpar(12)); + phaserp13->value(eff->geteffectpar(13)); + phaserp14->value(eff->geteffectpar(14)); effphaserwindow->show(); break; case 5: @@ -1417,10 +1462,10 @@ switch(eff->geteffect()){ break; }; -this->show();} {selected - } +this->show();} {} } - Function {refresh()} {} { + Function {refresh()} {open + } { code {refresh(eff);} {} } decl {EffectMgr *eff;} {} diff --git a/plugins/zynaddsubfx/src/UI/EffUI.h b/plugins/zynaddsubfx/src/UI/EffUI.h index 9f8721b51..be2f5f4a8 100644 --- a/plugins/zynaddsubfx/src/UI/EffUI.h +++ b/plugins/zynaddsubfx/src/UI/EffUI.h @@ -250,6 +250,12 @@ public: private: void cb_phaserp3_i(WidgetPDial*, void*); static void cb_phaserp3(WidgetPDial*, void*); +public: + Fl_Choice *phaserp4; +private: + void cb_phaserp4_i(Fl_Choice*, void*); + static void cb_phaserp4(Fl_Choice*, void*); + static Fl_Menu_Item menu_phaserp4[]; public: WidgetPDial *phaserp5; private: @@ -265,6 +271,11 @@ public: private: void cb_phaserp7_i(WidgetPDial*, void*); static void cb_phaserp7(WidgetPDial*, void*); +public: + Fl_Counter *phaserp8; +private: + void cb_phaserp8_i(Fl_Counter*, void*); + static void cb_phaserp8(Fl_Counter*, void*); public: WidgetPDial *phaserp9; private: @@ -275,22 +286,26 @@ public: private: void cb_phaserp10_i(Fl_Check_Button*, void*); static void cb_phaserp10(Fl_Check_Button*, void*); -public: - Fl_Choice *phaserp4; -private: - void cb_phaserp4_i(Fl_Choice*, void*); - static void cb_phaserp4(Fl_Choice*, void*); - static Fl_Menu_Item menu_phaserp4[]; -public: - Fl_Counter *phaserp8; -private: - void cb_phaserp8_i(Fl_Counter*, void*); - static void cb_phaserp8(Fl_Counter*, void*); public: WidgetPDial *phaserp11; private: void cb_phaserp11_i(WidgetPDial*, void*); static void cb_phaserp11(WidgetPDial*, void*); +public: + Fl_Check_Button *phaserp12; +private: + void cb_phaserp12_i(Fl_Check_Button*, void*); + static void cb_phaserp12(Fl_Check_Button*, void*); +public: + WidgetPDial *phaserp13; +private: + void cb_phaserp13_i(WidgetPDial*, void*); + static void cb_phaserp13(WidgetPDial*, void*); +public: + Fl_Check_Button *phaserp14; +private: + void cb_phaserp14_i(Fl_Check_Button*, void*); + static void cb_phaserp14(Fl_Check_Button*, void*); public: Fl_Group* make_alienwah_window(); Fl_Group *effalienwahwindow; diff --git a/plugins/zynaddsubfx/src/UI/LFOUI.cc b/plugins/zynaddsubfx/src/UI/LFOUI.cc index 57cdc956a..af6c1f189 100644 --- a/plugins/zynaddsubfx/src/UI/LFOUI.cc +++ b/plugins/zynaddsubfx/src/UI/LFOUI.cc @@ -57,11 +57,11 @@ Fl_Menu_Item LFOUI::menu_LFOtype[] = { {0,0,0,0,0,0,0,0,0} }; -void LFOUI::cb_continuous_i(Fl_Check_Button* o, void*) { - pars->Pcontinuous=(int)o->value(); +void LFOUI::cb_continous_i(Fl_Check_Button* o, void*) { + pars->Pcontinous=(int)o->value(); } -void LFOUI::cb_continuous(Fl_Check_Button* o, void* v) { - ((LFOUI*)(o->parent()->parent()->user_data()))->cb_continuous_i(o,v); +void LFOUI::cb_continous(Fl_Check_Button* o, void* v) { + ((LFOUI*)(o->parent()->parent()->user_data()))->cb_continous_i(o,v); } void LFOUI::cb_freqrand_i(WidgetPDial* o, void*) { @@ -203,13 +203,13 @@ Fl_Group* LFOUI::make_window() { LFOtype->align(Fl_Align(FL_ALIGN_BOTTOM)); LFOtype->menu(menu_LFOtype); } // Fl_Choice* LFOtype - { continuous = new Fl_Check_Button(165, 35, 15, 15, "C."); - continuous->tooltip("Continuous LFO"); - continuous->down_box(FL_DOWN_BOX); - continuous->labelsize(10); - continuous->callback((Fl_Callback*)cb_continuous); - continuous->align(Fl_Align(FL_ALIGN_BOTTOM)); - } // Fl_Check_Button* continuous + { continous = new Fl_Check_Button(165, 35, 15, 15, "C."); + continous->tooltip("Continous LFO"); + continous->down_box(FL_DOWN_BOX); + continous->labelsize(10); + continous->callback((Fl_Callback*)cb_continous); + continous->align(Fl_Align(FL_ALIGN_BOTTOM)); + } // Fl_Check_Button* continous { freqrand = new WidgetPDial(205, 7, 20, 20, "F.R."); freqrand->tooltip("LFO Frequency Randomness"); freqrand->box(FL_ROUND_UP_BOX); @@ -268,7 +268,7 @@ void LFOUI::refresh() { intensity->value(pars->Pintensity); startphase->value(pars->Pstartphase); delay->value(pars->Pdelay); -continuous->value(pars->Pcontinuous); +continous->value(pars->Pcontinous); stretch->value(pars->Pstretch); randomness->value(pars->Prandomness); freqrand->value(pars->Pfreqrand); diff --git a/plugins/zynaddsubfx/src/UI/LFOUI.fl b/plugins/zynaddsubfx/src/UI/LFOUI.fl index d5fcc2eba..ca0433a2d 100644 --- a/plugins/zynaddsubfx/src/UI/LFOUI.fl +++ b/plugins/zynaddsubfx/src/UI/LFOUI.fl @@ -119,10 +119,10 @@ hide(); xywh {70 70 100 20} labelfont 1 labelsize 10 } } - Fl_Check_Button continuous { + Fl_Check_Button continous { label {C.} - callback {pars->Pcontinuous=(int)o->value();} - tooltip {Continuous LFO} xywh {165 35 15 15} down_box DOWN_BOX labelsize 10 align 2 + callback {pars->Pcontinous=(int)o->value();} + tooltip {Continous LFO} xywh {165 35 15 15} down_box DOWN_BOX labelsize 10 align 2 } Fl_Dial freqrand { label {F.R.} @@ -154,7 +154,7 @@ hide(); intensity->value(pars->Pintensity); startphase->value(pars->Pstartphase); delay->value(pars->Pdelay); -continuous->value(pars->Pcontinuous); +continous->value(pars->Pcontinous); stretch->value(pars->Pstretch); randomness->value(pars->Prandomness); freqrand->value(pars->Pfreqrand); diff --git a/plugins/zynaddsubfx/src/UI/LFOUI.h b/plugins/zynaddsubfx/src/UI/LFOUI.h index f05c0bde2..6959fe3f3 100644 --- a/plugins/zynaddsubfx/src/UI/LFOUI.h +++ b/plugins/zynaddsubfx/src/UI/LFOUI.h @@ -56,10 +56,10 @@ private: static void cb_LFOtype(Fl_Choice*, void*); static Fl_Menu_Item menu_LFOtype[]; public: - Fl_Check_Button *continuous; + Fl_Check_Button *continous; private: - void cb_continuous_i(Fl_Check_Button*, void*); - static void cb_continuous(Fl_Check_Button*, void*); + void cb_continous_i(Fl_Check_Button*, void*); + static void cb_continous(Fl_Check_Button*, void*); public: WidgetPDial *freqrand; private: diff --git a/plugins/zynaddsubfx/src/UI/MasterUI.cc b/plugins/zynaddsubfx/src/UI/MasterUI.cc index bc1b836a9..cc8330473 100644 --- a/plugins/zynaddsubfx/src/UI/MasterUI.cc +++ b/plugins/zynaddsubfx/src/UI/MasterUI.cc @@ -2011,6 +2011,7 @@ General Public License for details."); o->labelfont(1); o->labelsize(12); o->align(Fl_Align(FL_ALIGN_BOTTOM|FL_ALIGN_INSIDE)); + o->hide(); { Fl_Counter* o = simplesyseffnocounter = new Fl_Counter(350, 75, 80, 20, "Sys.Effect No."); simplesyseffnocounter->type(1); simplesyseffnocounter->labelfont(1); @@ -2072,7 +2073,6 @@ General Public License for details."); o->labelfont(1); o->labelsize(12); o->align(Fl_Align(FL_ALIGN_BOTTOM|FL_ALIGN_INSIDE)); - o->hide(); { Fl_Counter* o = simpleinseffnocounter = new Fl_Counter(350, 75, 80, 20, "Ins.Effect No."); simpleinseffnocounter->type(1); simpleinseffnocounter->labelfont(1); diff --git a/plugins/zynaddsubfx/src/UI/MasterUI.fl b/plugins/zynaddsubfx/src/UI/MasterUI.fl index 451c9f422..b97b77326 100644 --- a/plugins/zynaddsubfx/src/UI/MasterUI.fl +++ b/plugins/zynaddsubfx/src/UI/MasterUI.fl @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0107 +version 1.0110 header_name {.h} code_name {.cc} decl {//Copyright (c) 2002-2009 Nasca Octavian Paul} {} @@ -414,8 +414,7 @@ panellistitemgroup->redraw();} {} } class MasterUI {} { - Function {make_window()} {selected - } { + Function {make_window()} {} { Fl_Window masterwindow { label zynaddsubfx callback {\#ifdef VSTAUDIOOUT @@ -426,7 +425,7 @@ fl_alert("ZynAddSubFX could not be closed this way, because it's a VST plugin. P *exitprogram=1; //}; \#endif} - xywh {31 206 390 465} type Double hide xclass zynaddsubfx + xywh {585 104 390 465} type Double xclass zynaddsubfx visible } { Fl_Menu_Bar mastermenu { xywh {-5 0 690 25} @@ -689,7 +688,7 @@ pthread_mutex_unlock(&master->mutex);} xywh {0 80 390 160} } { Fl_Group {} { - label {System Effects} open + label {System Effects} xywh {0 100 390 140} box ENGRAVED_FRAME labeltype EMBOSSED_LABEL labelsize 15 align 25 } { Fl_Counter syseffnocounter { @@ -1305,7 +1304,7 @@ o->redraw();} } { Fl_Group {} { label {System Effects} - xywh {345 55 245 155} box ENGRAVED_FRAME labelfont 1 labelsize 12 align 18 + xywh {345 55 245 155} box ENGRAVED_FRAME labelfont 1 labelsize 12 align 18 hide } { Fl_Counter simplesyseffnocounter { label {Sys.Effect No.} @@ -1387,7 +1386,7 @@ pthread_mutex_unlock(&master->mutex);} } Fl_Group {} { label {Insertion Effects} - xywh {345 55 245 155} box ENGRAVED_FRAME labelfont 1 labelsize 12 align 18 hide + xywh {345 55 245 155} box ENGRAVED_FRAME labelfont 1 labelsize 12 align 18 } { Fl_Counter simpleinseffnocounter { label {Ins.Effect No.} @@ -1415,7 +1414,7 @@ if (master->Pinsparts[ninseff]!=-1) { master->insefx[ninseff]->changeeffect((int) o->value()); pthread_mutex_unlock(&master->mutex); simpleinseffectui->refresh(master->insefx[ninseff]); -simpleinseffectui->show();} +simpleinseffectui->show();} selected xywh {515 80 70 15} down_box BORDER_BOX labelsize 10 align 5 code0 {o->value(master->insefx[ninseff]->geteffect());} code1 {if (master->Pinsparts[ninseff]== -1) o->deactivate();} diff --git a/plugins/zynaddsubfx/src/UI/PADnoteUI.cc b/plugins/zynaddsubfx/src/UI/PADnoteUI.cc index 86ab5fa78..0478e4cb1 100644 --- a/plugins/zynaddsubfx/src/UI/PADnoteUI.cc +++ b/plugins/zynaddsubfx/src/UI/PADnoteUI.cc @@ -516,7 +516,7 @@ void PADnoteUI::cb_spectrummode(Fl_Choice* o, void* v) { Fl_Menu_Item PADnoteUI::menu_spectrummode[] = { {"Bandwidth", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, {"Discrete", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, - {"Continuous", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Continous", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, {0,0,0,0,0,0,0,0,0} }; @@ -1149,7 +1149,7 @@ Fl_Double_Window* PADnoteUI::make_window() { o->value(pars->Pfixedfreq); } // Fl_Check_Button* hz440 { WidgetPDial* o = fixedfreqetdial = new WidgetPDial(420, 295, 15, 15, "Eq.T."); - fixedfreqetdial->tooltip("How the frequency varies according to the keyboard (leftmost for fixed frequen\ + fixedfreqetdial->tooltip("How the frequency varies acording to the keyboard (leftmost for fixed frequen\ cy)"); fixedfreqetdial->box(FL_ROUND_UP_BOX); fixedfreqetdial->color(FL_BACKGROUND_COLOR); diff --git a/plugins/zynaddsubfx/src/UI/PADnoteUI.fl b/plugins/zynaddsubfx/src/UI/PADnoteUI.fl index 3f03dc0ea..74441c199 100644 --- a/plugins/zynaddsubfx/src/UI/PADnoteUI.fl +++ b/plugins/zynaddsubfx/src/UI/PADnoteUI.fl @@ -762,7 +762,7 @@ cbwidget->do_callback();} xywh {125 125 100 20} labelfont 1 labelsize 11 } MenuItem {} { - label Continuous + label Continous xywh {115 115 100 20} labelfont 1 labelsize 11 } } @@ -842,7 +842,7 @@ if (x==0) fixedfreqetdial->deactivate(); Fl_Dial fixedfreqetdial { label {Eq.T.} callback {pars->PfixedfreqET=(int) o->value();} - tooltip {How the frequency varies according to the keyboard (leftmost for fixed frequency)} xywh {420 295 15 15} box ROUND_UP_BOX labelsize 10 align 8 maximum 127 step 1 + tooltip {How the frequency varies acording to the keyboard (leftmost for fixed frequency)} xywh {420 295 15 15} box ROUND_UP_BOX labelsize 10 align 8 maximum 127 step 1 code0 {o->value(pars->PfixedfreqET);} code1 {if (pars->Pfixedfreq==0) o->deactivate();} class WidgetPDial diff --git a/plugins/zynaddsubfx/src/UI/PresetsUI.cc b/plugins/zynaddsubfx/src/UI/PresetsUI.cc index b35c868f3..d27285ee5 100644 --- a/plugins/zynaddsubfx/src/UI/PresetsUI.cc +++ b/plugins/zynaddsubfx/src/UI/PresetsUI.cc @@ -1,6 +1,7 @@ // generated by Fast Light User Interface Designer (fluid) version 1.0300 #include "PresetsUI.h" +#include "../Params/PresetsArray.h" void PresetsUI_::refresh() { } @@ -242,12 +243,16 @@ if (but) { } void PresetsUI::copy(Presets *p,int n) { - p->setelement(n); + PresetsArray *pre = dynamic_cast(p); +if(pre) + pre->setelement(n); copy(p); } void PresetsUI::paste(Presets *p,PresetsUI_ *pui,int n) { - p->setelement(n); + PresetsArray *pre = dynamic_cast(p); +if(pre) + pre->setelement(n); paste(p,pui); } @@ -256,11 +261,12 @@ void PresetsUI::rescan() { pastebrowse->clear(); p->rescanforpresets(); -for (int i=0;iadd(name); - pastebrowse->add(name); +for (int i=0;iadd(name.c_str()); + pastebrowse->add(name.c_str()); }; } PresetsUI *presetsui; diff --git a/plugins/zynaddsubfx/src/UI/PresetsUI.fl b/plugins/zynaddsubfx/src/UI/PresetsUI.fl index 0378d62ef..dede2dd4d 100644 --- a/plugins/zynaddsubfx/src/UI/PresetsUI.fl +++ b/plugins/zynaddsubfx/src/UI/PresetsUI.fl @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0105 +version 1.0107 header_name {.h} code_name {.cc} decl {\#include } {public @@ -11,6 +11,8 @@ decl {\#include } {public decl {\#include } {public } +decl {\#include "../Params/PresetsArray.h"} {} + decl {\#include "../Params/Presets.h"} {public } @@ -96,7 +98,7 @@ if (strlen(tmp)>0) { }else{ pastepbutton->activate(); deletepbutton->activate(); -};} selected +};} xywh {10 25 245 320} type Hold } Fl_Button pastepbutton { @@ -171,11 +173,15 @@ if (but) { };} {} } Function {copy(Presets *p,int n)} {} { - code {p->setelement(n); + code {PresetsArray *pre = dynamic_cast(p); +if(pre) + pre->setelement(n); copy(p);} {} } Function {paste(Presets *p,PresetsUI_ *pui,int n)} {} { - code {p->setelement(n); + code {PresetsArray *pre = dynamic_cast(p); +if(pre) + pre->setelement(n); paste(p,pui);} {} } Function {rescan()} {} { @@ -183,12 +189,14 @@ paste(p,pui);} {} pastebrowse->clear(); p->rescanforpresets(); -for (int i=0;iadd(name); - pastebrowse->add(name); -};} {} +for (int i=0;iadd(name.c_str()); + pastebrowse->add(name.c_str()); +};} {selected + } } decl {Presets *p;} {public } diff --git a/plugins/zynaddsubfx/src/UI/SUBnoteUI.cc b/plugins/zynaddsubfx/src/UI/SUBnoteUI.cc index a28f8d9a1..c00c374c4 100644 --- a/plugins/zynaddsubfx/src/UI/SUBnoteUI.cc +++ b/plugins/zynaddsubfx/src/UI/SUBnoteUI.cc @@ -513,7 +513,7 @@ Fl_Double_Window* SUBnoteUI::make_window() { o->value(pars->Pfixedfreq); } // Fl_Check_Button* hz440 { WidgetPDial* o = fixedfreqetdial = new WidgetPDial(610, 45, 15, 15, "Eq.T."); - fixedfreqetdial->tooltip("How the frequency varies according to the keyboard (leftmost for fixed frequen\ + fixedfreqetdial->tooltip("How the frequency varies acording to the keyboard (leftmost for fixed frequen\ cy)"); fixedfreqetdial->box(FL_ROUND_UP_BOX); fixedfreqetdial->color(FL_BACKGROUND_COLOR); diff --git a/plugins/zynaddsubfx/src/UI/SUBnoteUI.fl b/plugins/zynaddsubfx/src/UI/SUBnoteUI.fl index d7406d475..ef50a0bb9 100644 --- a/plugins/zynaddsubfx/src/UI/SUBnoteUI.fl +++ b/plugins/zynaddsubfx/src/UI/SUBnoteUI.fl @@ -276,7 +276,7 @@ if (x==0) fixedfreqetdial->deactivate(); Fl_Dial fixedfreqetdial { label {Eq.T.} callback {pars->PfixedfreqET=(int) o->value();} - tooltip {How the frequency varies according to the keyboard (leftmost for fixed frequency)} xywh {610 45 15 15} box ROUND_UP_BOX labelsize 10 align 8 maximum 127 step 1 + tooltip {How the frequency varies acording to the keyboard (leftmost for fixed frequency)} xywh {610 45 15 15} box ROUND_UP_BOX labelsize 10 align 8 maximum 127 step 1 code0 {o->value(pars->PfixedfreqET);} code1 {if (pars->Pfixedfreq==0) o->deactivate();} class WidgetPDial diff --git a/plugins/zynaddsubfx/src/UI/VirKeyboard.cc b/plugins/zynaddsubfx/src/UI/VirKeyboard.cc index 25df926ad..193e1dc7c 100644 --- a/plugins/zynaddsubfx/src/UI/VirKeyboard.cc +++ b/plugins/zynaddsubfx/src/UI/VirKeyboard.cc @@ -103,7 +103,7 @@ if ((event==FL_PUSH)||(event==FL_DRAG)||(event==FL_RELEASE)){ }; }; - if (((event==FL_PUSH)||(event==FL_DRAG))&& + if ((kpos!=-1)&&((event==FL_PUSH)||(event==FL_DRAG))&& (Fl::event_shift()==0)) { presskey(kpos,1,1); }; diff --git a/plugins/zynaddsubfx/src/UI/VirKeyboard.fl b/plugins/zynaddsubfx/src/UI/VirKeyboard.fl index 37fe43e5c..a0b4c721c 100644 --- a/plugins/zynaddsubfx/src/UI/VirKeyboard.fl +++ b/plugins/zynaddsubfx/src/UI/VirKeyboard.fl @@ -138,7 +138,7 @@ if ((event==FL_PUSH)||(event==FL_DRAG)||(event==FL_RELEASE)){ }; }; - if (((event==FL_PUSH)||(event==FL_DRAG))&& + if ((kpos!=-1)&&((event==FL_PUSH)||(event==FL_DRAG))&& (Fl::event_shift()==0)) { presskey(kpos,1,1); };